//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 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; }
// 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); } }