int check_async_ready(void) { ErlAsync* a; int count = 0; erts_mtx_lock(&async_ready_mtx); a = async_ready_list; async_ready_list = NULL; erts_mtx_unlock(&async_ready_mtx); while(a != NULL) { ErlAsync* a_next = a->next; /* Every port not dead */ Port *p = erts_id2port_sflgs(a->port, NULL, 0, ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP); if (!p) { if (a->async_free) (*a->async_free)(a->async_data); } else { count++; if (async_ready(p, a->async_data)) { if (a->async_free != NULL) (*a->async_free)(a->async_data); } async_detach(a->hndl); erts_port_release(p); } erts_free(ERTS_ALC_T_ASYNC, (void *) a); a = a_next; } return count; }
static ERTS_INLINE void call_async_ready(ErtsAsync *a) { #if ERTS_USE_ASYNC_READY_Q Port *p = erts_id2port_sflgs(a->port, NULL, 0, ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP); #else Port *p = erts_thr_id2port_sflgs(a->port, ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP); #endif if (!p) { if (a->async_free) a->async_free(a->async_data); } else { if (async_ready(p, a->async_data)) { if (a->async_free) a->async_free(a->async_data); } #if ERTS_USE_ASYNC_READY_Q erts_port_release(p); #else erts_thr_port_release(p); #endif } if (a->pdl) driver_pdl_dec_refc(a->pdl); if (a->hndl) erts_ddll_dereference_driver(a->hndl); }
int check_async_ready(void) { #ifdef USE_THREADS ErtsAsyncReadyCallback *cbs; #endif ErlAsync* a; int count = 0; erts_mtx_lock(&async_ready_mtx); a = async_ready_list; async_ready_list = NULL; #ifdef USE_THREADS cbs = callbacks; #endif erts_mtx_unlock(&async_ready_mtx); while(a != NULL) { ErlAsync* a_next = a->next; /* Every port not dead */ Port *p = erts_id2port_sflgs(a->port, NULL, 0, ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP); if (!p) { if (a->async_free) (*a->async_free)(a->async_data); } else { count++; if (async_ready(p, a->async_data)) { if (a->async_free != NULL) (*a->async_free)(a->async_data); } async_detach(a->hndl); erts_port_release(p); } erts_free(ERTS_ALC_T_ASYNC, (void *) a); a = a_next; } #ifdef USE_THREADS for (; cbs; cbs = cbs->next) (*cbs->callback)(); #endif return count; }
static void* async_main(void* arg) { AsyncQueue* q = (AsyncQueue*) arg; #ifdef ERTS_ENABLE_LOCK_CHECK { char buf[27]; erts_snprintf(&buf[0], 27, "async %d", q->no); erts_lc_set_thread_name(&buf[0]); } #endif while(1) { ErlAsync* a = async_get(q); if (a->port == NIL) { /* TIME TO DIE SIGNAL */ erts_free(ERTS_ALC_T_ASYNC, (void *) a); break; } else { (*a->async_invoke)(a->async_data); /* Major problem if the code for async_invoke or async_free is removed during a blocking operation */ #ifdef ERTS_SMP { Port *p; p = erts_id2port_sflgs(a->port, NULL, 0, ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP); if (!p) { if (a->async_free) (*a->async_free)(a->async_data); } else { if (async_ready(p, a->async_data)) { if (a->async_free) (*a->async_free)(a->async_data); } async_detach(a->hndl); erts_port_release(p); } if (a->pdl) { driver_pdl_dec_refc(a->pdl); } erts_free(ERTS_ALC_T_ASYNC, (void *) a); } #else if (a->pdl) { driver_pdl_dec_refc(a->pdl); } erts_mtx_lock(&async_ready_mtx); a->next = async_ready_list; async_ready_list = a; erts_mtx_unlock(&async_ready_mtx); sys_async_ready(q->hndl); #endif } } return NULL; }