From 783811316469bcfc6fbdaf5cdb7f407895dc0253 Mon Sep 17 00:00:00 2001 From: matzman Date: Wed, 3 Jun 2015 09:13:36 +0200 Subject: [PATCH] . --- .../webresource/DeviceRepoHandler.cpp | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.cpp b/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.cpp index 3e9fe386..26c4ad65 100644 --- a/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.cpp +++ b/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.cpp @@ -330,31 +330,43 @@ void DeviceRepoHandler::__handleCommand(Poco::Net::HTTPServerRequest &req, Poco: void DeviceRepoHandler::__handleEventLongPolling(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, DeviceEventQueue* eventQueue) { Variant msg; bool breakLoop = false; - parent->getIOService().post([&]() { - Net::HTTPServerRequestImpl* reqImpl = static_cast(&req); - // I don't like the content of this loop at all. - while (!breakLoop) { + boost::asio::deadline_timer connCheckTimer(parent->getIOService()); + Net::HTTPServerRequestImpl* reqImpl = static_cast(&req); + std::mutex _m; + std::function connCheckFun = [&](const boost::system::error_code& error) { + if (error != boost::asio::error::operation_aborted) { + std::lock_guard _l(_m); // How to find out whether the client disconnected: Monitor the socket with Posix "select": // If select says that there is data, available() returns 0 then apparently the client has disconnected. // WTF, is this really the only way to notice that a client properly disconnected? Internet says so. - auto sockfs = reqImpl->socket().impl()->sockfd(); - fd_set fds; - FD_ZERO(&fds); - FD_SET(sockfs, &fds); + // And don't move anything outside, everything needs to be inside to work + auto sockfs = reqImpl->socket().impl()->sockfd(); + fd_set fds; + FD_ZERO(&fds); + FD_SET(sockfs, &fds); struct timeval timeout = {0, 1000}; int sel = select(sockfs + 1, &fds, 0, 0, &timeout); + std::cout << "Debug03: " << sel << " - " << reqImpl->socket().available() << " - " << sockfs << std::endl; if (sel < 0 || (sel > 0 && reqImpl->socket().available() == 0)) { ROS_ERROR_STREAM("Apparently we have a disconnect in device event queue \"" << eventQueue->clientID << "\""); breakLoop = true; eventQueue->cancelPopEvent(); } + connCheckTimer.expires_from_now(boost::posix_time::milliseconds(100)); + connCheckTimer.async_wait(connCheckFun); } - }); + }; + connCheckTimer.expires_from_now(boost::posix_time::milliseconds(100)); + connCheckTimer.async_wait(connCheckFun); try { msg = eventQueue->popEvent(); } catch (DeviceEventQueue::DisconnectedException& e) { } - breakLoop = true; + { + std::lock_guard _l(_m); + breakLoop = true; + connCheckTimer.cancel(); + } handleResponse(req, resp, msg); }; @@ -579,6 +591,7 @@ libvariant::Variant DeviceEventQueue::popEvent() { FD_SET(sockfs, &fds); struct timeval timeout = {0, 1}; int sel = select(sockfs + 1, &fds, 0, 0, &timeout); + std::cout << "Debug01: " << sel << " - " << reqImpl->socket().available() << " - " << sockfs << std::endl; if (sel > 0 && reqImpl->socket().available() == 0) { ROS_ERROR_STREAM("Apparently we have a disconnect in device event queue \"" << clientID << "\""); throw DisconnectedException();