21#include <osl/thread.hxx>
22#include <osl/conditn.hxx>
23#include <osl/mutex.hxx>
24#include <osl/diagnose.h>
47 uno_EnvCallee * m_pCallee;
50 osl::Mutex m_innerMutex;
51 oslThreadIdentifier m_innerThreadId;
52 std::unique_ptr<InnerThread> m_pInnerThread;
53 osl::Condition m_innerCondition;
54 sal_Int32 m_enterCount;
56 osl::Mutex m_outerMutex;
57 oslThreadIdentifier m_outerThreadId;
58 osl::Condition m_outerCondition;
59 std::unique_ptr<OuterThread> m_pOuterThread;
61 explicit AffineBridge();
62 virtual ~AffineBridge()
override;
64 virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
override;
65 virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam)
override;
67 virtual void v_enter()
override;
68 virtual void v_leave()
override;
70 virtual bool v_isValid(OUString * pReason)
override;
73 void outerDispatch(
bool loop);
76class InnerThread :
public osl::Thread
78 virtual void SAL_CALL
run()
override;
80 AffineBridge * m_pAffineBridge;
83 explicit InnerThread(AffineBridge * threadEnvironment)
84 : m_pAffineBridge(threadEnvironment)
92void InnerThread::run()
94 osl_setThreadName(
"UNO AffineBridge InnerThread");
96 m_pAffineBridge->enter();
97 m_pAffineBridge->innerDispatch();
98 m_pAffineBridge->leave();
103class OuterThread :
public osl::Thread
105 virtual void SAL_CALL
run()
override;
107 AffineBridge * m_pAffineBridge;
110 explicit OuterThread(AffineBridge * threadEnvironment);
115OuterThread::OuterThread(AffineBridge * threadEnvironment)
116 : m_pAffineBridge(threadEnvironment)
121void OuterThread::run()
123 osl_setThreadName(
"UNO AffineBridge OuterThread");
125 osl::MutexGuard guard(m_pAffineBridge->m_outerMutex);
128 m_pAffineBridge->outerDispatch(
false);
129 m_pAffineBridge->m_outerThreadId = 0;
131 m_pAffineBridge->m_pOuterThread =
nullptr;
132 m_pAffineBridge =
nullptr;
136AffineBridge::AffineBridge()
137 : m_message (CB_DONE),
144 SAL_INFO(
"cppu.affinebridge",
"LIFE: AffineBridge::AffineBridge(uno_Environment * pEnv) -> " <<
this);
147AffineBridge::~AffineBridge()
149 SAL_INFO(
"cppu.affinebridge",
"LIFE: AffineBridge::~AffineBridge() -> " <<
this);
151 if (m_pInnerThread && osl::Thread::getCurrentIdentifier() != m_innerThreadId)
154 m_innerCondition.set();
156 m_pInnerThread->join();
159 m_pInnerThread.reset();
163 m_pOuterThread->join();
168void AffineBridge::outerDispatch(
bool loop)
170 OSL_ASSERT(m_outerThreadId == osl::Thread::getCurrentIdentifier());
171 OSL_ASSERT(m_innerThreadId != m_outerThreadId);
182 m_outerCondition.wait();
183 m_outerCondition.reset();
197 m_innerCondition.set();
204 while(mm != CB_DONE && loop);
207void AffineBridge::innerDispatch()
209 OSL_ASSERT(m_innerThreadId == osl::Thread::getCurrentIdentifier());
210 OSL_ASSERT(m_innerThreadId != m_outerThreadId);
216 m_innerCondition.wait();
217 m_innerCondition.reset();
231 m_outerCondition.set();
238 while(mm != CB_DONE);
241void AffineBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
243 osl::MutexGuard guard(m_outerMutex);
245 if (m_innerThreadId == 0)
247 m_pInnerThread.reset(
new InnerThread(
this));
250 bool bResetId =
false;
251 if (!m_outerThreadId)
253 m_outerThreadId = osl::Thread::getCurrentIdentifier();
257 m_message = CB_FPOINTER;
260 m_innerCondition.set();
268void AffineBridge::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam)
270 OSL_ASSERT(m_innerThreadId);
272 osl::MutexGuard guard(m_innerMutex);
274 if (m_outerThreadId == 0)
276 osl::MutexGuard guard_m_outerMutex(m_outerMutex);
278 if (m_outerThreadId == 0)
282 m_pOuterThread->join();
285 m_pOuterThread.reset(
new OuterThread(
this));
289 m_message = CB_FPOINTER;
292 m_outerCondition.set();
297void AffineBridge::v_enter()
299 m_innerMutex.acquire();
302 m_innerThreadId = osl::Thread::getCurrentIdentifier();
304 OSL_ASSERT(m_innerThreadId == osl::Thread::getCurrentIdentifier());
309void AffineBridge::v_leave()
311 OSL_ASSERT(m_innerThreadId == osl::Thread::getCurrentIdentifier());
317 m_innerMutex.release();
320bool AffineBridge::v_isValid(OUString * pReason)
322 bool result = m_enterCount > 0;
324 *pReason =
"not entered";
328 result = m_innerThreadId == osl::Thread::getCurrentIdentifier();
331 *pReason =
"wrong thread";
340#ifdef DISABLE_DYNLOADING
342#define uno_initEnvironment affine_uno_uno_initEnvironment
343#define uno_ext_getMapping affine_uno_uno_ext_getMapping
void SAL_DLLPUBLIC_EXPORT uno_ext_getMapping(uno_Mapping **ppMapping, uno_Environment *pFrom, uno_Environment *pTo)
void SAL_DLLPUBLIC_EXPORT uno_initEnvironment(uno_Environment *pEnv) SAL_THROW_EXTERN_C()
C++ wrapper for binary C Enterable (http://wiki.openoffice.org/wiki/Uno/Cpp/Spec/Environment_Stack)
virtual bool v_isValid(rtl::OUString *pReason)=0
virtual void v_callOut_v(uno_EnvCallee *pCallee, va_list *pParam)=0
virtual void v_callInto_v(uno_EnvCallee *pCallee, va_list *pParam)=0
struct _uno_Environment uno_Environment
#define SAL_INFO(area, stream)
struct _uno_Mapping uno_Mapping
def run(arg=None, arg2=-1)
void Environment_initWithEnterable(uno_Environment *pEnvironment, cppu::Enterable *pEnterable)
C++ helper for implementing Purpose Environments.
void createMapping(uno_Mapping **ppMapping, uno_Environment *pFrom, uno_Environment *pTo, ProbeFun *probeFun, void *pContext)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString getIdentifier(css::uno::Reference< css::deployment::XPackage > const &package)
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
#define SAL_THROW_EXTERN_C()