Пример #1
0
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);
  }
}
Пример #2
0
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);
}