diff options
author | Michael Stahl <mstahl@redhat.com> | 2013-10-02 23:20:25 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2013-10-02 23:52:32 +0200 |
commit | cf88ebc1f7d358a1dcd9e5b49026194e05916896 (patch) | |
tree | f2cfc6e9ab3e881627b7bee7f82206426bb4aa36 | |
parent | 970448ef96c8be8b282f91dc235cab518d941549 (diff) |
vcl: avoid deadlock in X11 SelectionManager::shutdown()
It is evidently possible that SelectionManager::run() exits while
shutdown() is still trying to write to its end of the pipe, so close the
pipe when run() exits to avoid that.
(regression from ec5a7256ca549d358b9c5380194ea2d1b991a73e)
Change-Id: Ibc2823c61ea5df5b5227676c6e37ae5de44cde6b
-rw-r--r-- | vcl/unx/generic/dtrans/X11_selection.cxx | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/vcl/unx/generic/dtrans/X11_selection.cxx b/vcl/unx/generic/dtrans/X11_selection.cxx index 7a36159ebec2..2cdf21d81742 100644 --- a/vcl/unx/generic/dtrans/X11_selection.cxx +++ b/vcl/unx/generic/dtrans/X11_selection.cxx @@ -3782,6 +3782,10 @@ void SelectionManager::run( void* pThis ) aLast = aNow; } } + // close write end on exit so write() fails and other thread does not block + // forever + close(This->m_EndThreadPipe[1]); + close(This->m_EndThreadPipe[0]); #if OSL_DEBUG_LEVEL > 1 fprintf(stderr, "SelectionManager::run end\n" ); #endif @@ -3827,16 +3831,16 @@ void SelectionManager::shutdown() throw() aGuard.clear(); while (osl_isThreadRunning(m_aThread)) { - SolarMutexGuard guard2; - Application::Reschedule(); + { // drop mutex before write - otherwise may deadlock + SolarMutexGuard guard2; + Application::Reschedule(); + } // trigger poll()'s wait end by writing a dummy value int dummy=0; dummy = write(m_EndThreadPipe[1], &dummy, 1); } osl_joinWithThread( m_aThread ); osl_destroyThread( m_aThread ); - close(m_EndThreadPipe[0]); - close(m_EndThreadPipe[1]); m_aThread = NULL; aGuard.reset(); } |