It does not like .patch, sorry about that.

--
Norman


> -----Original Message-----
> From: Casagrande, Norman
> Sent: 10 July 2009 12:22
> To: [email protected]
> Subject: RE: Stopping persistent connections on TThreadedServer (C++
only?)
> 
> Here's a simple patch to address the issue. Note that TSocket should
> also be changed if you want to avoid the TTransportException exception
> being thrown.
> 
> --
> Norman Casagrande
> Head of Music Research
> last.fm
> 
> 
> > -----Original Message-----
> > From: Casagrande, Norman
> > Sent: 10 July 2009 11:51
> > To: [email protected]
> > Subject: Stopping persistent connections on TThreadedServer (C++
> only?)
> >
> > Hi,
> >
> > Apparently TThreadedServer (and TThreadPoolServer) does not stop the
> > tasks that are waiting on a persistent connection even if the server
> is
> > halted with stop() or its transport is closed.
> >
> > Looking at the code (ThreadedServer.cpp) it seems TThreadedServer is
> > waiting here:
> >
> > 230      Synchronized s(tasksMonitor_);
> > 231      while (!tasks_.empty()) {
> > 232        tasksMonitor_.wait();
> > 233      }
> >
> > The task is stuck here:
> >
> > 61      while (processor_->process(input_, output_)) {
> > 62        if (!input_->getTransport()->peek()) {
> > 63          break;
> > 64        }
> > 65      }
> >
> > Which means that in the TSocket.cpp code the task is waiting here:
> >
> > 108     int r = recv(socket_, &buf, 1, MSG_PEEK);
> >
> > The socket is local, so it never gets invalidated thus waiting
> forever.
> >
> > Any suggestion?
> >
> > --
> > Norman

Index: TThreadedServer.cpp
===================================================================
--- TThreadedServer.cpp (revision 792885)
+++ TThreadedServer.cpp (working copy)
@@ -50,7 +50,11 @@
   }
 
   ~Task() {}
-
+  
+  void stop() {
+     input_->getTransport()->close();
+  }
+  
   void run() {
     boost::shared_ptr<TServerEventHandler> eventHandler =
       server_.getEventHandler();
@@ -228,6 +232,8 @@
     }
     try {
       Synchronized s(tasksMonitor_);
+      for ( std::set<Task*>::iterator tIt = tasks_.begin(); tIt != 
tasks_.end(); ++tIt )
+         (*tIt)->stop();
       while (!tasks_.empty()) {
         tasksMonitor_.wait();
       }

Reply via email to