PFPSimDebugger::DebugMsg* DebuggerIPCServer::recv() { struct nn_pollfd pfd; pfd.fd = socket; pfd.events = NN_POLLIN; auto rc = nn_poll(&pfd, 1, 100); if (rc == 0) { return nullptr; } if (rc == -1) { // TODO(gordon) printf("Error!"); exit(1); } if (pfd.revents & NN_POLLIN) { char *buf; int bytes = nn_recv(socket, &buf, NN_MSG, 0); if (bytes != -1) { std::string message_string(buf, bytes); nn_freemsg(buf); PFPSimDebugger::DebugMsg *message = new PFPSimDebugger::DebugMsg(); message->ParseFromString(message_string); return message; } else { return nullptr; } } else { return nullptr; } }
JNIEXPORT jint JNICALL Java_org_nanomsg_NanoLibrary_nn_1poll(JNIEnv* env, jobject obj, jobjectArray pollfds, jint timeout) { jsize length = (*env)->GetArrayLength(env, pollfds); if (length <= 0) return -1; struct nn_pollfd *pfds = (struct nn_pollfd *) malloc(sizeof(struct nn_pollfd) * length); NANO_ASSERT(pfds); int i; for (i = 0; i < length; ++i) { jobject pollfd = (*env)->GetObjectArrayElement(env, pollfds, i); pfds[i].fd = (*env)->GetIntField(env, pollfd, pollfd_fd); pfds[i].events = (*env)->GetIntField(env, pollfd, pollfd_events); } int ret = nn_poll(pfds, length, timeout); if (ret > 0) { for (i = 0; i < length; ++i) { jobject pollfd = (*env)->GetObjectArrayElement(env, pollfds, i); (*env)->SetIntField(env, pollfd, pollfd_revents, pfds[i].revents); (*env)->SetObjectArrayElement(env, pollfds, i, pollfd); } } free(pfds); return ret; }
int32_t nn_socket_status(int32_t sock,int32_t timeoutmillis) { struct nn_pollfd pfd; int32_t rc; pfd.fd = sock; pfd.events = NN_POLLIN | NN_POLLOUT; if ( (rc= nn_poll(&pfd,1,timeoutmillis)) == 0 ) return(pfd.revents); else return(-1); }
// Wait until socketA or socketB has something to tell us, and return which one. static int poll_in(int socketA, int socketB) { struct nn_pollfd polls[] = { { socketA, NN_POLLIN, 0 }, { socketB, NN_POLLIN, 0 }, }; nn_poll(polls, SK_ARRAY_COUNT(polls), -1/*no timeout*/); if (polls[0].revents & NN_POLLIN) { return socketA; } if (polls[1].revents & NN_POLLIN) { return socketB; } SkFAIL("unreachable"); return 0; }
std::pair<int, boost::optional<NanoMessage>> NanoSocket::Poll(NanoSocket **sockets, size_t len, std::chrono::milliseconds timeout) throw() { std::vector<nn_pollfd> pfds; std::stringstream trace; trace << "Polling [ "; for (size_t i=0; i<len; ++i) { nn_pollfd pfd; pfd.fd = sockets[i]->m_socket; pfd.events = NN_POLLIN; pfds.push_back(pfd); trace << pfd.fd << " "; } std::cout << trace.str() << "]" << std::endl; boost::optional<NanoMessage> message; int rc = nn_poll(&pfds[0], len, -1); if (rc == -1) { throw NanoException(); } int socketIndex = -1; if (rc > 0) { for (size_t i=0; i<len; ++i) { if (pfds[i].revents & NN_POLLIN) { socketIndex = i; break; } } } if (socketIndex >= 0) { message = sockets[socketIndex]->Recv(); } return std::make_pair(socketIndex, message); }
void subscribe_socket::thread_function() { int rc = 0; while(!shutting_down) { nn_pollfd pollitem; pollitem.fd = z_socket; pollitem.revents = 0; pollitem.events = NN_POLLIN; rc = nn_poll(&pollitem, 1, RECV_TIMEOUT); if (rc <= 0) continue; char* buf = NULL; size_t len = NN_MSG; rc = nn_recv(z_socket, reinterpret_cast<void*>(&buf), len, 0); if (rc < 0) continue; std::string val(buf, rc); callback(val); nn_freemsg(buf); } }
/**@brief Start cursor server*/ void Cursor::Run(const Config&& cfg) { if (cfg.urls.empty()) { LOG(INFO) << "No URL to bind on. Quit."; return; } shared_curr_ = cfg.shared_curr; shared_total_ = cfg.shared_total; std::vector<MixerT::InRangeT> fiters; std::vector<std::shared_ptr<std::ifstream>> ifiles; for (auto fname : cfg.extra_fnames) { ifiles.emplace_back(new std::ifstream(fname.c_str())); if (!ifiles.back()->is_open()) { LOG(ERROR) << _("Error file opening.") << _(" Filename: \"") << fname << "\""; continue; } fiters.emplace_back(MixerT::InRangeT(LineIterT(*ifiles.back()), LineIterT())); } extra_delim_ = cfg.extra_delim; extra_state_.reset(new MixerT(fiters, cfg.extra_mix ? MixerT::MIX_SHUFFLE : MixerT::MIX_NONE, 0xABCDEF0F)); std::vector<int> socks; for (auto url : cfg.urls) { int sock = nn_socket(AF_SP, NN_PAIR); if (sock < 0) { LOG(ERROR) << _("Error creating socket.") << _(" Message: ") << nn_strerror(errno); return; } if (nn_bind(sock, url.c_str()) < 0) { LOG(ERROR) << _("Error binding socket.") << _(" Message: ") << nn_strerror(errno); return; } LOG(INFO) << _("Starting cursor.") << _(" URL: ") << url; socks.push_back(sock); } struct nn_pollfd* pfd = new nn_pollfd[socks.size()]; while( true ) { for (size_t i = 0; i < socks.size(); ++i) { pfd[i].fd = socks[i]; pfd[i].events = NN_POLLIN; } int rs = nn_poll (pfd, socks.size(), 1000); if (rs == 0) { if(state_ & STATE_STOP) break; continue; } if (rs == -1) { if (rs != EINTR) { LOG(ERROR) << _("Error calling select.") << _(" Message: ") << nn_strerror(errno); state_ = STATE_STOP | STATE_ERROR; } continue; } for (size_t i = 0; i < socks.size(); ++i) { if (pfd[i].revents & NN_POLLIN) { char *buf = NULL; int bufsz = nn_recv (pfd[i].fd, &buf, NN_MSG, 0); if (bufsz < 0) { LOG(ERROR) << _("Error data receiving.") << _(" Message: ") << nn_strerror(errno); state_ = STATE_STOP | STATE_ERROR; nn_freemsg (buf); continue; } nx::String request = nx::String::fromUTF8( std::string(buf, buf + bufsz)).trim().toLower(); nn_freemsg (buf); nx::String reply; if(request == "speed") { reply = nx::String::fromASCII(speedometer_.AVGSpeedS()) + L" " + nx::String::fromASCII(speedometer_.LastSpeedS()); } else if(request == "stop") { LOG(INFO) << _("Received stop signal. Setting STATE_STOP."); state_ = state_ | STATE_STOP; continue; } else if(request == "get") { ++speedometer_; if(state_ == STATE_STOP) { LOG(INFO) << _("Received GET in STATE_STOP"); reply = L"END"; } else { if(buf_.empty()) { Next(bufsz_, buf_); if(buf_.empty()) { LOG(INFO) << _("Cursor is empty. Stopping."); state_ = state_ | STATE_STOP; reply = L"END"; } else { LOG(INFO) << "Renew buffer. Last element: " << buf_.back().toUTF8(); } } if(!(state_ & STATE_STOP)) { reply = buf_.front(); buf_.pop_front(); } } } else { LOG(WARNING) << _("Unknown request: ") << request.toUTF8(); continue; } std::string reply_utf8 = reply.toUTF8(); rs = nn_send(pfd[i].fd, reply_utf8.c_str(), reply_utf8.length(), 0); } } if(rs < 0) { LOG(ERROR) << _("Error sending reply.") << _(" Message: ") << nn_strerror(errno); state_ = STATE_STOP | STATE_ERROR; } } delete [] pfd; for (auto sock : socks) { nn_shutdown(sock, 0); nn_close(sock); } }
int poll(pollfd *fds, int nfds, int timeout) { return check_error(nn_poll(fds, nfds, timeout)); }
int main () { int rc; int sb; char buf [3]; struct nn_thread thread; struct nn_pollfd pfd [2]; /* Test nn_poll() function. */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); test_send (sc, "ABC"); nn_sleep (100); pfd [0].fd = sb; pfd [0].events = NN_POLLIN | NN_POLLOUT; pfd [1].fd = sc; pfd [1].events = NN_POLLIN | NN_POLLOUT; rc = nn_poll (pfd, 2, -1); errno_assert (rc >= 0); nn_assert (rc == 2); nn_assert (pfd [0].revents == (NN_POLLIN | NN_POLLOUT)); nn_assert (pfd [1].revents == NN_POLLOUT); test_close (sc); test_close (sb); /* Create a simple topology. */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); /* Check the initial state of the socket. */ rc = getevents (sb, NN_IN | NN_OUT, 1000); nn_assert (rc == NN_OUT); /* Poll for IN when there's no message available. The call should time out. */ rc = getevents (sb, NN_IN, 10); nn_assert (rc == 0); /* Send a message and start polling. This time IN event should be signaled. */ test_send (sc, "ABC"); rc = getevents (sb, NN_IN, 1000); nn_assert (rc == NN_IN); /* Receive the message and make sure that IN is no longer signaled. */ test_recv (sb, "ABC"); rc = getevents (sb, NN_IN, 10); nn_assert (rc == 0); /* Check signalling from a different thread. */ nn_thread_init (&thread, routine1, NULL); rc = getevents (sb, NN_IN, 1000); nn_assert (rc == NN_IN); test_recv (sb, "ABC"); nn_thread_term (&thread); /* Check terminating the library from a different thread. */ nn_thread_init (&thread, routine2, NULL); rc = getevents (sb, NN_IN, 1000); nn_assert (rc == NN_IN); rc = nn_recv (sb, buf, sizeof (buf), 0); nn_assert (rc < 0 && nn_errno () == ETERM); nn_thread_term (&thread); /* Clean up. */ test_close (sc); test_close (sb); return 0; }
/* Thread */ void *janus_nanomsg_thread(void *data) { JANUS_LOG(LOG_INFO, "Nanomsg thread started\n"); int fds = 0; struct nn_pollfd poll_nfds[3]; /* FIXME Should we allow for more clients? */ char buffer[BUFFER_SIZE]; while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) { /* Prepare poll list of file descriptors */ fds = 0; /* Writeable monitor */ poll_nfds[fds].fd = write_nfd[0]; poll_nfds[fds].events = NN_POLLIN; fds++; if(nfd > -1) { /* Janus API */ poll_nfds[fds].fd = nfd; poll_nfds[fds].events = NN_POLLIN; if(client.messages != NULL && g_async_queue_length(client.messages) > 0) poll_nfds[fds].events |= NN_POLLOUT; fds++; } if(admin_nfd > -1) { /* Admin API */ poll_nfds[fds].fd = admin_nfd; poll_nfds[fds].events = NN_POLLIN; if(admin_client.messages != NULL && g_async_queue_length(admin_client.messages) > 0) poll_nfds[fds].events |= NN_POLLOUT; fds++; } /* Start polling */ int res = nn_poll(poll_nfds, fds, -1); if(res == 0) continue; if(res < 0) { if(errno == EINTR) { JANUS_LOG(LOG_HUGE, "Got an EINTR (%s) polling the Nanomsg descriptors, ignoring...\n", nn_strerror(errno)); continue; } JANUS_LOG(LOG_ERR, "poll() failed: %d (%s)\n", errno, nn_strerror(errno)); break; } int i = 0; for(i=0; i<fds; i++) { /* FIXME Is there a Nanomsg equivalent of POLLERR? */ if(poll_nfds[i].revents & NN_POLLOUT) { /* Find the client from its file descriptor */ if(poll_nfds[i].fd == nfd || poll_nfds[i].fd == admin_nfd) { char *payload = NULL; while((payload = g_async_queue_try_pop(poll_nfds[i].fd == nfd ? client.messages : admin_client.messages)) != NULL) { int res = nn_send(poll_nfds[i].fd, payload, strlen(payload), 0); /* FIXME Should we check if sent everything? */ JANUS_LOG(LOG_HUGE, "Written %d/%zu bytes on %d\n", res, strlen(payload), poll_nfds[i].fd); g_free(payload); } } } if(poll_nfds[i].revents & NN_POLLIN) { if(poll_nfds[i].fd == write_nfd[0]) { /* Read and ignore: we use this to unlock the poll if there's data to write */ (void)nn_recv(poll_nfds[i].fd, buffer, BUFFER_SIZE, 0); } else if(poll_nfds[i].fd == nfd || poll_nfds[i].fd == admin_nfd) { /* Janus/Admin API: get the message from the client */ int res = nn_recv(poll_nfds[i].fd, buffer, BUFFER_SIZE, 0); if(res < 0) { JANUS_LOG(LOG_WARN, "Error receiving %s API message... %d (%s)\n", poll_nfds[i].fd == nfd ? "Janus" : "Admin", errno, nn_strerror(errno)); continue; } /* If we got here, there's data to handle */ buffer[res] = '\0'; JANUS_LOG(LOG_VERB, "Got %s API message (%d bytes)\n", poll_nfds[i].fd == nfd ? "Janus" : "Admin", res); JANUS_LOG(LOG_HUGE, "%s\n", buffer); /* Parse the JSON payload */ json_error_t error; json_t *root = json_loads(buffer, 0, &error); /* Notify the core, passing both the object and, since it may be needed, the error */ gateway->incoming_request(&janus_nanomsg_transport, poll_nfds[i].fd == nfd ? client.ts : admin_client.ts, NULL, poll_nfds[i].fd == nfd ? FALSE : TRUE, root, &error); } } } } nn_close(write_nfd[0]); nn_close(write_nfd[1]); if(nfd > -1) { nn_shutdown(nfd, nfd_addr); nn_close(nfd); janus_transport_session_destroy(client.ts); client.ts = NULL; } if(admin_nfd > -1) { nn_shutdown(admin_nfd, admin_nfd_addr); nn_close(admin_nfd); janus_transport_session_destroy(admin_client.ts); admin_client.ts = NULL; } /* Done */ JANUS_LOG(LOG_INFO, "Nanomsg thread ended\n"); return NULL; }