void Server::checkAndDispatchEpoll(int epollMillis) { constexpr int maxEvents = 256; epoll_event events[maxEvents]; std::list<Connection*> toBeDeleted; int numEvents = epoll_wait(_epollFd, events, maxEvents, epollMillis); if (numEvents == -1) { if (errno != EINTR) { LS_ERROR(_logger, "Error from epoll_wait: " << getLastError()); } return; } if (numEvents == maxEvents) { static time_t lastWarnTime = 0; time_t now = time(nullptr); if (now - lastWarnTime >= 60) { LS_WARNING(_logger, "Full event queue; may start starving connections. " "Will warn at most once a minute"); lastWarnTime = now; } } for (int i = 0; i < numEvents; ++i) { if (events[i].data.ptr == this) { if (events[i].events & ~EPOLLIN) { LS_SEVERE(_logger, "Got unexpected event on listening socket (" << EventBits(events[i].events) << ") - terminating"); _terminate = true; break; } handleAccept(); } else if (events[i].data.ptr == &_eventFd) { if (events[i].events & ~EPOLLIN) { LS_SEVERE(_logger, "Got unexpected event on management pipe (" << EventBits(events[i].events) << ") - terminating"); _terminate = true; break; } handlePipe(); } else { auto connection = reinterpret_cast<Connection*>(events[i].data.ptr); if (handleConnectionEvents(connection, events[i].events) == Close) { toBeDeleted.push_back(connection); } } } // The connections are all deleted at the end so we've processed any other subject's // closes etc before we call onDisconnect(). for (auto it = toBeDeleted.begin(); it != toBeDeleted.end(); ++it) { auto connection = *it; if (_connections.find(connection) == _connections.end()) { LS_SEVERE(_logger, "Attempt to delete connection we didn't know about: " << (void*)connection << formatAddress(connection->getRemoteAddress())); _terminate = true; break; } LS_DEBUG(_logger, "Deleting connection: " << formatAddress(connection->getRemoteAddress())); delete connection; } }
/*JSON{ "type" : "idle", "generate" : "jswrap_pipe_idle", "ifndef" : "SAVE_ON_FLASH" }*/ bool jswrap_pipe_idle() { bool wasBusy = false; JsVar *arr = pipeGetArray(false); if (arr) { JsvObjectIterator it; jsvObjectIteratorNew(&it, arr); while (jsvObjectIteratorHasValue(&it)) { JsVar *pipe = jsvObjectIteratorGetValue(&it); wasBusy |= handlePipe(arr, &it, pipe); jsvUnLock(pipe); jsvObjectIteratorNext(&it); } jsvObjectIteratorFree(&it); jsvUnLock(arr); } return wasBusy; }