X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=shared%2Fhttpd.cpp;h=74d0c26d72b1252ae1485490ab2daef41725211c;hb=1bb1c66b1548cbad52cc107b40f24a330edca2e1;hp=09c065693f005dbcd137b95f1ade099f387a27e5;hpb=2cb648106d32b9968f2026536fbead096308c7d1;p=nageru diff --git a/shared/httpd.cpp b/shared/httpd.cpp index 09c0656..74d0c26 100644 --- a/shared/httpd.cpp +++ b/shared/httpd.cpp @@ -45,7 +45,6 @@ void HTTPD::start(int port) port, nullptr, nullptr, &answer_to_connection_thunk, this, - MHD_OPTION_NOTIFY_COMPLETED, nullptr, this, MHD_OPTION_END); if (mhd == nullptr) { fprintf(stderr, "Warning: Could not open HTTP server. (Port already in use?)\n"); @@ -209,10 +208,23 @@ ssize_t HTTPD::Stream::reader_callback_thunk(void *cls, uint64_t pos, char *buf, ssize_t HTTPD::Stream::reader_callback(uint64_t pos, char *buf, size_t max) { unique_lock lock(buffer_mutex); - has_buffered_data.wait(lock, [this] { return should_quit || !buffered_data.empty(); }); + bool has_data = has_buffered_data.wait_for(lock, std::chrono::seconds(60), [this] { return should_quit || !buffered_data.empty(); }); if (should_quit) { return -1; } + if (!has_data) { + // The wait timed out, so tell microhttpd to clean out the socket; + // it's not unlikely that the client has given up anyway. + // This is seemingly the only way to actually reap sockets if we + // do not get any data; returning 0 does nothing, and + // MHD_OPTION_NOTIFY_CONNECTION does not trigger for these cases. + // If not, an instance that has no data to send (typically an instance + // of kaeru connected to a nonfunctional backend) would get a steadily + // increasing amount of sockets in CLOSE_WAIT (ie., the other end has + // hung up, but we haven't called close() yet, as our thread is stuck + // in this callback). + return -1; + } ssize_t ret = 0; while (max > 0 && !buffered_data.empty()) {