static void es_fa_stat(void *aux) { es_fa_handle_t *fah = aux; es_fap_t *ef = fah->fah_ef; es_context_t *ec = ef->super.er_ctx; duk_context *ctx = ec->ec_duk; es_context_begin(ec); duk_set_top(ctx, 0); es_push_root(ctx, ef); duk_get_prop_string(ctx, -1, "stat"); es_push_native_obj(ctx, &es_native_fah, fah_retain(fah)); duk_push_string(ctx, fah->fah_url); int rc = duk_pcall(ctx, 2); if(rc) { fah_exception(fah, ctx); es_dump_err(ctx); } es_context_end(ec, 0); fah_release(fah); }
static void es_fa_read(void *aux) { es_fa_handle_t *fah = aux; es_fap_t *ef = fah->fah_ef; es_context_t *ec = ef->super.er_ctx; duk_context *ctx = ec->ec_duk; es_context_begin(ec); duk_set_top(ctx, 0); duk_push_external_buffer(ctx); es_root_register(ctx, -1, fah->fah_readbuf); duk_config_buffer(ctx, 0, fah->fah_readbuf, fah->fah_readlen); es_push_root(ctx, ef); duk_get_prop_string(ctx, -1, "read"); es_push_native_obj(ctx, &es_native_fah, fah_retain(fah)); es_push_root(ctx, fah); duk_push_buffer_object(ctx, 0, 0, fah->fah_readlen, DUK_BUFOBJ_UINT8ARRAY); duk_push_int(ctx, fah->fah_readlen); duk_push_number(ctx, fah->fah_fpos); int rc = duk_pcall(ctx, 5); if(rc) { fah_exception(fah, ctx); es_dump_err(ctx); } es_context_end(ec, 0); fah_release(fah); }
static void * timer_thread(void *aux) { int destroy = 0; es_timer_t *et; hts_mutex_lock(&timer_mutex); while(1) { et = LIST_FIRST(&timers); if(et == NULL) break; int64_t now = arch_get_ts(); int64_t delta = et->et_expire - now; if(delta > 0) { int ms = (delta + 999) / 1000; hts_cond_wait_timeout(&timer_cond, &timer_mutex, ms); continue; } LIST_REMOVE(et, et_link); if(et->et_interval) { et->et_expire = now + et->et_interval * 1000LL; LIST_INSERT_SORTED(&timers, et, et_link, estimercmp, es_timer_t); } else { et->et_expire = 0; destroy = 1; } es_resource_retain(&et->super); hts_mutex_unlock(&timer_mutex); es_context_t *ec = et->super.er_ctx; es_context_begin(ec); duk_context *ctx = ec->ec_duk; es_push_root(ctx, et); int rc = duk_pcall(ctx, 0); if(rc) es_dump_err(ctx); duk_pop(ctx); es_resource_release(&et->super); if(destroy) es_resource_destroy(&et->super); es_context_end(ec, 0); hts_mutex_lock(&timer_mutex); } thread_running = 0; hts_mutex_unlock(&timer_mutex); return NULL; }
static int es_fap_read(fa_handle_t *fh, void *buf, size_t size) { es_fa_handle_t *fah = (es_fa_handle_t *)fh; fah->fah_readbuf = buf; fah->fah_readlen = size; hts_mutex_lock(&es_fa_mutex); fah->fah_status = ES_FA_WORKING; task_run(es_fa_read, fah_retain(fah)); while(fah->fah_status == ES_FA_WORKING) hts_cond_wait(&es_fa_cond, &es_fa_mutex); hts_mutex_unlock(&es_fa_mutex); es_fap_t *ef = fah->fah_ef; es_context_t *ec = ef->super.er_ctx; duk_context *ctx = ec->ec_duk; es_context_begin(ec); es_push_root(ctx, fah->fah_readbuf); duk_config_buffer(ctx, -1, NULL, 0); es_root_unregister(ctx, fah->fah_readbuf); es_context_end(ec, 0); switch(fah->fah_status) { case ES_FA_OK: fah->fah_fpos += fah->fah_return_value; return fah->fah_return_value; case ES_FA_CANCELLED: case ES_FA_ERROR: return -1; } return 0; }
int ecmascript_openuri(prop_t *page, const char *url, int sync) { hts_regmatch_t matches[8]; hts_mutex_lock(&route_mutex); es_route_t *er; LIST_FOREACH(er, &routes, er_link) if(!hts_regexec(&er->er_regex, url, 8, matches, 0)) break; if(er == NULL) { hts_mutex_unlock(&route_mutex); return 1; } es_resource_retain(&er->super); es_context_t *ec = er->super.er_ctx; hts_mutex_unlock(&route_mutex); es_context_begin(ec); duk_context *ctx = ec->ec_duk; es_push_root(ctx, er); es_stprop_push(ctx, page); duk_push_boolean(ctx, sync); int array_idx = duk_push_array(ctx); for(int i = 1; i < 8; i++) { if(matches[i].rm_so == -1) break; duk_push_lstring(ctx, url + matches[i].rm_so, matches[i].rm_eo - matches[i].rm_so); duk_put_prop_index(ctx, array_idx, i-1); } int rc = duk_pcall(ctx, 3); if(rc) { if(duk_is_string(ctx, -1)) { nav_open_error(page, duk_to_string(ctx, -1)); } else { duk_get_prop_string(ctx, -1, "message"); nav_open_error(page, duk_to_string(ctx, -1)); duk_pop(ctx); } es_dump_err(ctx); } duk_pop(ctx); es_context_end(ec); es_resource_release(&er->super); return 0; }