void erl_drv_tsd_set(ErlDrvTSDKey key, void *data) { #ifdef USE_THREADS struct ErlDrvTid_ *dtid = (struct ErlDrvTid_ *) erl_drv_thread_self(); #endif if (key < 0 || max_used_tsd_key < key || !used_tsd_keys[key]) fatal_error(EINVAL, "erl_drv_tsd_set()"); if (!ERL_DRV_TSD__) { ErlDrvTSDKey i; ERL_DRV_TSD_LEN__ = key + ERL_DRV_TSD_EXTRA; ERL_DRV_TSD__ = erts_alloc(ERTS_ALC_T_DRV_TSD, sizeof(void *)*ERL_DRV_TSD_LEN__); for (i = 0; i < ERL_DRV_TSD_LEN__; i++) ERL_DRV_TSD__[i] = NULL; } else if (ERL_DRV_TSD_LEN__ <= key) { ErlDrvTSDKey i = ERL_DRV_TSD_LEN__; ERL_DRV_TSD_LEN__ = key + ERL_DRV_TSD_EXTRA; ERL_DRV_TSD__ = erts_realloc(ERTS_ALC_T_DRV_TSD, ERL_DRV_TSD__, sizeof(void *)*ERL_DRV_TSD_LEN__); for (; i < ERL_DRV_TSD_LEN__; i++) ERL_DRV_TSD__[i] = NULL; } ERL_DRV_TSD__[key] = data; }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ static void zmqdrv_outputv(ErlDrvData handle, ErlIOVec *ev) { zmq_drv_t* drv = reinterpret_cast<zmq_drv_t*>(handle); ErlDrvBinary* bin = ev->binv[1]; enum driver_commands cmd = (enum driver_commands)bin->orig_bytes[0]; uint8_t* bytes = (uint8_t*)&bin->orig_bytes[1]; assert(1 <= bin->orig_size); zmqdrv_fprintf("driver got command %d on thread %p\r\n", (int)cmd, erl_drv_thread_self()); switch (cmd) { case ZMQ_INIT: wrap_zmq_init(drv, bytes, bin->orig_size - 1); break; case ZMQ_TERM: wrap_zmq_term(drv); break; case ZMQ_SOCKET: wrap_zmq_socket(drv, bytes, bin->orig_size - 1); break; case ZMQ_CLOSE: wrap_zmq_close(drv); break; case ZMQ_SETSOCKOPT: wrap_zmq_setsockopt(drv, bytes, bin->orig_size - 1); break; case ZMQ_GETSOCKOPT: wrap_zmq_getsockopt(drv, bytes, bin->orig_size - 1); break; case ZMQ_BIND: wrap_zmq_bind(drv, bytes, bin->orig_size - 1); break; case ZMQ_CONNECT: wrap_zmq_connect(drv, bytes, bin->orig_size - 1); break; case ZMQ_SEND: wrap_zmq_send(drv, bytes, bin->orig_size - 1, bin); break; case ZMQ_RECV: wrap_zmq_recv(drv, bytes, bin->orig_size - 1); break; case ZMQ_POLL: wrap_zmq_poll(drv, bytes, bin->orig_size - 1); break; default : assert(true); } }
/* Erlang command, called on binary input from VM. */ static void zmqdrv_outputv(ErlDrvData handle, ErlIOVec *ev) { zmq_drv_t* drv = (zmq_drv_t *)handle; ErlDrvBinary* data = ev->binv[1]; unsigned char cmd = data->orig_bytes[0]; // First byte is the command zmqdrv_fprintf("driver got command %d on thread %p\r\n", (int)cmd, erl_drv_thread_self()); switch (cmd) { case ZMQ_INIT : zmqdrv_init(drv, ev); break; case ZMQ_TERM : zmqdrv_term(drv, ev); break; case ZMQ_SOCKET : zmqdrv_socket(drv, ev); break; case ZMQ_CLOSE : zmqdrv_close(drv, ev); break; case ZMQ_SETSOCKOPT : zmqdrv_setsockopt(drv, ev); break; case ZMQ_GETSOCKOPT : zmqdrv_getsockopt(drv, ev); break; case ZMQ_BIND : zmqdrv_bind(drv, ev); break; case ZMQ_CONNECT : zmqdrv_connect(drv, ev); break; case ZMQ_SEND : zmqdrv_send(drv, ev); break; case ZMQ_RECV : zmqdrv_recv(drv, ev); break; default : zmqdrv_error(drv, "Invalid driver command"); } }
ErlNifTid enif_thread_self(void) { return erl_drv_thread_self(); }
erl_thread_t erts_thread_self(void) { return (erl_thread_t) erl_drv_thread_self(); }