Beispiel #1
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
static void
zmqdrv_process_exit(ErlDrvData handle, ErlDrvMonitor* monitor)
{
    zmq_drv_t*     drv = reinterpret_cast<zmq_drv_t*>(handle);
    ErlDrvTermData pid = driver_get_monitored_process(drv->port, monitor);

    zmqdrv_fprintf("detected death of %lu process\r\n", pid);

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

    assert(NULL != si);

    zmqdrv_fprintf("force close %p\r\n", si->socket);

    driver_demonitor_process(drv->port, &si->monitor);

    if (si->busy)
    {
        // Remove socket from vm polling
        driver_select(drv->port, si->fd, ERL_DRV_READ, 0);
    }

    drv->zmq_pid_socket.erase(pid);
    drv->zmq_fd_socket.erase(si->fd);

    //zmq_close(Socket) is called in ~zmq_sock_info
    delete si;
}
Beispiel #2
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
static void
wrap_zmq_close(zmq_drv_t *drv)
{
    ErlDrvTermData caller = driver_caller(drv->port);
    zmq_sock_info* si = drv->get_socket_info(caller);

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

    zmqdrv_fprintf("close %p\r\n", si->socket);

    driver_demonitor_process(drv->port, &si->monitor);

    if (si->busy)
    {
        // Remove socket from vm polling
        driver_select(drv->port, si->fd, ERL_DRV_READ, 0);
    }

    drv->zmq_pid_socket.erase(caller);
    drv->zmq_fd_socket.erase(si->fd);

    //zmq_close(Socket) is called in ~zmq_sock_info
    delete si;

    reply_ok(drv->port, caller);
}
Beispiel #3
0
zmq_drv_t::~zmq_drv_t()
{
    for (zmq_pid_sockets_map_t::iterator it = zmq_pid_sockets.begin();
            it != zmq_pid_sockets.end(); ++it)
        driver_demonitor_process(port, &it->second.monitor);

    for (zmq_fd_sockets_map_t::iterator it = zmq_fd_sockets.begin();
            it != zmq_fd_sockets.end(); ++it)
        driver_select(port, (ErlDrvEvent)it->first, ERL_DRV_READ, 0);

    for (zmq_sock_info *it=zmq_sock_infos, *next=(it ? it->next : NULL); it; it = next) {
        next = it->next;
        delete (&*it);
    }
    zmq_sockets.clear();
    zmq_idxs.clear();
    zmq_pid_sockets.clear();
    zmq_fd_sockets.clear();

    if (zmq_context) {
        zmqdrv_fprintf("calling zmq_term(context) ...\r\n");
        zmq_term(zmq_context);
        zmqdrv_fprintf("terminated zmq context\r\n");
    }
}
Beispiel #4
0
void handle_event_callback(ErlDrvPort port, ErlDrvTermData process)
{
  WxeApp * app = (WxeApp *) wxTheApp;
  ErlDrvMonitor monitor;
  driver_monitor_process(port, process, &monitor);
  // Should we be able to handle commands when recursing? probably
  erl_drv_mutex_lock(wxe_batch_locker_m);
  //fprintf(stderr, "\r\nCB Start ");fflush(stderr);
  app->dispatch_cb(wxe_batch, wxe_batch_cb_saved, process);
  //fprintf(stderr, ".. done \r\n");fflush(stderr);
  wxe_batch_caller = 0;
  erl_drv_mutex_unlock(wxe_batch_locker_m);
  driver_demonitor_process(port, &monitor);
}
Beispiel #5
0
int zmq_drv_t::del_socket(uint32_t idx)
{
    zmq_sock_info* s;
    int ret = -1;

    zmq_idx_socket_map_t::iterator it = zmq_sockets.find(idx);
    if (it == zmq_sockets.end()) {
        zmqdrv_fprintf("warning: socket info not found for idx %d\r\n", idx);
        return ret;
    }

    s = it->second;
    s->unlink();
    if (s == zmq_sock_infos)
        zmq_sock_infos = s->next;

    zmq_sockets.erase(idx);
    zmq_idxs.erase(s->socket);

    {
        // Remove the socket from a list of sockets owned by pid.
        // If this was the last socket, demonitor pid.
        zmq_pid_sockets_map_t::iterator it = zmq_pid_sockets.find(s->owner);
        if (it != zmq_pid_sockets.end()) {
            it->second.sockets.erase(s);
            if (it->second.sockets.empty()) {
                driver_demonitor_process(port, &it->second.monitor);
                zmq_pid_sockets.erase(it);
            }
        }
    }
    {
        zmq_fd_sockets_map_t::iterator it = zmq_fd_sockets.find(s->fd);
        if (it != zmq_fd_sockets.end()) {
            it->second.erase(s);
            if (it->second.empty()) {
                zmq_fd_sockets.erase(it->first);
                driver_select(port, (ErlDrvEvent)it->first, ERL_DRV_READ, 0);
                zmqdrv_fprintf("unregistered sig_fd(%d) with VM\r\n", it->first);
            }
        }
    }

    delete s;
    return 0;
}
Beispiel #6
0
void handle_event_callback(ErlDrvPort port, ErlDrvTermData process)
{
  WxeApp * app = (WxeApp *) wxTheApp;
  ErlDrvMonitor monitor;

  if(wxe_status != WXE_INITIATED)
    return;

  // Is thread safe if pdl have been incremented
  if(driver_monitor_process(port, process, &monitor) == 0) {
    // Should we be able to handle commands when recursing? probably
    // fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr);
    app->recurse_level++;
    app->dispatch_cb(wxe_queue, wxe_queue_cb_saved, process);
    app->recurse_level--;
    // fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr);
    driver_demonitor_process(port, &monitor);
  }
}
Beispiel #7
0
// Called when an Erlang process owning sockets died.
// Perform cleanup of orphan sockets owned by pid.
static void 
zmqdrv_process_exit(ErlDrvData handle, ErlDrvMonitor* monitor)
{
    zmq_drv_t*     drv = (zmq_drv_t *)handle;
    ErlDrvTermData pid = driver_get_monitored_process(drv->port, monitor);

    zmqdrv_fprintf("detected death of %lu process\r\n", pid);

    driver_demonitor_process(drv->port, monitor);

    // Walk through the list of sockets and close the ones
    // owned by pid.
    zmq_pid_sockets_map_t::iterator it=drv->zmq_pid_sockets.find(pid);

    if (it != drv->zmq_pid_sockets.end()) {
        zmqdrv_fprintf("pid %lu has %lu sockets to be closed\r\n", pid, it->second.sockets.size());
        for(zmq_sock_set_t::iterator sit = it->second.sockets.begin();
            sit != it->second.sockets.end(); ++sit)
            drv->del_socket((*sit)->idx);
    }
}
Beispiel #8
0
static void
enm_stop(ErlDrvData drv_data)
{
    EnmData* d = (EnmData*)drv_data;
    EnmRecv* rcv = d->waiting_recvs;
    ErlDrvTermData port = driver_mk_port(d->port);
    char refbuf[64];
    int index;

    enm_write_select(d, 0);
    enm_read_select(d, 0);
    while (rcv != 0) {
        EnmRecv* p = rcv;
        if (driver_demonitor_process(d->port, &rcv->monitor) == 0) {
            index = 0;
            ei_encode_version(refbuf, &index);
            ei_encode_ref(refbuf, &index, &rcv->ref);
            {
                ErlDrvTermData term[] = {
                    ERL_DRV_EXT2TERM, (ErlDrvTermData)refbuf, index+1,
                    ERL_DRV_ATOM, driver_mk_atom("error"),
                    ERL_DRV_ATOM, enm_errno_atom(ETERM),
                    ERL_DRV_TUPLE, 2,
                    ERL_DRV_TUPLE, 2,
                };
                erl_drv_send_term(port, rcv->rcvr, term,
                                  sizeof term/sizeof *term);
            }
        }
        rcv = rcv->next;
        driver_free(p);
    }
    if (d->fd != -1)
        nn_close(d->fd);
    d->fd = d->sfd = d->rfd = -1;
    driver_free(d);
}
Beispiel #9
0
static ErlDrvSSizeT
monitor_drv_control(ErlDrvData drv_data,
		     unsigned int command,
		     char *ibuf, ErlDrvSizeT ilen,
		     char **rbuf, ErlDrvSizeT rlen)
{
    MyDrvData *data = (MyDrvData *) drv_data;
    char *answer = NULL;
    char buff[64];
    ErlDrvSSizeT alen;

    switch (command) {
    case OP_I_AM_IPID:
	data->ipid = driver_caller(data->port);
	answer = "ok";
	break;
    case OP_MONITOR_ME:
	{
	    int res;
	    OneMonitor *om = driver_alloc(sizeof(OneMonitor));
	    om->pid = driver_caller(data->port);
	    om->later_id = 0;
	    res = driver_monitor_process(data->port,om->pid,&(om->mon));
	    if (res < 0) {
		answer = "error";
		driver_free(om);
	    } else if (res > 0) {
		answer = "noproc";
		driver_free(om);
	    } else {
		om->next = data->first;
		data->first = om;
		answer = "ok";
	    }
	    break;
	}
    case OP_DEMONITOR_ME:
	{
	    int res;
	    OneMonitor *p,*q = NULL;
	    int found = 0;
	    ErlDrvTermData pid = driver_caller(data->port);
	    for (p = data->first; p != NULL; p = p->next) {
		if (p->pid == pid) {
		    q = p;
		    ++found;
		}
	    }
	    if (q == NULL) {
		answer = "not_monitored";
	    } else {
		if (q->later_id > 0) {
		    if (found > 1) {
			answer = "delayd_but_more";
		    } else {
			answer = "delayed";
		    }
		} else {
		    res = driver_demonitor_process(data->port, &(q->mon));
		    if (res < 0) {
			answer = "error";
		    } else if (res > 0) {
			if (found > 1) {
			    answer = "gone_but_more";
			} else {
			    answer = "gone";
			}
		    } else {
			if (found > 1) {
			    answer = "ok_but_more";
			} else {
			    answer = "ok";
			}
		    }
		}
		if (data->first == q) {
		    data->first = q->next;
		} else {
		    for (p = data->first; p != NULL; p = p->next) {
			if (p->next == q) {
			    p->next = q->next;
			    break;
			}
		    }
		}
		driver_free(q);
	    }
	    break;
	}
    case OP_MONITOR_ME_LATER:
	{
	    int res;
	    OneMonitor *om = driver_alloc(sizeof(OneMonitor));
	    om->pid = driver_caller(data->port);
	    om->later_id = (++(data->later_counter));
	    om->next = data->first;
	    data->first = om;
	    sprintf(buff,"ok:%d",om->later_id);
	    answer = buff;
	    break;
	}
    case OP_DO_DELAYED_MONITOR:
	{
	    int id = 0, sign = 1, in_number = 0;
	    OneMonitor *p, *q;
	    char *bp;
	    for (bp = ibuf; bp < (ibuf + ilen); ++bp) {
		if (*bp <= '9' && *bp >= '0') {
		    int x = *bp - '0';
		    in_number++;
		    id *= 10;
		    id += x;
		} else if (*bp == '-') {
		    if (in_number) {
			break;
		    } 
		    sign = -1;
		    ++in_number;
		} else {
		    if (in_number) {
			break;
		    }
		}
	    }
	    id *= sign;
	    q = NULL;
	    for (p = data->first; p != NULL; q = p, p = p->next) {
		if (p->later_id != 0 && p->later_id == id) {
		    break;
		}
	    }
	    if (p == NULL) {
		answer = "not_found";
	    } else {
		int res = driver_monitor_process(data->port,p->pid,&(p->mon));
		if (res != 0) {
		    if (res < 0) {
			answer = "error";
		    } else {
			answer = "noproc";
		    }
		    if (q == NULL) {
			data->first = p->next;
		    } else {
			q->next = p->next;
		    }
		    driver_free(p);
		} else {
		    p->later_id = 0;
		    answer = "ok";
		}
	    }
	    break;
	}
    default:
	answer = "unknown_op";
    }
    if (answer == NULL) {
	answer = "internal_error";
    }
    alen = strlen(answer);
    if (alen >= rlen) {
	*rbuf = driver_alloc(alen+1);
    }
    strcpy(*rbuf,answer);
    return alen;
}