diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-05-10 09:47:04 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-05-10 10:05:02 +0200 |
commit | 021bba1b9d9d0e483a76607aaafaf7eb81ff6bed (patch) | |
tree | fb6f2b5cfbecb8b1cb7aaff9a4a4850c77df223c /vcl/headless/svpinst.cxx | |
parent | 77171fc384b3c6359cdae026a0c38f2f112c9d60 (diff) |
Avoid non--async-signal-safe functions in child after fork
Posix requires that a process forked from a multi-threaded process only calls
async-signal-safe functions between fork and exec. This has been observed to
cause trouble at least in an ASan build, where a forked sub-process (that wants
to proceed to exec java from getJavaProps,
jvmfwk/plugins/sunmajor/pluginlib/util.cxx) hangs in
__sanitizer::BlockingMutex::Lock from within ASan's operator new replacement,
from within the SAL_INFO in SvpSalInstance::CloseWakeupPipe, from within the
atfork_child handler established with pthread_atfork. The rest of the calls in
SvpSalInstance::Create-/CloseWakupPipe appear to be async-signal-safe.
This pthread_atfork handler got introduced with
dbced8e8584b631524dacf607f752ebb734901db "Don't share the wakeup pipe with child
processes". It is irrelevant when the child process will proceed to call exec.
And if the child process does not proceed to call exec (which is the intented
use case why it got added), the above-mentioned Posix requirement makes it look
unlikely that the child will operate properly (i.e., not call any async-signal-
safe functions), unless the parent process was single-threaded.
Change-Id: I9ecaf98597b396e0db83fe98fb11a7df7686e1d6
Diffstat (limited to 'vcl/headless/svpinst.cxx')
-rw-r--r-- | vcl/headless/svpinst.cxx | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx index 5cbcf4a98fde..0305ceeebe01 100644 --- a/vcl/headless/svpinst.cxx +++ b/vcl/headless/svpinst.cxx @@ -67,8 +67,8 @@ static void atfork_child() { if (SvpSalInstance::s_pDefaultInstance != nullptr) { - SvpSalInstance::s_pDefaultInstance->CloseWakeupPipe(); - SvpSalInstance::s_pDefaultInstance->CreateWakeupPipe(); + SvpSalInstance::s_pDefaultInstance->CloseWakeupPipe(false); + SvpSalInstance::s_pDefaultInstance->CreateWakeupPipe(false); } } @@ -82,7 +82,7 @@ SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) : m_nTimeoutMS = 0; m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1; - CreateWakeupPipe(); + CreateWakeupPipe(true); if( s_pDefaultInstance == nullptr ) s_pDefaultInstance = this; #ifndef ANDROID @@ -95,29 +95,38 @@ SvpSalInstance::~SvpSalInstance() if( s_pDefaultInstance == this ) s_pDefaultInstance = nullptr; - CloseWakeupPipe(); + CloseWakeupPipe(true); } -void SvpSalInstance::CloseWakeupPipe() +void SvpSalInstance::CloseWakeupPipe(bool log) { if (m_pTimeoutFDS[0] != -1) { - SAL_INFO("vcl.headless", "CloseWakeupPipe: Closing inherited wakeup pipe: [" << m_pTimeoutFDS[0] << "," << m_pTimeoutFDS[1] << "]"); + if (log) + { + SAL_INFO("vcl.headless", "CloseWakeupPipe: Closing inherited wakeup pipe: [" << m_pTimeoutFDS[0] << "," << m_pTimeoutFDS[1] << "]"); + } close (m_pTimeoutFDS[0]); close (m_pTimeoutFDS[1]); m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1; } } -void SvpSalInstance::CreateWakeupPipe() +void SvpSalInstance::CreateWakeupPipe(bool log) { if (pipe (m_pTimeoutFDS) == -1) { - SAL_WARN("vcl.headless", "Could not create wakeup pipe: " << strerror(errno)); + if (log) + { + SAL_WARN("vcl.headless", "Could not create wakeup pipe: " << strerror(errno)); + } } else { - SAL_INFO("vcl.headless", "CreateWakeupPipe: Created wakeup pipe: [" << m_pTimeoutFDS[0] << "," << m_pTimeoutFDS[1] << "]"); + if (log) + { + SAL_INFO("vcl.headless", "CreateWakeupPipe: Created wakeup pipe: [" << m_pTimeoutFDS[0] << "," << m_pTimeoutFDS[1] << "]"); + } // initialize 'wakeup' pipe. int flags; |