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

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_r59410629
  
    --- 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 --
    
    This busted StressTest and StressTestNonBlocking because they are coded to 
assume that the thread shared pointer will hold on to the runnable after the 
thread is gone.  The TConnectedClientTracker is therefore necessary to avoid 
breaking existing clients that might depend on this behavior of Thread, so I am 
not going to simplify to a map of TConnectedClient* to shared_ptr<Thread>.


> 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