Difference between revisions of "Uno/Article/Multi-Thread Programming"

From Apache OpenOffice Wiki
< Uno
Jump to: navigation, search
(Thread-Free: Moved purpose reference note: to Environments&Mappings.)
(Rework in progress.)
Line 5: Line 5:
 
[[Uno]] is inherently multi threaded. Every instance of a [[Uno]] component (which is an object) may be accessed by multiple threads concurrently. The [[Uno/Spec/Threading Model|Uno threading framework]] provides support for simplifying multi-thread programming.
 
[[Uno]] is inherently multi threaded. Every instance of a [[Uno]] component (which is an object) may be accessed by multiple threads concurrently. The [[Uno/Spec/Threading Model|Uno threading framework]] provides support for simplifying multi-thread programming.
  
 +
===Environments===
 
Every [[Uno]] reference points to an object with particular characteristics. Among implementing a concrete interface, the object may belong to one or multiple [[Uno/Spec/Purpose Environment|purpose environment]]s. The [[Uno/Spec/Threading Model|Uno threading model]] provides [[Uno/Spec/Thread Affinity Bridge|thread-affine purpose environments]] and [[Uno/Spec/Thread Unsafety Bridge|thread-unsafe purpose environments]]. Objects not belonging to one of these two [[Uno/Spec/Purpose Environment|purpose environments]] are assumed to be [[Uno/Term/Thread Safe|thread-safe]].  
 
Every [[Uno]] reference points to an object with particular characteristics. Among implementing a concrete interface, the object may belong to one or multiple [[Uno/Spec/Purpose Environment|purpose environment]]s. The [[Uno/Spec/Threading Model|Uno threading model]] provides [[Uno/Spec/Thread Affinity Bridge|thread-affine purpose environments]] and [[Uno/Spec/Thread Unsafety Bridge|thread-unsafe purpose environments]]. Objects not belonging to one of these two [[Uno/Spec/Purpose Environment|purpose environments]] are assumed to be [[Uno/Term/Thread Safe|thread-safe]].  
 
===Implementing Objects===
 
Going to implement an UNO object, you need to decide on the threading architecture. You basically have the following choices, the object can either be
 
* [[Uno/Term/Thread Unsafe|thread-unsafe]], or
 
* [[Uno/Term/Thread Safe|thread-safe]], or
 
* [[Uno/Term/Thread Affine|thread-affine]], or
 
* [[Uno/Term/Thread Free|thread-free]].
 
  
 
====Thread-Unsafe====
 
====Thread-Unsafe====
[[Uno/Term/Thread Unsafe|Thread unsafe]] is the choice for most cases. Actually leaving proper synchronization of method calls to the [[Uno/Spec/Runtime|runtime]].  
+
Any environment with an ":unsafe" in its description is a thread-unsafe environment. Objects managed by such an environment may not be called by concurrent threads. See the specification of the [[Uno/Spec/Thread Unsafety Bridge|thread-unsafety bridge]] for details.
  
====Thread-Safe====
+
The semantics of the "entering" or "invoking" a thread-unsafe environment are same.  
There are only rare cases where you actually want to implement your object [[Uno/Term/Thread Safe|thread safe]]. Either
+
* your object should or must allow the parallel execution of some of its methods, or
+
* your object wants to avoid the overhead associated with leaving synchronization to the [[Uno/Spec/Runtime|runtime]].
+
  
