[ 
https://issues.apache.org/jira/browse/THRIFT-3768?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15237323#comment-15237323
 ] 

ASF GitHub Bot commented on THRIFT-3768:
----------------------------------------

Github user jeking3 commented on a diff in the pull request:

    https://github.com/apache/thrift/pull/980#discussion_r59390673
  
    --- Diff: lib/cpp/src/thrift/server/TThreadedServer.h ---
    @@ -83,12 +88,56 @@ class TThreadedServer : public TServerFramework {
       virtual void serve();
     
     protected:
    +  /**
    +   * Drain recently connected clients by joining their threads - this is 
done lazily because
    +   * we cannot do it inside the thread context that is disconnecting.
    +   */
    +  virtual void drainDeadClients();
    +
    +  /**
    +   * Implementation of TServerFramework::onClientConnected
    +   */
       virtual void onClientConnected(const 
boost::shared_ptr<TConnectedClient>& pClient) /* override */;
    -  virtual void onClientDisconnected(TConnectedClient* pClient) /* override 
*/;
    +
    +  /**
    +   * Implementation of TServerFramework::onClientDisconnected
    +   */
    +  virtual void onClientDisconnected(TConnectedClient *pClient) /* override 
*/;
     
       boost::shared_ptr<apache::thrift::concurrency::ThreadFactory> 
threadFactory_;
    -  apache::thrift::concurrency::Monitor clientsMonitor_;
    +
    +  /**
    +   * A helper wrapper used to wrap the client in something we can use to 
maintain
    +   * the lifetime of the connected client within a detached thread.
    --- End diff --
    
    I made this change and it will only work if I modify each of the thread 
implementations to release the smart_ptr to runnable in the thread class after 
the thread runs.  I assume this is acceptable; once the runnable runs we don't 
need the thread smart_ptr holding on to it any more; TServerFramework requires 
the TConnectedClient (the runnable) to be destroyed when the client disconnects 
to function properly.


> TThreadedServer may crash if it is destroyed immediately after it returns 
> from serve(); TThreadedServer disconnects clients when they connec
> --------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: THRIFT-3768
>                 URL: https://issues.apache.org/jira/browse/THRIFT-3768
>             Project: Thrift
>          Issue Type: Bug
>          Components: C++ - Library
>    Affects Versions: 0.9.3
>            Reporter: Ted Wang
>            Assignee: James E. King, III
>            Priority: Minor
>
> Here's a sequence that shows the race:
> Thread-1 (Users of TThreadedServer): Calls TThreadedServer::stop(), which 
> calls interruptChildren and initiates the tearing down of client connections.
> Thread-2: In TServerFramework::serve(), broke out of accept, and now blocks 
> in TThreadedServer::serve() waiting to drain all the clients.
> Thread-3 (The connected client thread created by TThreadedServer): In 
> disposeConnectedClient, running because the server is shutting down and the 
> shared_ptr specified this function to be the cleanup function for the client. 
> This thread just returned from onClientDisconnected and now context switches.
> Thread-2: TThreadedServer::serve() is notified that all of the clients have 
> disconnected and completes.
> Thread-1: Joins on Thread-2 and destroys the server object because it is done.
> Thread-3: Finally gets a chance to run, but now encounters undefined behavior 
> because it is still executing a member function of an object that has been 
> destroyed.
> You can force this race in action if you put sleep(1) before 
> onClientDisconnected() in disposeConnectedClient



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to