int main(int ac, char **av) { int lc; int pid; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); ++lc) { pid = tst_fork(); switch (pid) { case 0: send_events(); exit(0); case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); default: if (!check_events()) tst_resm(TFAIL, "Wrong data received in eventX"); else tst_resm(TPASS, "Data received in eventX"); break; } SAFE_WAITPID(NULL, pid, NULL, 0); } cleanup(); tst_exit(); }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ static void wrap_zmq_term(zmq_drv_t *drv) { zmqdrv_fprintf("term %p\r\n", drv->zmq_context); if (0 < drv->zmq_pid_socket.size()) { for (zmq_pid_socket_map_t::iterator it = drv->zmq_pid_socket.begin(); it != drv->zmq_pid_socket.end(); ++it) { zmq_sock_info* si = it->second; if (si->busy) { // Remove socket from erlang vm polling driver_select(drv->port, si->fd, ERL_DRV_READ, 0); if (si->out_caller) { reply_error(drv->port, si->out_caller, ETERM); si->out_caller = 0; zmq_msg_close(&si->out_msg); } if (si->in_caller) { reply_error(drv->port, si->in_caller, ETERM); si->in_caller = 0; } if (si->poll_caller) { send_events(drv->port, si->poll_caller, (uint32_t)ZMQ_POLLERR); si->poll_caller = 0; } si->busy = false; } } // TODO: Remove if zeromq itself ever gets fixed. As zmq_term() is a // blocking call, and will not return until all sockets are closed, // so do not allow it to be called while there are open sockets. drv->terminating = true; reply_error(drv->port, driver_caller(drv->port), EAGAIN); return; } // cross fingers and hope zmq_term() doesn't block, else we hardlock. if (0 != zmq_term(drv->zmq_context)) { reply_error(drv->port, driver_caller(drv->port), zmq_errno()); return; } drv->zmq_context = NULL; reply_ok(drv->port, driver_caller(drv->port)); }
static void wait_for_events (int listener) { char buf[BUFSIZ]; fd_set readfds; fd_set rfd; int highest = listener; int i, s; FD_ZERO(&readfds); FD_SET(listener, &readfds); while (run) { rfd = readfds; if (new_event) send_events(&readfds, highest, listener); if (select(highest + 1, &rfd, NULL, NULL, NULL) <= 0) continue; /* Find out which fds have data. */ for (i = 0; i <= highest; i++) { if (!FD_ISSET(i, &rfd)) continue; if (i == listener) { /* We have a new client. */ s = accept(i, NULL, 0); if (s < 0) perror("accept"); else { FD_SET(s, &readfds); if (s > highest) highest = s; } } else { /* An old client went away. */ s = read(i, buf, sizeof(buf)); if (s < 0) perror("read"); else if (s == 0) { close(i); FD_CLR(i, &readfds); highest = find_highest(&readfds, highest); } } } } }
void FilterClient::run_supplier () { this->wait_ready (); //Add delay so consumer won't miss any events. ACE_OS::sleep (5); send_events (); this->wait_consumer_complete (); }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ static void zmqdrv_ready_input(ErlDrvData handle, ErlDrvEvent event) { zmq_drv_t *drv = reinterpret_cast<zmq_drv_t*>(handle); zmq_sock_info *si = drv->get_socket_info(event); // I'm not sure if a race condition could develop here or not // So let's assert and see if we ever hit it. Hopefully not. assert(!drv->terminating); assert(NULL != si); assert(si->busy); // unregister event with erlang vm while we work with the socket driver_select(drv->port, si->fd, ERL_DRV_READ, 0); // Finish blocking recv request if input is ready if (si->in_caller) { zmq_msg_t msg; zmq_msg_init(&msg); if (0 == zmq_recv(si->socket, &msg, si->in_flags|ZMQ_NOBLOCK)) { // Unblock the waiting caller's pid by returning result reply_ok_binary(drv->port, si->in_caller, zmq_msg_data(&msg), zmq_msg_size(&msg)); si->in_caller = 0; si->in_flags = 0; } else if (zmq_errno() != EAGAIN) { // Unblock the waiting caller's pid by returning error reply_error(drv->port, si->in_caller, zmq_errno()); si->in_caller = 0; si->in_flags = 0; } // else no input was ready, continue waiting zmq_msg_close(&msg); } // Finish blocking send request if able if (si->out_caller) { if (0 == zmq_send(si->socket, &si->out_msg, si->out_flags|ZMQ_NOBLOCK)) { // Unblock the waiting caller's pid by returning result reply_ok(drv->port, si->out_caller); si->out_caller = 0; si->out_flags = 0; zmq_msg_close(&si->out_msg); } else if (zmq_errno() != EAGAIN) { // Unblock the waiting caller's pid by returning error reply_error(drv->port, si->out_caller, zmq_errno()); si->out_caller = 0; si->out_flags = 0; zmq_msg_close(&si->out_msg); } // else not able to send, continue waiting } // Finish poll request if events available if (si->poll_caller) { uint32_t revents = 0; size_t revents_size = sizeof(revents); if (0 == zmq_getsockopt(si->socket, ZMQ_EVENTS, &revents, &revents_size)) { revents &= si->poll_events; if (0 != revents) { send_events(drv->port, si->poll_caller, revents); si->poll_caller = 0; si->poll_events = 0; } // else no requested events pending, continue waiting } else { // EINVAL will only occur if our getsockopt call was invalid assert(EINVAL != zmq_errno()); // send out of band event error notification send_events(drv->port, si->poll_caller, (uint32_t)ZMQ_POLLERR); si->poll_caller = 0; si->poll_events = 0; } } // reregister event with erlang vm if any pending operations exist if (si->poll_caller || si->in_caller || si->out_caller) { driver_select(drv->port, si->fd, ERL_DRV_READ, 1); } else { si->busy = false; } }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ static void wrap_zmq_poll(zmq_drv_t *drv, const uint8_t* bytes, size_t size) { uint32_t events = *bytes; 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; } zmqdrv_fprintf("poll %p (events: %u)\r\n", si->socket, events); if (0 == events) { si->poll_events = 0; si->poll_caller = 0; if (si->busy && 0 == si->in_caller && 0 == si->out_caller) { driver_select(drv->port, si->fd, ERL_DRV_READ, 0); si->busy = false; } reply_ok(drv->port, caller); return; } if (si->busy) { reply_error(drv->port, caller, EBUSY); return; } assert((ZMQ_POLLIN|ZMQ_POLLOUT) & events); uint32_t revents; size_t revents_size = sizeof(revents); if (0 == zmq_getsockopt(si->socket, ZMQ_EVENTS, &revents, &revents_size)) { // reply immediately; poll event notification happens out of band. reply_ok(drv->port, caller); revents &= events; if (0 != revents) { send_events(drv->port, caller, revents); } else { // No matching pending event, wait for one. zmqdrv_fprintf("poll %p blocking\r\n", si->socket); si->poll_events = events; si->poll_caller = caller; si->busy = true; driver_select(drv->port, si->fd, ERL_DRV_READ, 1); } } else { // EINVAL will only occur if our getsockopt call was invalid assert(EINVAL != zmq_errno()); // else the problem was with the context/socket, and should be returned reply_error(drv->port, caller, zmq_errno()); } }
/* Handle incoming connections */ void server_loop () { struct sockaddr_un client_name; socklen_t name_len = sizeof (client_name); logit ("MOC server started, pid: %d", getpid()); assert (server_sock != -1); log_circular_start (); do { int res; fd_set fds_write, fds_read; FD_ZERO (&fds_read); FD_ZERO (&fds_write); FD_SET (server_sock, &fds_read); FD_SET (wake_up_pipe[0], &fds_read); add_clients_fds (&fds_read, &fds_write); res = 0; if (!server_quit) res = select (max_fd(server_sock)+1, &fds_read, &fds_write, NULL, NULL); if (res == -1 && errno != EINTR && !server_quit) fatal ("select() failed: %s", xstrerror (errno)); if (!server_quit && res >= 0) { if (FD_ISSET(server_sock, &fds_read)) { int client_sock; debug ("accept()ing connection..."); client_sock = accept (server_sock, (struct sockaddr *)&client_name, &name_len); if (client_sock == -1) fatal ("accept() failed: %s", xstrerror (errno)); logit ("Incoming connection"); if (!add_client(client_sock)) busy (client_sock); } if (FD_ISSET(wake_up_pipe[0], &fds_read)) { int w; logit ("Got 'wake up'"); if (read(wake_up_pipe[0], &w, sizeof(w)) < 0) fatal ("Can't read wake up signal: %s", xstrerror (errno)); } send_events (&fds_write); handle_clients (&fds_read); } if (server_quit) logit ("Exiting..."); } while (!server_quit); log_circular_log (); log_circular_stop (); close_clients (); clients_cleanup (); close (server_sock); server_sock = -1; server_shutdown (); }
static bool handle_input(struct input_state *st, int out_fd) { struct input_event ev; ssize_t l; unsigned long mask = 0, value; bool do_submit = false; l = read(st->fd, &ev, sizeof ev); if (l == 0 || (l < 0 && errno == ENODEV)) return false; if (l < 0) { err("read(<event>): %m"); exit(1); } if (l != sizeof ev) abort(); switch (ev.type) { case EV_KEY: st->is_raw = false; switch (ev.code) { case KEY_LEFTMETA: case KEY_RIGHTMETA: mask = MODE_META; break; case KEY_LEFTCTRL: case KEY_RIGHTCTRL: mask = MODE_CTRL; break; case KEY_LEFTALT: case KEY_RIGHTALT: mask = MODE_ALT; break; case KEY_LEFTSHIFT: case KEY_RIGHTSHIFT: mask = MODE_SHIFT; break; case KEY_NUMLOCK: mask = MODE_NUMLOCK; break; } if (mask) { if (ev.value) value = mask; else value = 0; st->mode &= ~mask; st->mode |= value; if (st->mode != MODE_ALT && st->is_alt) { ev.value = 1; do_submit = true; } } else if (st->mode == MODE_ALT && ev.value == 0) ; /* noop */ else if (st->mode == MODE_ALT) { int num_code = -1; switch (ev.code) { case KEY_KP0: num_code = 0; break; case KEY_KP1: num_code = 1; break; case KEY_KP2: num_code = 2; break; case KEY_KP3: num_code = 3; break; case KEY_KP4: num_code = 4; break; case KEY_KP5: num_code = 5; break; case KEY_KP6: num_code = 6; break; case KEY_KP7: num_code = 7; break; case KEY_KP8: num_code = 8; break; case KEY_KP9: num_code = 9; break; default: num_code = -1; break; } st->is_alt = num_code != -1; if (!st->is_alt) { st->key = ev.code; do_submit = true; } else st->key = st->key * 10 + num_code; } else if (st->is_alt) { ev.value = 0; do_submit = true; st->is_alt = false; } else { st->key = ev.code; do_submit = true; } break; case EV_SYN: if (st->is_raw && !send_events(out_fd, &ev, 1)) exit(1); st->is_raw = false; break; case EV_MSC: break; case EV_REL: if (!send_events(out_fd, &ev, 1)) exit(1); st->is_raw = true; break; case EV_REP: break; default: ; warn("unsupported event type %02x\n", ev.type); break; } if (do_submit) { int found; st->ev[0].time = ev.time; st->ev[1].time = ev.time; st->ev[1].value = ev.value; st->ev[2].time = ev.time; st->ev[2].type = EV_SYN; st->ev[2].code = SYN_REPORT; st->ev[2].value = 0; if (ev.value) found = fill_key(st->ev, st->mode | (st->is_alt ? MODE_NUMALT : 0), st->key); else found = true; if (found) { bool send_scancode = st->ev[1].value == 1; if (!send_events(out_fd, send_scancode ? &st->ev[0] : &st->ev[1], send_scancode ? 3 : 2)) exit(1); } else warn("unknown code M(%u,%u,%u,%u,%u) %d %d %ld\n", !!(st->mode & MODE_META), !!(st->mode & MODE_CTRL), !!(st->mode & MODE_SHIFT), !!(st->mode & MODE_ALT), !!st->is_alt, st->key, ev.value, (st->mode & MODE_NUMLOCK)); st->key = 0; } return true; }