summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2018-02-01 13:52:00 +0100
committerMichael Stahl <mstahl@redhat.com>2018-02-01 20:11:37 +0100
commit5357ca82846ea7147ad61e9340f25647a5934eb0 (patch)
tree1071df72bc57f3b8d5b95a0ebc28bc8d7915f5fc
parentef3d1bf9e35d4753c52883137e07236ce8617f2f (diff)
tdf#114815 pyuno: avoid 2 threads initing python in parallel
According to the crash reports, it's possible for the grammar checking thread to call GetGrammarChecker, instantiating lightproof, at the same time as the main thread instantiates LngSvcMgr, which also instantiates (some?) (all?) grammar checkers. Ensure that pyuno_loader::CreateInstance() initialises Python only once with a C++11 thread safe static. Change-Id: I5b1faba9107355c508831a078366e4a29fdbfadf
-rw-r--r--pyuno/source/loader/pyuno_loader.cxx20
1 files changed, 16 insertions, 4 deletions
diff --git a/pyuno/source/loader/pyuno_loader.cxx b/pyuno/source/loader/pyuno_loader.cxx
index 559dc64d1d99..31b4f8f494f9 100644
--- a/pyuno/source/loader/pyuno_loader.cxx
+++ b/pyuno/source/loader/pyuno_loader.cxx
@@ -176,11 +176,10 @@ static void prependPythonPath( const OUString & pythonPathBootstrap )
osl_setEnvironment(envVar.pData, envValue.pData);
}
-Reference< XInterface > CreateInstance( const Reference< XComponentContext > & ctx )
+struct PythonInit
{
- Reference< XInterface > ret;
-
- if( ! Py_IsInitialized() )
+PythonInit() {
+ if (! Py_IsInitialized()) // may be inited by getComponentContext() already
{
OUString pythonPath;
OUString pythonHome;
@@ -236,9 +235,22 @@ Reference< XInterface > CreateInstance( const Reference< XComponentContext > & c
// PyThreadAttach below.
PyThreadState_Delete(tstate);
}
+}
+};
+
+Reference<XInterface> CreateInstance(const Reference<XComponentContext> & ctx)
+{
+ // tdf#114815 thread-safe static to init python only once
+ static PythonInit s_Init;
+
+ Reference< XInterface > ret;
PyThreadAttach attach( PyInterpreterState_Head() );
{
+ // note: this can't race against getComponentContext() because
+ // either (in soffice.bin) CreateInstance() must be called before
+ // getComponentContext() can be called, or (in python.bin) the other
+ // way around
if( ! Runtime::isInitialized() )
{
Runtime::initialize( ctx );