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 void fah_release(es_fa_handle_t *fah) { if(atomic_dec(&fah->fah_refcount)) return; es_resource_release(&fah->fah_ef->super); free(fah->fah_url); free(fah); }
static void call_finalizer(int type, void *ptr) { switch(type) { case ES_NATIVE_PROP: prop_ref_dec(ptr); break; case ES_NATIVE_RESOURCE: es_resource_release(ptr); break; default: abort(); } }
static void es_fap_fini(fa_protocol_t *fap) { es_fap_t *ef = fap->fap_opaque; es_resource_release(&ef->super); }
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; }