Exemplo n.º 1
0
static void
zmqdrv_send(zmq_drv_t *drv, ErlIOVec *ev)
{
    ErlDrvBinary*  bin   = ev->binv[1];
    char*          bytes = bin->orig_bytes;
    uint32_t       idx   = ntohl(*(uint32_t*)(bytes+1));
    zmq_sock_info* si    = drv->get_socket_info(idx);
    uint32_t       flags = ntohl(*(uint32_t*)(bytes+5));
    void*          data  = (void *)(bytes + 9);
    size_t         size  = bin->orig_size - 9;

    if (idx > drv->zmq_socket_count || !si) {
        zmqdrv_error_code(drv, ENODEV);
        return;
    }

#ifdef ZMQDRV_DEBUG
    uint32_t events;
    size_t events_size = sizeof(events);
    zmq_getsockopt(si->socket, ZMQ_EVENTS, &events, &events_size);
    zmqdrv_fprintf("sending %p [idx=%d] %lu bytes (events=%d)\r\n", si->socket, idx, size, events);
#endif

    if (si->out_caller != 0) {
        // There's still an unwritten message pending
        zmqdrv_error_code(drv, EBUSY);
        return;
    }

    // Increment the reference count on binary so that zmq can
    // take ownership of it.
    driver_binary_inc_refc(bin);

    if (zmq_msg_init_data(&si->out_msg, data, size, &zmq_free_binary, bin)) {
        zmqdrv_error_code(drv, zmq_errno());
        driver_binary_dec_refc(bin);
        return;
    }

    if (zmq_send(si->socket, &si->out_msg, flags | ZMQ_NOBLOCK) == 0) {
        zmqdrv_ok(drv);
        zmqdrv_ready_input((ErlDrvData)drv, (ErlDrvEvent)si->fd);
    } else {
        int e = zmq_errno();
        if (e == EAGAIN) {
            // No msg returned to caller - make him wait until async
            // send succeeds
            si->out_caller = driver_caller(drv->port);
            return;
        }
        zmqdrv_error_code(drv, e);
    }
    zmq_msg_close(&si->out_msg);
}
Exemplo n.º 2
0
void run_js(void *jsargs) {
  js_call *call_data = (js_call *) jsargs;
  spidermonkey_drv_t *dd = call_data->driver_data;
  ErlDrvBinary *args = call_data->args;
  driver_free(call_data);
  char *data = args->orig_bytes;
  char *command = read_command(&data);
  char *call_id = read_string(&data);
  char *result = NULL;
  if (strncmp(command, "ej", 2) == 0) {
    char *filename = read_string(&data);
    char *code = read_string(&data);
    result = sm_eval(dd->vm, filename, code, 1);
    if (strstr(result, "{\"error\"") != NULL) {
      send_error_string_response(dd, call_id, result);
    }
    else {
      send_string_response(dd, call_id, result);
    }
    driver_free(filename);
    driver_free(code);
    driver_free(result);
  }
  else if (strncmp(command, "dj", 2) == 0) {
    char *filename = read_string(&data);
    char *code = read_string(&data);
    result = sm_eval(dd->vm, filename, code, 0);
    if (result == NULL) {
      send_ok_response(dd, call_id);
    }
    else {
      send_error_string_response(dd, call_id, result);
      driver_free(result);
    }
    driver_free(filename);
    driver_free(code);
  }
  else if (strncmp(command, "sd", 2) == 0) {
    dd->shutdown = 1;
    send_ok_response(dd, call_id);
  }
  else {
    unknown_command(dd, call_id);
  }
  driver_free(command);
  driver_free(call_id);
  driver_binary_dec_refc(args);
}
Exemplo n.º 3
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
static void
wrap_zmq_send(zmq_drv_t *drv, const uint8_t* bytes, size_t size, ErlDrvBinary* bin)
{
    int     flags     = *bytes;
    void*   data      = (void *)(bytes+sizeof(uint8_t));
    size_t  data_size = size - sizeof(uint8_t);

    assert(sizeof(uint8_t) <= size);

    ErlDrvTermData caller = driver_caller(drv->port);

    if (drv->terminating)
    {
        reply_error(drv->port, caller, ETERM);
        return;
    }

    zmq_sock_info* si = drv->get_socket_info(caller);

    if (!si)
    {
        reply_error(drv->port, caller, ENODEV);
        return;
    }

    assert(0 == si->out_caller);

    zmqdrv_fprintf("send %p (flags: %d bytes: %u)\r\n", si->socket, flags, data_size);

    // Increment the reference count on binary so that zmq can take ownership of it.
    driver_binary_inc_refc(bin);

    if (zmq_msg_init_data(&si->out_msg, data, data_size, &zmqcb_free_binary, bin))
    {
        reply_error(drv->port, caller, zmq_errno());
        driver_binary_dec_refc(bin);
        return;
    }

    if (0 == zmq_send(si->socket, &si->out_msg, flags|ZMQ_NOBLOCK))
    {
        reply_ok(drv->port, caller);
        zmq_msg_close(&si->out_msg);
    }
    else if (ZMQ_NOBLOCK != (ZMQ_NOBLOCK & flags) && EAGAIN == zmq_errno())
    {
        // Caller requested blocking send
        // Can't send right now. Make the caller wait by not returning result
        zmqdrv_fprintf("send %p blocking\r\n", si->socket);

        si->out_flags = flags;
        si->out_caller = caller;

        if (!si->busy)
        {
            driver_select(drv->port, si->fd, ERL_DRV_READ, 1);
            si->busy = true;
        }
    }
    else
    {
        reply_error(drv->port, caller, zmq_errno());
        zmq_msg_close(&si->out_msg);
    }
}