9d1e678
From 5b29409ae1ec8c75296a257dfc02b6acb296a527 Mon Sep 17 00:00:00 2001
9d1e678
From: Stephan Bergmann <sbergman@redhat.com>
9d1e678
Date: Thu, 13 Dec 2012 15:41:10 +0100
9d1e678
Subject: [PATCH 2/2] Related fdo#33484: Terminate OfficeIPCThread by closing
9d1e678
 the accepting pipe
9d1e678
9d1e678
... (and setting mbDowning to indicate an error returned from accept() is due to
9d1e678
termination) instead of setting up an extra pipe connection to send an
9d1e678
"InternalIPC::TerminateThread" message (which allegedly caused deadlocks, see
9d1e678
<https://gerrit.libreoffice.org/#/c/1311/> "Change Idf933915: office ipc: use
9d1e678
timeout pipe feature when connecting to self").
9d1e678
9d1e678
Change-Id: Id302ca13112fc409685e7665b38f1030704a0ccf
9d1e678
(cherry picked from commit 4ce2602befd59e69264d8e4ced8730b40c2b947c)
9d1e678
9d1e678
Conflicts:
9d1e678
	desktop/source/app/officeipcthread.cxx
9d1e678
	desktop/source/app/officeipcthread.hxx
9d1e678
(cherry picked from commit 6527b8a135c20e223a6fcf7c49835205a99ff02a)
9d1e678
---
9d1e678
 desktop/source/app/officeipcthread.cxx | 54 +++++++++++++++-------------------
9d1e678
 desktop/source/app/officeipcthread.hxx |  1 -
9d1e678
 2 files changed, 23 insertions(+), 32 deletions(-)
9d1e678
9d1e678
diff --git a/desktop/source/app/officeipcthread.cxx b/desktop/source/app/officeipcthread.cxx
9d1e678
index 452a3b5..1d37ee0 100644
9d1e678
--- a/desktop/source/app/officeipcthread.cxx
9d1e678
+++ b/desktop/source/app/officeipcthread.cxx
9d1e678
@@ -60,8 +60,6 @@ using ::rtl::OString;
9d1e678
 using ::rtl::OUString;
9d1e678
 using ::rtl::OUStringBuffer;
9d1e678
 
9d1e678
-const char  *OfficeIPCThread::sc_aTerminationSequence = "InternalIPC::TerminateThread";
9d1e678
-const int OfficeIPCThread::sc_nTSeqLength = 28;
9d1e678
 const char  *OfficeIPCThread::sc_aShowSequence = "-tofront";
9d1e678
 const int OfficeIPCThread::sc_nShSeqLength = 5;
9d1e678
 const char  *OfficeIPCThread::sc_aConfirmationSequence = "InternalIPC::ProcessingDone";
9d1e678
@@ -436,8 +434,6 @@ OfficeIPCThread::Status OfficeIPCThread::EnableOfficeIPCThread()
9d1e678
 
9d1e678
     rtl::Reference< OfficeIPCThread > pThread(new OfficeIPCThread);
9d1e678
 
9d1e678
-    pThread->maPipeIdent = OUString( "SingleOfficeIPC_"  );
9d1e678
-
9d1e678
     // The name of the named pipe is created with the hashcode of the user installation directory (without /user). We have to retrieve
9d1e678
     // this information from a unotools implementation.
9d1e678
     ::utl::Bootstrap::PathStatus aLocateResult = ::utl::Bootstrap::locateUserInstallation( aUserInstallPath );
9d1e678
@@ -494,19 +490,19 @@ OfficeIPCThread::Status OfficeIPCThread::EnableOfficeIPCThread()
9d1e678
     if ( aUserInstallPathHashCode.isEmpty() )
9d1e678
         return IPC_STATUS_BOOTSTRAP_ERROR; // Something completely broken, we cannot create a valid hash code!
9d1e678
 
9d1e678
-    pThread->maPipeIdent = pThread->maPipeIdent + aUserInstallPathHashCode;
9d1e678
+    OUString aPipeIdent( "SingleOfficeIPC_" + aUserInstallPathHashCode );
9d1e678
 
9d1e678
     PipeMode nPipeMode = PIPEMODE_DONTKNOW;
9d1e678
     do
9d1e678
     {
9d1e678
         osl::Security &rSecurity = Security::get();
9d1e678
         // Try to create pipe
9d1e678
-        if ( pThread->maPipe.create( pThread->maPipeIdent.getStr(), osl_Pipe_CREATE, rSecurity ))
9d1e678
+        if ( pThread->maPipe.create( aPipeIdent.getStr(), osl_Pipe_CREATE, rSecurity ))
9d1e678
         {
9d1e678
             // Pipe created
9d1e678
             nPipeMode = PIPEMODE_CREATED;
9d1e678
         }
9d1e678
-        else if( pThread->maPipe.create( pThread->maPipeIdent.getStr(), osl_Pipe_OPEN, rSecurity )) // Creation not successfull, now we try to connect
9d1e678
+        else if( pThread->maPipe.create( aPipeIdent.getStr(), osl_Pipe_OPEN, rSecurity )) // Creation not successfull, now we try to connect
9d1e678
         {
9d1e678
             osl::StreamPipe aStreamPipe(pThread->maPipe.getHandle());
9d1e678
             char pReceiveBuffer[sc_nCSASeqLength + 1];
9d1e678
@@ -610,18 +606,8 @@ void OfficeIPCThread::DisableOfficeIPCThread()
9d1e678
             pGlobalOfficeIPCThread);
9d1e678
         pGlobalOfficeIPCThread.clear();
9d1e678
 
9d1e678
-        // send thread a termination message
9d1e678
-        // this is done so the subsequent join will not hang
9d1e678
-        // because the thread hangs in accept of pipe
9d1e678
-        osl::StreamPipe aPipe ( pOfficeIPCThread->maPipeIdent, osl_Pipe_OPEN, Security::get() );
9d1e678
-        if (aPipe.is())
9d1e678
-        {
9d1e678
-            aPipe.send( sc_aTerminationSequence, sc_nTSeqLength+1 ); // also send 0-byte
9d1e678
-
9d1e678
-            // close the pipe so that the streampipe on the other
9d1e678
-            // side produces EOF
9d1e678
-            aPipe.close();
9d1e678
-        }
9d1e678
+        pOfficeIPCThread->mbDowning = true;
9d1e678
+        pOfficeIPCThread->maPipe.close();
9d1e678
 
9d1e678
         // release mutex to avoid deadlocks
9d1e678
         aMutex.clear();
9d1e678
@@ -686,22 +672,23 @@ void OfficeIPCThread::execute()
9d1e678
             // down during wait
9d1e678
             osl::ClearableMutexGuard aGuard( GetMutex() );
9d1e678
 
9d1e678
-            if (!mbDowning)
9d1e678
+            if ( mbDowning )
9d1e678
             {
9d1e678
-                // notify client we're ready to process its args
9d1e678
-                int nBytes = 0;
9d1e678
-                int nResult = 0;
9d1e678
-                while (
9d1e678
-                    (nResult = maStreamPipe.send(sc_aSendArgumentsSequence+nBytes, sc_nCSASeqLength-nBytes))>0 &&
9d1e678
-                    ((nBytes += nResult) < sc_nCSASeqLength) ) ;
9d1e678
+                break;
9d1e678
             }
9d1e678
+
9d1e678
+            // notify client we're ready to process its args
9d1e678
+            int nBytes = 0;
9d1e678
+            int nResult;
9d1e678
+            while (
9d1e678
+                (nResult = maStreamPipe.send(sc_aSendArgumentsSequence+nBytes, sc_nCSASeqLength-nBytes))>0 &&
9d1e678
+                ((nBytes += nResult) < sc_nCSASeqLength) ) ;
9d1e678
             maStreamPipe.write("\0", 1);
9d1e678
 
9d1e678
             // test byte by byte
9d1e678
             const int nBufSz = 2048;
9d1e678
             char pBuf[nBufSz];
9d1e678
-            int nBytes = 0;
9d1e678
-            int nResult = 0;
9d1e678
+            nBytes = 0;
9d1e678
             rtl::OStringBuffer aBuf;
9d1e678
             // read into pBuf until '\0' is read or read-error
9d1e678
             while ((nResult=maStreamPipe.recv( pBuf+nBytes, nBufSz-nBytes))>0) {
9d1e678
@@ -719,9 +706,6 @@ void OfficeIPCThread::execute()
9d1e678
             if (aArguments.isEmpty())
9d1e678
                 continue;
9d1e678
 
9d1e678
-            // is this a termination message ? if so, terminate
9d1e678
-            if (aArguments.equalsL(sc_aTerminationSequence, sc_nTSeqLength) || mbDowning)
9d1e678
-                return;
9d1e678
             std::auto_ptr< CommandLineArgs > aCmdLineArgs;
9d1e678
             try
9d1e678
             {
9d1e678
@@ -938,6 +922,14 @@ void OfficeIPCThread::execute()
9d1e678
         }
9d1e678
         else
9d1e678
         {
9d1e678
+            {
9d1e678
+                osl::MutexGuard aGuard( GetMutex() );
9d1e678
+                if ( mbDowning )
9d1e678
+                {
9d1e678
+                    break;
9d1e678
+                }
9d1e678
+            }
9d1e678
+
9d1e678
 #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
9d1e678
             fprintf( stderr, "Error on accept: %d\n", (int)nError );
9d1e678
 #endif
9d1e678
diff --git a/desktop/source/app/officeipcthread.hxx b/desktop/source/app/officeipcthread.hxx
9d1e678
index ba40b57..09e56da 100644
9d1e678
--- a/desktop/source/app/officeipcthread.hxx
9d1e678
+++ b/desktop/source/app/officeipcthread.hxx
9d1e678
@@ -82,7 +82,6 @@ class OfficeIPCThread : public salhelper::Thread
9d1e678
 
9d1e678
     osl::Pipe                   maPipe;
9d1e678
     osl::StreamPipe             maStreamPipe;
9d1e678
-    rtl::OUString               maPipeIdent;
9d1e678
     bool                        mbDowning;
9d1e678
     bool                        mbRequestsEnabled;
9d1e678
     int                         mnPendingRequests;
9d1e678
-- 
9d1e678
1.7.11.7
9d1e678