static void test_drv_outputv(ErlDrvData handle, ErlIOVec *ev) { test_data* d = (test_data*)handle; test_async_data* ad = (test_async_data*)driver_alloc(sizeof(test_async_data)); size_t p, q; char method, fn, arg, res; p = 0; q = 1; EV_GET_CHAR(ev, &method, &p, &q); EV_GET_CHAR(ev, &fn, &p, &q); EV_GET_CHAR(ev, &arg, &p, &q); switch (method) { case 1: res = (char) do_f(fn, arg); driver_output(d->port, &res, 1); break; case 2: ad->fn = fn; ad->arg = arg; driver_async(d->port, NULL, do_async, (void *) ad, NULL); } }
static void s1_outputv(ErlDrvData drv_data, ErlIOVec *ev) { descriptor_t *desc = (descriptor_t *) drv_data; unsigned char cmd; int p = 0, q = 1; callstate_t *c = NULL; int do_async_call = default_async_calls; unsigned long binlen; int index; void *tmp = NULL; binlen = binlen; index = index; tmp = tmp; if (desc == NULL || ev == NULL || ev->size < 1) { edtk_debug("%s: bad arg(s)", __FUNCTION__); return; } if (! EV_GET_CHAR(ev, &cmd, &p, &q)) { edtk_debug("%s: empty command", __FUNCTION__); reply_error(desc, EINVAL); } if ((c = sys_alloc(sizeof(callstate_t))) == NULL) { reply_error(desc, ENOMEM); return; } c->cmd = cmd; c->key = NULL; c->free = sys_free; c->xid = 0; /* XXX unused right now */ c->o.__expect = 1; /* Default is that expectation is always met */ edtk_debug("%s: my threadid = %lx, cmd = %d", __FUNCTION__, pthread_self(), cmd); switch (cmd) { case S1_DEBUG: EV_GET_UINT32(ev, &edtk_debug_flag, &p, &q); reply_ok_num(desc, edtk_debug_flag); /* Immediate reply */ sys_free(c); c = NULL; break; case S1_NULL: c->invoke = invoke_s1_null; break; case S1_OPEN: c->invoke = invoke_s1_open; EV_GET_UINT32(ev, &binlen, &p, &q); c->i.filename = (char *) EV_GETPOS(ev, p, q); if (edtk_ev_forward_N(ev, binlen, &p, &q, 1) < 0) { goto error; } EV_GET_UINT32(ev, &c->i.flags, &p, &q); break; case S1_GETFD: c->invoke = invoke_s1_getfd; EV_GET_UINT32(ev, &index, &p, &q); if (desc->valmap_fd[index] == -1) { goto error; } else { edtk_debug("%s: valmap fd index %d = 0x%lx", __FUNCTION__, index, desc->valmap_fd[index]); c->i.fd = desc->valmap_fd[index]; c->i.__valmap_fd_index = index; } break; case S1_SENDFD: c->invoke = invoke_s1_sendfd; EV_GET_UINT32(ev, &c->i.unixdom_fd, &p, &q); EV_GET_UINT32(ev, &c->i.fd_to_be_sent, &p, &q); break; case S1_RECEIVEFD: c->invoke = invoke_s1_receivefd; EV_GET_UINT32(ev, &c->i.unixdom_fd, &p, &q); break; case S1_CLOSE: c->invoke = invoke_s1_close; EV_GET_UINT32(ev, &index, &p, &q); if (index == -1 && 0 == 1) { edtk_debug("%s: valmap fd index %d = default value 0x%lx", __FUNCTION__, index, -1); c->i.fd = -1; c->i.__valmap_fd_index = -1; } else if (desc->valmap_fd[index] == -1) { goto error; } else { edtk_debug("%s: valmap fd index %d = 0x%lx", __FUNCTION__, index, desc->valmap_fd[index]); c->i.fd = desc->valmap_fd[index]; c->i.__valmap_fd_index = index; } break; } if (c != NULL) { if (do_async_call) { driver_async(desc->port, c->key, c->invoke, c, c->free); } else { /* ** Execute the bottom half right away, then send the result. */ (*(c->invoke))((void *) c); s1_ready_async((ErlDrvData) desc, (ErlDrvThreadData) c); /* ** c is already freed for us by s1_ready_async() */ } } return; error: if (c != NULL) { sys_free(c); } reply_error_atom(desc, am_badarg); }