void test_null_poller_pointers (void *ctx) { int rc = zmq_poller_destroy (NULL); assert (rc == -1 && errno == EFAULT); void *null_poller = NULL; rc = zmq_poller_destroy (&null_poller); assert (rc == -1 && errno == EFAULT); void *socket = zmq_socket (ctx, ZMQ_PAIR); assert (socket != NULL); rc = zmq_poller_add (NULL, socket, NULL, ZMQ_POLLIN); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_add (&null_poller, socket, NULL, ZMQ_POLLIN); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_modify (NULL, socket, ZMQ_POLLIN); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_modify (&null_poller, socket, ZMQ_POLLIN); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_remove (NULL, socket); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_remove (&null_poller, socket); assert (rc == -1 && errno == EFAULT); fd_t fd; size_t fd_size = sizeof fd; rc = zmq_getsockopt(socket, ZMQ_FD, &fd, &fd_size); assert (rc == 0); rc = zmq_poller_add_fd (NULL, fd, NULL, ZMQ_POLLIN); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_add_fd (&null_poller, fd, NULL, ZMQ_POLLIN); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_modify_fd (NULL, fd, ZMQ_POLLIN); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_modify_fd (&null_poller, fd, ZMQ_POLLIN); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_remove_fd (NULL, fd); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_remove_fd (&null_poller, fd); assert (rc == -1 && errno == EFAULT); zmq_poller_event_t event; rc = zmq_poller_wait (NULL, &event, 0); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_wait (&null_poller, &event, 0); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_wait_all (NULL, &event, 1, 0); assert (rc == -1 && errno == EFAULT); rc = zmq_poller_wait_all (&null_poller, &event, 1, 0); assert (rc == -1 && errno == EFAULT); rc = zmq_close (socket); assert (rc == 0); }
void test_null_socket_pointers () { void *poller = zmq_poller_new (); assert (poller != NULL); int rc = zmq_poller_add (poller, NULL, NULL, ZMQ_POLLIN); assert (rc == -1 && errno == ENOTSOCK); rc = zmq_poller_modify (poller, NULL, ZMQ_POLLIN); assert (rc == -1 && errno == ENOTSOCK); rc = zmq_poller_remove (poller, NULL); assert (rc == -1 && errno == ENOTSOCK); fd_t null_socket_fd = retired_fd; rc = zmq_poller_add_fd (poller, null_socket_fd, NULL, ZMQ_POLLIN); assert (rc == -1 && errno == EBADF); rc = zmq_poller_modify_fd (poller, null_socket_fd, ZMQ_POLLIN); assert (rc == -1 && errno == EBADF); rc = zmq_poller_remove_fd (poller, null_socket_fd); assert (rc == -1 && errno == EBADF); rc = zmq_poller_destroy (&poller); assert (rc == 0); }
void test_add_modify_remove_corner_cases(void *ctx) { void *poller = zmq_poller_new (); assert (poller != NULL); void *zeromq_socket = zmq_socket (ctx, ZMQ_PAIR); assert (zeromq_socket != NULL); int rc = zmq_poller_add (poller, zeromq_socket, NULL, ZMQ_POLLIN); assert (rc == 0); // attempt to add the same socket twice rc = zmq_poller_add (poller, zeromq_socket, NULL, ZMQ_POLLIN); assert (rc == -1 && errno == EINVAL); rc = zmq_poller_remove (poller, zeromq_socket); assert (rc == 0); // attempt to remove socket that is not present rc = zmq_poller_remove (poller, zeromq_socket); assert (rc == -1 && errno == EINVAL); // attempt to modify socket that is not present rc = zmq_poller_modify (poller, zeromq_socket, ZMQ_POLLIN); assert (rc == -1 && errno == EINVAL); // add a socket with no events // TODO should this really be legal? it does not make any sense... rc = zmq_poller_add (poller, zeromq_socket, NULL, 0); assert (rc == 0); fd_t plain_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); rc = zmq_poller_add_fd (poller, plain_socket, NULL, ZMQ_POLLIN); assert (rc == 0); // attempt to add the same plain socket twice rc = zmq_poller_add_fd (poller, plain_socket, NULL, ZMQ_POLLIN); assert (rc == -1 && errno == EINVAL); rc = zmq_poller_remove_fd (poller, plain_socket); assert (rc == 0); // attempt to remove plain socket that is not present rc = zmq_poller_remove_fd (poller, plain_socket); assert (rc == -1 && errno == EINVAL); // attempt to modify plain socket that is not present rc = zmq_poller_modify_fd (poller, plain_socket, ZMQ_POLLIN); assert (rc == -1 && errno == EINVAL); rc = zmq_poller_destroy (&poller); assert (rc == 0); rc = zmq_close (zeromq_socket); assert (rc == 0); rc = close (plain_socket); assert (rc == 0); }
inline int zmq_poller_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) { // implement zmq_poll on top of zmq_poller int rc; zmq_poller_event_t *events; zmq::socket_poller_t poller; events = new (std::nothrow) zmq_poller_event_t[nitems_]; alloc_assert(events); bool repeat_items = false; // Register sockets with poller for (int i = 0; i < nitems_; i++) { items_[i].revents = 0; bool modify = false; short e = items_[i].events; if (items_[i].socket) { // Poll item is a 0MQ socket. for (int j = 0; j < i; ++j) { // Check for repeat entries if (items_[j].socket == items_[i].socket) { repeat_items = true; modify = true; e |= items_[j].events; } } if (modify) { rc = zmq_poller_modify (&poller, items_[i].socket, e); } else { rc = zmq_poller_add (&poller, items_[i].socket, NULL, e); } if (rc < 0) { delete [] events; return rc; } } else { // Poll item is a raw file descriptor. for (int j = 0; j < i; ++j) { // Check for repeat entries if (!items_[j].socket && items_[j].fd == items_[i].fd) { repeat_items = true; modify = true; e |= items_[j].events; } } if (modify) { rc = zmq_poller_modify_fd (&poller, items_[i].fd, e); } else { rc = zmq_poller_add_fd (&poller, items_[i].fd, NULL, e); } if (rc < 0) { delete [] events; return rc; } } } // Wait for events rc = zmq_poller_wait_all (&poller, events, nitems_, timeout_); if (rc < 0) { delete [] events; if (zmq_errno() == ETIMEDOUT) { return 0; } return rc; } // Transform poller events into zmq_pollitem events. // items_ contains all items, while events only contains fired events. // If no sockets are repeated (likely), the two are still co-ordered, so step through the items // checking for matches only on the first event. // If there are repeat items, they cannot be assumed to be co-ordered, // so each pollitem must check fired events from the beginning. int j_start = 0, found_events = rc; for (int i = 0; i < nitems_; i++) { for (int j = j_start; j < found_events; ++j) { if ( (items_[i].socket && items_[i].socket == events[j].socket) || (!(items_[i].socket || events[j].socket) && items_[i].fd == events[j].fd) ) { items_[i].revents = events[j].events & items_[i].events; if (!repeat_items) { // no repeats, we can ignore events we've already seen j_start++; } break; } if (!repeat_items) { // no repeats, never have to look at j > j_start break; } } } // Cleanup delete [] events; return rc; }