dthread_t* dthread_start(ErlDrvPort port, void* (*func)(void* arg), void* arg, int stack_size) { ErlDrvThreadOpts* opts = NULL; dthread_t* thr = NULL; if (!(thr = DALLOC(sizeof(dthread_t)))) return 0; if (dthread_init(thr, port) < 0) goto error; if (!(opts = erl_drv_thread_opts_create("dthread_opts"))) goto error; opts->suggested_stack_size = stack_size; thr->arg = arg; if (erl_drv_thread_create("dthread", &thr->tid, func, thr, opts) < 0) goto error; erl_drv_thread_opts_destroy(opts); return thr; error: dthread_finish(thr); if (opts) erl_drv_thread_opts_destroy(opts); dthread_finish(thr); DFREE(thr); return 0; }
static ErlDrvData uart_drv_start(ErlDrvPort port, char* command) { (void) command; drv_ctx_t* ctx = NULL; INFOF("memory allocated: %ld", dlib_allocated()); INFOF("total memory allocated: %ld", dlib_total_allocated()); ctx = DZALLOC(sizeof(drv_ctx_t)); dthread_init(&ctx->self, port); if (strncmp(command, "uart_drv", 8) == 0) command += 8; if (*command == ' ') command++; DEBUGF("uart_drv: start (%s)", command); if (strcmp(command, "ftdi") == 0) { #ifdef HAVE_FTDI ctx->other = dthread_start(port, uart_ftdi_main, &ctx->self, 4096); DEBUGF("uart_drv: ftdi thread = %p", ctx->other); #endif } else { #ifdef __WIN32__ if ((*command == '\0') || (strcmp(command, "win32") == 0)) { ctx->other = dthread_start(port, uart_win32_main, &ctx->self, 4096); DEBUGF("uart_drv: win32 thread = %p", ctx->other); } #else if ((*command == '\0') || (strcmp(command, "unix") == 0)) { ctx->other = dthread_start(port, uart_unix_main, &ctx->self, 4096); DEBUGF("uart_drv: unix thread = %p", ctx->other); } #endif } if (ctx->other == NULL) { dthread_finish(&ctx->self); DFREE(ctx); return ERL_DRV_ERROR_BADARG; } dthread_signal_use(&ctx->self, 1); dthread_signal_select(&ctx->self, 1); set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); return (ErlDrvData) ctx; }