示例#1
0
static void 
zmqdrv_getsockopt(zmq_drv_t *drv, ErlIOVec *ev)
{
    ErlDrvBinary*  bin   = ev->binv[1];
    char*          bytes = bin->orig_bytes;
    uint32_t       idx   = ntohl(*(uint32_t*)(bytes+1));
    void*          s     = drv->get_zmq_socket(idx);
    uint32_t       opt   = ntohl (*(uint32_t*)(bytes+sizeof(idx)+1));

    if (opt == ZMQ_RCVMORE) {
        int64_t val;
        size_t valsz = sizeof (val);
        if (zmq_getsockopt (s, opt, &val, &valsz) < 0) {
            zmqdrv_error_code(drv, zmq_errno());
            return;
        }

        ErlDrvTermData spec[] = {
            ERL_DRV_ATOM,  am_zok,
            ERL_DRV_ATOM, (val ? am_true : am_false),
            ERL_DRV_TUPLE, 2};
        driver_send_term(drv->port, driver_caller(drv->port), spec, sizeof(spec)/sizeof(spec[0]));
        return;
    }

    zmqdrv_error(drv, "Not implemented");
}
示例#2
0
文件: zmq_drv.cpp 项目: gar1t/erlzmq
/* 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");
    }
}
示例#3
0
文件: zmq_drv.cpp 项目: gar1t/erlzmq
static void
zmqdrv_socket(zmq_drv_t *drv, ErlIOVec *ev)
{
    ErlDrvBinary* bin   = ev->binv[1];
    char*         bytes = bin->orig_bytes;
    int           type  = *(bytes + 1);

    void* s = zmq_socket(drv->zmq_context, type);
    if (!s) {
        zmqdrv_error_code(drv, zmq_errno());
        return;
    }

    int sig_fd;
    size_t sig_size = sizeof(sig_fd);
    zmq_getsockopt(s, ZMQ_FD, &sig_fd, &sig_size);

    if (sig_fd < 0) {
        zmqdrv_error(drv, "Invalid signaler");
        return;
    }

    // Register a new socket handle in order to avoid
    // passing actual address of socket to Erlang.  This
    // way it's more safe and also portable between 32 and
    // 64 bit OS's.
    uint32_t n = ++drv->zmq_socket_count;

    zmq_sock_info* zsi = new zmq_sock_info(s, n, driver_caller(drv->port), sig_fd);
    if (!zsi) {
        driver_failure_posix(drv->port, ENOMEM);
        return;
    }

    drv->add_socket(zsi);

    zmqdrv_fprintf("socket %p [idx=%d] owner=%ld\r\n", s, n, zsi->owner);

    ErlDrvTermData spec[] = {ERL_DRV_ATOM,  am_zok,
                             ERL_DRV_UINT,  n,
                             ERL_DRV_TUPLE, 2};
    driver_send_term(drv->port, zsi->owner, spec, sizeof(spec)/sizeof(spec[0]));
}
示例#4
0
文件: zmq_drv.cpp 项目: gar1t/erlzmq
static void 
zmqdrv_getsockopt(zmq_drv_t *drv, ErlIOVec *ev)
{
    ErlDrvBinary*   bin   = ev->binv[1];
    char*           bytes = bin->orig_bytes;
    uint32_t        idx   = ntohl(*(uint32_t*)(bytes+1));
    void*           s     = drv->get_zmq_socket(idx);
    zmq_sock_info*  si    = drv->get_socket_info(idx);
    uint32_t        opt   = ntohl (*(uint32_t*)(bytes+sizeof(idx)+1));
    union {
        uint8_t  a[255];
        uint64_t ui64;
        int64_t  i64;
        int      i;
        uint32_t ui;
    } val;
    size_t vallen;

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

    zmqdrv_fprintf("setsockopt %p (setting %d options)\r\n", si->socket, (int)n);

    switch (opt) {
        case ZMQ_AFFINITY:
            vallen = sizeof(uint64_t);
            if (zmq_getsockopt(s, opt, &val.ui64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.ui64);
            break;
        case ZMQ_BACKLOG:
            vallen = sizeof(int);
            if (zmq_getsockopt(s, opt, &val.i, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.i);
            break;
        case ZMQ_EVENTS:
            vallen = sizeof(uint32_t);
            if (zmq_getsockopt(s, opt, &val.ui, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.ui);
            break;
        case ZMQ_FD:
            vallen = sizeof(int);
            if (zmq_getsockopt(s, opt, &val.i, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.i);
            break;
        case ZMQ_HWM:
            vallen = sizeof(uint64_t);
            if (zmq_getsockopt(s, opt, &val.ui64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.ui64);
            break;
        case ZMQ_IDENTITY:
            vallen = sizeof(val);
            if (zmq_getsockopt(s, opt, val.a, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_binary(drv, driver_caller(drv->port), val.a, vallen);
            break;
        case ZMQ_LINGER:
            vallen = sizeof(int);
            if (zmq_getsockopt(s, opt, &val.i, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_bool(drv, driver_caller(drv->port), !!val.i);
            break;
        case ZMQ_MCAST_LOOP:
            vallen = sizeof(int64_t);
            if (zmq_getsockopt(s, opt, &val.i64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_bool(drv, driver_caller(drv->port), !!val.i64);
            break;
        case ZMQ_RATE:
            vallen = sizeof(int64_t);
            if (zmq_getsockopt(s, opt, &val.i64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.i64);
            break;
        case ZMQ_RCVBUF:
            vallen = sizeof(uint64_t);
            if (zmq_getsockopt(s, opt, &val.ui64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.ui64);
            break;
        case ZMQ_RCVMORE:
            vallen = sizeof(int64_t);
            if (zmq_getsockopt(s, opt, &val.i64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_bool(drv, driver_caller(drv->port), !!val.i64);
            break;
        case ZMQ_RECONNECT_IVL:
            vallen = sizeof(int);
            if (zmq_getsockopt(s, opt, &val.i, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.i);
            break;
        case ZMQ_RECOVERY_IVL:
            vallen = sizeof(int64_t);
            if (zmq_getsockopt(s, opt, &val.i64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.i64);
            break;
        case ZMQ_RECOVERY_IVL_MSEC:
            vallen = sizeof(int64_t);
            if (zmq_getsockopt(s, opt, &val.i64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.i64);
            break;
        case ZMQ_SNDBUF:
            vallen = sizeof(uint64_t);
            if (zmq_getsockopt(s, opt, &val.ui64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.ui64);
            break;
        case ZMQ_SWAP:
            vallen = sizeof(int64_t);
            if (zmq_getsockopt(s, opt, &val.i64, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.i64);
            break;
        case ZMQ_TYPE:
            vallen = sizeof(int);
            if (zmq_getsockopt(s, opt, &val.i, &vallen) < 0)
                zmqdrv_error_code(drv, zmq_errno());
            zmqdrv_ok_int64(drv, driver_caller(drv->port), val.i);
            break;
        case ZMQ_ACTIVE:
            zmqdrv_ok_atom(drv, driver_caller(drv->port),
                           (si->active_mode == 1 ? am_true :
                            (si->active_mode == 2 ? am_parts :
                             am_false)));
            break;
        default:
            zmqdrv_error(drv, "Option not implemented!");
            return;
    }
}