ErlDrvTid erl_drv_thread_self(void) { #ifdef USE_THREADS struct ErlDrvTid_ *dtid = ethr_tsd_get(tid_key); if (!dtid) { int res; /* This is a thread not spawned by this interface. thread_exit_handler() will clean it up when it terminates. */ dtid = erts_alloc(ERTS_ALC_T_DRV_TID, sizeof(struct ErlDrvTid_)); dtid->drv_thr = 0; /* Not a driver thread */ dtid->tid = ethr_self(); dtid->func = NULL; dtid->arg = NULL; dtid->tsd = NULL; dtid->tsd_len = 0; dtid->name = no_name; res = ethr_tsd_set(tid_key, (void *) dtid); if (res != 0) fatal_error(res, "erl_drv_thread_self()"); } return (ErlDrvTid) dtid; #else return (ErlDrvTid) NULL; #endif }
static void * tt_thread(void *arg) { int res = ethr_tsd_set(tt_key, arg); ASSERT(res == 0); return ethr_tsd_get(tt_key); }
void erts_lcnt_thread_exit_handler() { erts_lcnt_thread_data_t *eltd; eltd = ethr_tsd_get(lcnt_thr_data_key); if (eltd) { free(eltd); } }
static void thread_exit_handler(void) { struct ErlDrvTid_ *dtid = ethr_tsd_get(tid_key); if (dtid) { if (dtid->tsd) erts_free(ERTS_ALC_T_DRV_TSD, dtid->tsd); if (!dtid->drv_thr) erts_free(ERTS_ALC_T_DRV_TID, dtid); } }
void erl_drv_thread_exit(void *res) { #ifdef USE_THREADS struct ErlDrvTid_ *dtid = ethr_tsd_get(tid_key); if (dtid && dtid->drv_thr) { ethr_thr_exit(res); fatal_error(0, "erl_drv_thread_exit()"); } #endif fatal_error(EACCES, "erl_drv_thread_exit()"); }
void * erl_drv_tsd_get(ErlDrvTSDKey key) { #ifdef USE_THREADS struct ErlDrvTid_ *dtid = ethr_tsd_get(tid_key); #endif if (key < 0 || max_used_tsd_key < key || !used_tsd_keys[key]) fatal_error(EINVAL, "erl_drv_tsd_get()"); #ifdef USE_THREADS if (!dtid) return NULL; #endif if (ERL_DRV_TSD_LEN__ <= key) return NULL; return ERL_DRV_TSD__[key]; }
static erts_lcnt_thread_data_t *lcnt_get_thread_data(void) { return (erts_lcnt_thread_data_t *)ethr_tsd_get(lcnt_thr_data_key); }