One case, where your component must allow the parallel execution of methods is, when you want to be able to abort a running invocation. UNO currently does not offer a mechanism to do this generically, so that particular objects must provide dedicated methods for abortion. An example for this is the [http://util.openoffice.org/source/browse/util/io/source/acceptor/ util/io/Acceptor] implementation.
+
; C++ Example:
 
+
<pre>
The overhead for automatic synchronization only affects inter-environment calls. The threading architecture of a particular application should be designed in a way, that closely connected objects happen to exist in the same [[Uno/Spec/Environment|environment]]. Basically ensuring a low inter-environment call frequency, converting the potential advantage of self synchronized methods to the reverse.
+
  cppu::EnvGuard unsafeGuard(Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gcc3:unsafe"))));
 
+
  // now we can safely call any object belonging to this environment ...
'''Note:''' Scalability may be achieved by the introduction of [[Uno/Spec/Named Environment|named environments]], actually allowing any number of [[Uno/Term/Thread Unsafe|thread-unsafe]] [[Uno/Spec/Purpose Environment|purpose environments]] to exist simultanesously and to be entered by multiple threads in parallel.
+
  // no second thread may enter this environment in paralell
 +
</pre>
  
 
====Thread-Affine====
 
====Thread-Affine====
[[Uno/Term/Thread Affine|Thread-affine]] objects are rare. In OOo they are needed to encapsulate the Win32 respectively the OLE/COM thread affinity.
+
Any environment with a ":affine" in its description is a thread-affine environment. Objects managed by such an environment may not be called by concurrent threads. See the of the [[Uno/Spec/Thread Affinity Bridge|thread-affinity bridge]] for details.
  
====Thread-Free====
+
Actually, the semantics of "entering" or "invoking" a thread-affine environment differ. Entering a thread-affine environment associates the current thread with this particular environment. All invocations of objects of this thread-affine environment get dispatched into this thread.
[[Uno/Term/Thread Free|Thread-free]] objects may be used in any threading environment. While doing so, they certainly need to respect particular environment related constraints.
+
An implementation being able to deal with one of [[Uno/Term/Thread Unsafe|thread-unsafe]], [[Uno/Term/Thread Safe|thread-safe]] or [[Uno/Term/Thread Affine|thread-affine]] objects only, is [[Uno/Term/Thread Specialized|thread-specialized]] on this particular threading model, while a [[Uno/Term/Thread Free|thread-free]] implementation is able to deal with any threading model. In essence, a [[Uno/Term/Thread Free|thread-free]] object appears thread agnostic to the outside (i.e. can be utilized in any of the three environment types, without the cost of environment entry/exit), but needs in fact to distinguish between the client environments internally.
+
  
'''Note:''' The [[Uno]] [[Uno/Spec/Runtime|runtime]] provides APIs for implementing any whished scenario. Including objects shared between different [[Uno/Spec/Purpose Environment|purpose environments]] or the instantiation of a [[Uno/Term/Thread Safe|thread-safe]] component in a [[Uno/Term/Thread Unsafe|thread-unsafe]] [[Uno/Spec/Environment|environment]]. These mechanisms are in place to implement the [[Uno/Spec/Threading Model|threading framework]] itself, and to allow the programmer to gain full control, if needed.
+
; C++ Example: In this example, the newly created instance of "MyUnoObject" is guaranteed to only be called by exactly this thread. When trying to leave the thread-affine environment, the call will block as long as objects are managed by this environment, basically ensuring that the objects are still reachable.
 +
<pre>
 +
  class MyUnoObject ...;
  
====Capabilities====
+
  ...
Code may actually vary in its capabilities regarding '[[Uno/Term/Transparent Concurrency|transparent concurrency]]'. Code may be differentiated into code using
+
  cppu::EnvGuard affineGuard(Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gcc3:affine"))));
* global variables, or
+
 
* thread local variables, or
+
  smgr->createInstanceWithArguments(new MyUnoObject());
* parameters only ("pure"), or
+
  ...
* value parameters only, or
+
* doing internal protection of critical sections, or
+
* not doing internal protection.
+
Such categorizations help to decide, what one can do with a particular implemention. Also the codes threading type is a compile time information and may therefor be used during compilation, so that the compiler may give errors when mixing [[Uno/Term/Thread Safe|thread-safe]] and [[Uno/Term/Thread Unsafe|thread-unsafe]] code in a multi-thread scenario.
+
 
+
===Implementation Types===
+
Depending on the type of the planned implementation, which either is a
+
* component, or a
+
* library, or an
+
* application,
+
care of the "purpose" characteristic of the involved objects needs to be taken.
+
 
+
'''Note:''' It is planned, to support the selection of an [[Uno/Spec/Implementation Environment|implementation environment]] (determining the implementations [[Uno/Spec/Purpose Environment|purpose environment]]) at compile time, e.g. for 'C' like languages by a macro or an include. Some experiments have been done, so no final decisions have been made yet.
+
 
+
====Components====
+
Components do provide their implementation environment. If a component should be implemented [[Uno/Term/Thread Unsafe|thread-unsafe]], this needs to be reflected in the target environment.
+
 
+
=====C++=====
+
[[Uno/Term/Thread Specialized|Thread-specialized]] components directly return their ABI plus their thread related specialisation. The implementation of the <code>component_getImplementationEnvironment</code> function for a [[Uno/Term/Thread Unsafe|thread-unsafe]] component needs to reflect this unsafeness by providing it together with the ABI, e.g.:
+
<pre>
+
extern "C" void SAL_CALL component_getImplementationEnvironment(sal_Char        const ** ppEnvTypeName,
+
uno_Environment      ** ppEnv)
+
{
+
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ":unsafe";
+
}
+
 
</pre>
 
</pre>
  
A [[Uno/Term/Thread Free|thread-free]] component providing objects for all thread related environments needs to implement the <code>component_getImplementationEnvironmentExt</code> function, e.g.:
+
; C++ Example:  
 
<pre>
 
<pre>
extern "C" void SAL_CALL component_getImplementationEnvironmentExt(sal_Char        const ** ppEnvTypeName,
+
   class MyUnoObject ...;
                                                          uno_Environment      ** ppEnv,
+
                                                          sal_Char        const  * pImplName,
+
                                                                  uno_Environment        * pSrcEnv
+
)
+
{
+
   rtl::OUString envName(RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING));
+
  envName += cppu::EnvDcp_getPurpose(Environment(pSrcEnv).getTypeName();
+
  
   uno_getEnvironment(ppEnv, envName.pData, NULL);
+
   ...
}
+
  uno::Environment affineEnv(Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gcc3:affine"))));
 +
 
 +
  smgr->createInstanceWithArguments(new MyUnoObject());
 +
  ...
 
</pre>
 
</pre>
Implementing this function, the component may very well select the threading environments depending on the provided implementation names.
 
  
====Libraries====
+
====Thread-Safe====
Libraries can not rely on the [[Uno/Spec/Runtime|runtime]] to handle thread (respectively purpose) related mapping. Libraries need to care of thread related environments by their own. As well as components or applications, libraries may be implemented [[Uno/Term/Thread Specialized|thread-specialized]] or [[Uno/Term/Thread Free|thread-free]]. Depending on the capabilities of the particular programming language and language binding, correct specialization may be ensured during compilation time, e.g. by dedicated reference types.
+
  
=====C++=====
+
===Objects===
The current C++ UNO language binding only supports free (<code>cppu::FreeReference</code>) and classic (<code>com::sun::star::uno::Reference</code>) references. The API of [[Uno/Term/Thread Free|thread-free]] libraries should reflect the "freeness" by using the <code>cppu::FreeReference</code> in its definition, e.g.:
+
Going to implement an UNO object, you need to decide on the threading architecture. You basically have the following choices, the object can either be
<pre>
+
* [[Uno/Term/Thread Unsafe|thread-unsafe]], or
// Declaration
+
* [[Uno/Term/Thread Safe|thread-safe]], or
cppu::FreeReference<XSingleServiceFactory> get_a_factory(void);
+
* [[Uno/Term/Thread Affine|thread-affine]].
</pre>
+
  
For compatibility reasons, classic UNO references (<code>com::sun::star::uno::Reference</code>) may be used, doing a runtime check for the thread type of the passed or requested objects, e.g.:
+
====Thread-Unsafe====
<pre>
+
[[Uno/Term/Thread Unsafe|Thread unsafe]] is the choice for most cases. Actually leaving proper synchronization of method calls to the [[Uno/Spec/Runtime|runtime]].  
static void creator(va_list param) {
+
cppu::FreeReference * prFactory = va_arg(param, cppu::FreeReference<XSingleServiceFactory> *);
+
  
    rFactory->set(new MyThreadUnsafeFactory());
+
====Thread-Safe====
}
+
There are only rare cases where you actually want to implement your object [[Uno/Term/Thread Safe|thread safe]]. Either
 +
* your object should or must allow the parallel execution of some of its methods, or
 +
* your object wants to avoid the overhead associated with leaving synchronization to the [[Uno/Spec/Runtime|runtime]].
  
// API Implementation
+
One case, where your component must allow the parallel execution of methods is, when you want to be able to abort a running invocation. UNO currently does not offer a mechanism to do this generically, so that particular objects must provide dedicated methods for abortion. An example for this is the [http://util.openoffice.org/source/browse/util/io/source/acceptor/ util/io/Acceptor] implementation.
uno::Reference<XSingleServiceFactory> get_a_factory(void)
+
{
+
  cppu::FreeReference<XSingleServiceFactory> rFactory(new MyThreadUnsafeFactory());
+
  
  uno::Environment(rtl::OUString(RTL_CONSTASCII_PARAM("uno:unsafe"))).invoke(creator, &rFactory);
+
The overhead for automatic synchronization only affects inter-environment calls. The threading architecture of a particular application should be designed in a way, that closely connected objects happen to exist in the same [[Uno/Spec/Environment|environment]]. Basically ensuring a low inter-environment call frequency, converting the potential advantage of self synchronized methods to the reverse.
  
  return rFactory;
+
'''Note:''' Scalability may be achieved by the introduction of [[Uno/Spec/Named Environment|named environments]], actually allowing any number of [[Uno/Term/Thread Unsafe|thread-unsafe]] [[Uno/Spec/Purpose Environment|purpose environments]] to exist simultanesously and to be entered by multiple threads in parallel.
}
+
</pre>
+
  
The [http://udk.openoffice.org/source/browse/udk/cppuhelper cppuhelper] library dynamically checks the current environment, and returns matching references, e.g. guaranteeing that [[Uno/Term/Thread Safe|thread-safe]] and [[Uno/Term/Thread Unsafe|thread-unsafe]] objects do not get mixed.
+
====Thread-Affine====
 
+
[[Uno/Term/Thread Affine|Thread-affine]] objects are rare. In OOo they are needed to encapsulate the Win32 respectively the OLE/COM thread affinity.
====Applications====
+
Applications are basically like libraries, except that no [[Uno]] objects are passed in, or are returned. Application code implemented other than in the [[Uno/Term/Thread Safe|thread-safe]] environment needs to explicitly enter the wished [[Uno/Spec/Purpose Environment|purpose environment]] respectively thread related [[Uno/Spec/Environment|environment]] before calling any particular [[Uno]] aware [[Uno/Term/Thread Specialized|thread specialized]] library. [[Uno]] aware libraries may than provide matching objects, depending on their threading architecture. By default, applications start in the [[Uno/Term/Thread Safe|thread-safe]] environment.
+
 
+
=====C++=====
+
An application implementing thread-unsafe objects to be passed to some [[Uno]] components may look like this:
+
<pre>
+
class MyThreadUnsafeObject : ... {
+
  ...
+
};
+
 
+
SAL_IMPLEMENT_MAIN()
+
{
+
  cppu::EnvGuard unsafeGuard(Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("uno:unsafe"))));
+
 
+
  // Get a thread unsafe component context.
+
  Reference< XComponentContext> xCtxt(cppu::defaultBootstrap_InitialComponentContext());
+
  ...
+
  xObject.set(new MyThreadUnsafeObject());
+
  ...
+
  return 0;
+
}
+
</pre>
+
 
+
'''Note:''' The planned introduction of [[Uno/Spec/Implementation Environment|implementation environments]] is going to be usable by the application programmer as well. It basically removes the necessity to explicitly enter a particular [[Uno/Spec/Purpose Environment|purpose environment]].
+
  
===Using Threads===
+
===Threads===
 
You may create threads in your implementation. Depending on the selected threading architecture, these threads may are allowed to be visible from the outside or not. If your implementation is to be instantiated in a
 
You may create threads in your implementation. Depending on the selected threading architecture, these threads may are allowed to be visible from the outside or not. If your implementation is to be instantiated in a
 
* [[Uno/Spec/Thread Unsafety Bridge|thread-unsafe environment]], than it must be [[Uno/Term/Thread Transparent|thread-transparent]], if it is to be used in a
 
* [[Uno/Spec/Thread Unsafety Bridge|thread-unsafe environment]], than it must be [[Uno/Term/Thread Transparent|thread-transparent]], if it is to be used in a
 
* [[Uno/Spec/Thread Affinity Bridge|thread-affine environment]], than is must be [[Uno/Term/Thread Transparent|thread-transparent]] as well, if it is to be used in a  
 
* [[Uno/Spec/Thread Affinity Bridge|thread-affine environment]], than is must be [[Uno/Term/Thread Transparent|thread-transparent]] as well, if it is to be used in a  
* [[Uno/Term/Thread Safe|thread-safe]] environment, it may create visible threads and be [[Uno/Term/Thread Aware|thread-aware]] as needed, if it is to be used in
+
* [[Uno/Term/Thread Safe|thread-safe]] environment, it may create visible threads and show any [[Uno/Term/Thread Aware|thread-awares]] as needed.
* any environment (being [[Uno/Term/Thread Free|thread-free]]), it may behave differently, depending on the managing environment.
+
 
Obviously, invisible threads can be used and created anytime anyway. Invisible threads do not harm [[Uno/Term/Thread Transparent|thread-transparency]] by definition.
 
Obviously, invisible threads can be used and created anytime anyway. Invisible threads do not harm [[Uno/Term/Thread Transparent|thread-transparency]] by definition.
  
Line 278: Line 208:
 
</pre>
 
</pre>
  
====The Thread Unsafe Environment====
 
 
====The Thread Affine Environment====
 
 
====The Thread Safe (or default) Environment====
 
  
===Relevant Specifications===
+
===Specifications===
 
The relevant specifications can be found here:
 
The relevant specifications can be found here:
 
* [[Uno/Spec/Threading Model]]
 
* [[Uno/Spec/Threading Model]]

Revision as of 15:01, 2 August 2006

Preface

The technologie described in this article depends on the presence of the Uno Threading Framework.

Multi-Thread Programming

Uno is inherently multi threaded. Every instance of a Uno component (which is an object) may be accessed by multiple threads concurrently. The Uno threading framework provides support for simplifying multi-thread programming.

Environments

Every Uno reference points to an object with particular characteristics. Among implementing a concrete interface, the object may belong to one or multiple purpose environments. The Uno threading model provides thread-affine purpose environments and thread-unsafe purpose environments. Objects not belonging to one of these two purpose environments are assumed to be thread-safe.

Thread-Unsafe

Any environment with an ":unsafe" in its description is a thread-unsafe environment. Objects managed by such an environment may not be called by concurrent threads. See the specification of the thread-unsafety bridge for details.

The semantics of the "entering" or "invoking" a thread-unsafe environment are same.

C++ Example
  cppu::EnvGuard unsafeGuard(Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gcc3:unsafe"))));
  // now we can safely call any object belonging to this environment ...
  // no second thread may enter this environment in paralell

Thread-Affine

Any environment with a ":affine" in its description is a thread-affine environment. Objects managed by such an environment may not be called by concurrent threads. See the of the thread-affinity bridge for details.

Actually, the semantics of "entering" or "invoking" a thread-affine environment differ. Entering a thread-affine environment associates the current thread with this particular environment. All invocations of objects of this thread-affine environment get dispatched into this thread.

C++ Example
In this example, the newly created instance of "MyUnoObject" is guaranteed to only be called by exactly this thread. When trying to leave the thread-affine environment, the call will block as long as objects are managed by this environment, basically ensuring that the objects are still reachable.
  class MyUnoObject ...;

  ...
  cppu::EnvGuard affineGuard(Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gcc3:affine"))));
  
  smgr->createInstanceWithArguments(new MyUnoObject());
  ...
C++ Example
  class MyUnoObject ...;

  ...
  uno::Environment affineEnv(Environment(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gcc3:affine"))));
  
  smgr->createInstanceWithArguments(new MyUnoObject());
  ...

Thread-Safe

Objects

Going to implement an UNO object, you need to decide on the threading architecture. You basically have the following choices, the object can either be

Thread-Unsafe

Thread unsafe is the choice for most cases. Actually leaving proper synchronization of method calls to the runtime.

Thread-Safe

There are only rare cases where you actually want to implement your object thread safe. Either

  • your object should or must allow the parallel execution of some of its methods, or
  • your object wants to avoid the overhead associated with leaving synchronization to the runtime.

One case, where your component must allow the parallel execution of methods is, when you want to be able to abort a running invocation. UNO currently does not offer a mechanism to do this generically, so that particular objects must provide dedicated methods for abortion. An example for this is the util/io/Acceptor implementation.

The overhead for automatic synchronization only affects inter-environment calls. The threading architecture of a particular application should be designed in a way, that closely connected objects happen to exist in the same environment. Basically ensuring a low inter-environment call frequency, converting the potential advantage of self synchronized methods to the reverse.

Note: Scalability may be achieved by the introduction of named environments, actually allowing any number of thread-unsafe purpose environments to exist simultanesously and to be entered by multiple threads in parallel.

Thread-Affine

Thread-affine objects are rare. In OOo they are needed to encapsulate the Win32 respectively the OLE/COM thread affinity.

Threads

You may create threads in your implementation. Depending on the selected threading architecture, these threads may are allowed to be visible from the outside or not. If your implementation is to be instantiated in a

Obviously, invisible threads can be used and created anytime anyway. Invisible threads do not harm thread-transparency by definition.

Unsafe / Affine Code

If you are writing thread-unsafe or thread-affine code, any created thread to run outside the current (thread-unsafe / -affine) environment. The objects, which should be used by this thread, need to be mapped to the threads environment, which typically will be the thread-safe environment.

Mapped objects need to be managed by the belonging enviroment only, as long as this environment has not been entered explicity, otherwise methods (e.g. release or acquire) of the objects may be called from the wrong environment.

C++

Do not enter the environment explicity, but only implicity when calling methods on mapped objects (assuming the objects have been implemented in the target environment).

Use the shield helper:

class MyThread : public Thread 
{
  uno::Reference<XInterface> m_xInterface;

public:
  MyThread(uno::Reference<XInterface> const & xInterface)
    : m_xInterface(uno::shield(xInterface), SAL_NO_ACQUIRE)
  {
  }
};

Do the mapping by hand:

class MyThread : public Thread 
{
  uno::Reference<XInterface> m_xInterface;

public:
  MyThread(uno::Reference<XInterface> const & xInterface);
};

MyThread::MyThread(uno::Reference<XInterface> const & xInterface)
{
  uno::Mapping unsafe2safe(uno::getCurrentEnvironment(), 
                           rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))));
		
  m_xInterface.set(unsafe2safe.mapInterface(pT, getCppuType(m_xInterface)), 
		   SAL_NO_ACQUIRE);
}

Just enter the environment add do all calls while being in it. Obviously, releasing the objects also needs to be done in the environment.

class MyThread : public Thread 
{
  uno::Environment           m_refEnv;
  uno::Reference<XInterface> m_xInterface;

  void i_doSomething();

public:
  MyThread(uno::Reference<XInterface> const & xInterface);

  void doSomething();
};

MyThread::MyThread(uno::Reference<XInterface> const & xInterface)
 : m_xInterface(xInterface), m_refEnv(uno::getCurrentEnvironment());
{
}

void MyThread::doSomething()
{
  // do not do any slow/blocking operations here, as the target environment is
  // currently entered, and no other thread may enter at the moment...
  m_xInterface->...
}

static void s_doSomething(va_list param)
{
  MyThread * pMyThread = va_arg(param, MyThread *);
  pMyThread->i_doSomething();
}

void MyThread::doSomething()
{
  m_refEnv.invoke(s_doSomething, this);
}

MyThread::~MyThread() 
{
  m_refEnv.invoke(clearRefs);
}

These may be eased by using the FreeReference.

Free References

For some language bindings, there is support for shareable or free references (optional, e.g. Uno/Cpp/Spec/FreeReference). These free references may be used in any particular purpose environment, as they are taking care of the appropriate mapping of any objects prior to the invokation of a particular method.

C++
class MyUnoObject;

class MyObject 
{
  cppu::FreeReference<uno::XInterface> m_obj;

public:
  MyObject(XInterface * xInterface)
    : m_obj(xInterface, SAL_NO_ACQUIRE)
  {}

  void doSomething() 
  {
    m_obj.aMethod();
  }
};

class MyThread : public Thread 
{
  MyObject * m_pMyObject;
public:
  MyThread(MyObject * pMyObject);

  void run() 
  {
    m_pMyObject->doSomething();
  }
};

...
MyObject * pMyObject = new MyObject(new UnoObject());
MyThread * pMyThread = new pMyThread(pMyObject);

pMyObject->doSomething();
...


Specifications

The relevant specifications can be found here:

In particular:

See also

Personal tools