summaryrefslogtreecommitdiff
path: root/vcl/headless
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2016-04-20 13:13:16 +0300
committerTor Lillqvist <tml@collabora.com>2016-04-22 18:09:02 +0300
commitdbced8e8584b631524dacf607f752ebb734901db (patch)
tree7d2a2c493a973bdb39bf23107a73d45b26604e14 /vcl/headless
parentdb18de5868454ed5c242d54e483ea8f403a80601 (diff)
Don't share the wakeup pipe with child processes
Create a new pipe in the child process. In a normal desktop LibreOffice each fork() will be followed quickly by an exec(), so the FD_CLOEXEC would be enough for that. In LibreOfficeKit-based software that uses the preinit mechanism, though, the intent is that one can fork child processes without exec(). This solution uses pthread_atfork(). Another way would be to add suitable public API callable from the LibreOfficeKit client initialisation code in desktop/source/lib/init.cxx to explicitly close and reopen the wakeup pipe in the default SvpSalInstance. Change-Id: I03fad4ce4adf14c16cb0f537b3baab58fba38922 Reviewed-on: https://gerrit.libreoffice.org/24256 Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Tested-by: Michael Meeks <michael.meeks@collabora.com>
Diffstat (limited to 'vcl/headless')
-rw-r--r--vcl/headless/svpinst.cxx57
1 files changed, 44 insertions, 13 deletions
diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx
index 0c71f6330376..65c25f12a075 100644
--- a/vcl/headless/svpinst.cxx
+++ b/vcl/headless/svpinst.cxx
@@ -19,6 +19,7 @@
#include <unistd.h>
#include <fcntl.h>
+#include <pthread.h>
#include <sys/time.h>
#include <sys/poll.h>
@@ -59,6 +60,15 @@ bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
SvpSalInstance* SvpSalInstance::s_pDefaultInstance = nullptr;
+static void atfork_child()
+{
+ if (SvpSalInstance::s_pDefaultInstance != nullptr)
+ {
+ SvpSalInstance::s_pDefaultInstance->CloseWakeupPipe();
+ SvpSalInstance::s_pDefaultInstance->CreateWakeupPipe();
+ }
+}
+
SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
SalGenericInstance( pMutex )
{
@@ -67,8 +77,41 @@ SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
m_nTimeoutMS = 0;
m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
- if (pipe (m_pTimeoutFDS) != -1)
+ CreateWakeupPipe();
+ if( s_pDefaultInstance == nullptr )
+ s_pDefaultInstance = this;
+ pthread_atfork(NULL, NULL, atfork_child);
+}
+
+SvpSalInstance::~SvpSalInstance()
+{
+ if( s_pDefaultInstance == this )
+ s_pDefaultInstance = NULL;
+
+ CloseWakeupPipe();
+}
+
+void SvpSalInstance::CloseWakeupPipe()
+{
+ if (m_pTimeoutFDS[0] != -1)
{
+ 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()
+{
+ if (pipe (m_pTimeoutFDS) == -1)
+ {
+ 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] << "]");
+
// initialize 'wakeup' pipe.
int flags;
@@ -96,18 +139,6 @@ SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
(void)fcntl(m_pTimeoutFDS[1], F_SETFL, flags);
}
}
- if( s_pDefaultInstance == nullptr )
- s_pDefaultInstance = this;
-}
-
-SvpSalInstance::~SvpSalInstance()
-{
- if( s_pDefaultInstance == this )
- s_pDefaultInstance = nullptr;
-
- // close 'wakeup' pipe.
- close (m_pTimeoutFDS[0]);
- close (m_pTimeoutFDS[1]);
}
void SvpSalInstance::PostEvent(const SalFrame* pFrame, ImplSVEvent* pData, sal_uInt16 nEvent)