Why does COM+ ignore the apartment threading model? - windows

I have an STA COM component which is put into a COM+ application. The client creates several instances of the class in that component and calls their methods in parallel. The class is registered properly - the "ThreadingModel" for the corresponding class id is "Apartment".
I see several calls of the same method of the same class being executed in parallel inside the component - in actual component code. They are executed in the same process but in different threads.
What's happening? Is COM+ ignoring the threading model? Shouldn't STA model only allow one call at a time to be executed?

To avoid confusion, I won't use the term "object" in this answer. Instead let's use "class" and "instance". I'm confident we all understand the difference between them.
Marking your COM class with a ThreadingModel of "Apartment" means that instances of it will be loaded into an STA. The process creating those instances will determine whether they all go into the same STA, or into separate STAs.
As you've discovered, COM+ has loaded several instances into separate STAs.
The guarantee you get with an STA is that a single instance will never be accessed by multiple threads at the same time. Separate instances of the same class, if they are loaded into separate STAs, could certainly be accessed by different threads at the same time.
So the STA is really a way of protecting your instance data. Not your class data. Any "shared" or "static" data in your COM code will have to be protected by you.

STA guarantees that your object is only accessed from a single, specific thread -- no protection against shared variable is required.
I remember that for VB6, there was a special mode (I do not recall how it was named): You could allow COM+ to spawn up multiple STAs, each using a dedicated object. The variables of these objects, however, were treated as thread-local storage -- so although there are multiple instances of your COM class being accessed from multiple threads, no sharing of variables is taking place. Is it possible that you are using this feature?

No, not really. STA literally means 'Single Threaded Apartment' which further means that only a single thread can run in an apartment. Now the question is that what is an apartment. Apartment is a logical space within a process and its implementation can vary from framework to framework. Microsoft implements apartments as Threads because of which an STA (in Microsoft's COM Context) translates into Single Threaded Thread i.e., there can be multiple apartments/threads but every apartment/thread will be single threaded in case of STA.
You can generalize this thing to MTA yourself. From what I said above, an MTA is a Multi-Threaded thread in COM Context.

Have you passed the object to objects that live in another apartment? If so, did you need to marshal the interface before you did it? Did you happen to aggregate the free threaded marshaller?
Roughly speaking, if you pass an interface to your object to an object in another apartment (thread), then you must make sure to marshal the interface. If you do not, then you may find that your object can be called freely from the objects in the other apartment, since they are not calling through a proxy which handles the call correctly.
All calls to an object must be made on
its thread (within its apartment). It
is forbidden to call an object
directly from another thread; using
objects in this free-threaded manner
could cause problems for applications.
The implication of this rule is that
all pointers to objects must be
marshaled when passed between
apartments. COM provides the following
two functions for this purpose:
* CoMarshalInterThreadInterfaceInStream marshals an interface into a stream object that is returned to the caller.
* CoGetInterfaceAndReleaseStream unmarshals an interface pointer from a stream object and releases it.
These functions wrap calls to
CoMarshalInterface and
CoUnmarshalInterface functions, which
require the use of the MSHCTX_INPROC
flag.

Related

What does JMS Session single-threadedness mean?

What is the exact nature of the thread-unsafety of a JMS Session and its associated constructs (Message, Consumer, Producer, etc)? Is it just that access to them must be serialized, or is it that access is restricted to the creating thread only?
Or is it a hybrid case where creation can be distinguished from use, i.e. one thread can create them only and then another thread can be the only one to use them? This last possibility would seem to contradict the statement in this answer which says "In fact you must not use it from two different threads at different times either!"
But consider the "Server Side" example code from the ActiveMQ documentation.
The Server class has data members named session (of type Session) and replyProducer (of type MessageProducer) which are
created in one thread: whichever one invokes the Server() constructor and thereby invokes the setupMessageQueueConsumer() method with the actual creation calls; and
used in another thread: whichever one invokes the onMessage() asynchronous callback.
(In fact, the session member is used in both threads too: in one to create the replyProducer member, and in the other to create a message.)
Is this official example code working by accident or by design? Is it really possible to create such objects in one thread and then arrange for another thread to use them?
(Note: in other messaging infrastructures, such as Solace, it's possible to specify the thread on which callbacks occur, which could be exploited to get around this "thread affinity of objects" restriction, but no such API call is defined in JMS, as far as I know.)
JMS specification says a session object should not be used across threads except when calling Session.Close() method. Technically speaking if access to Session object or it's children (producer, consumer etc) is serialized then Session or it's child objects can be accessed across threads. Having said that, since JMS is an API specification, it's implementation differs from vendor to vendor. Some vendors might strictly enforce the thread affinity while some may not. So it's always better to stick to JMS specification and write code accordingly.
The official answer appears to be a footnote to section 4.4. "Session" on p.60 in the JMS 1.1 specification.
There are no restrictions on the number of threads that can use a Session object or those it creates. The restriction is that the resources of a Session should not be used concurrently by multiple threads. It is up to the user to insure that this concurrency restriction is met. The simplest way to do this is to use one thread. In the case of asynchronous delivery, use one thread for setup in stopped mode and then start asynchronous delivery. In more complex cases the user must provide explicit synchronization.
Whether a particular implementation abides by this is another matter, of course. In the case of the ActiveMQ example, the code is conforming because all inbound message handling is through a single asynchronous callback.

boost.asio - do i need to use locks if sharing database type object between different async handlers?

I'm making a little server for a project, I have a log handler class which contains a log implemented as a map and some methods to act on it (add entry, flush to disk, commit etc..)
This object is instantiated in the server Class, and I'm passing the address to the session so each session can add entries to it.
The sessions are async, the log writes will happen in the async_read callback. I'm wondering if this will be an issue and if i need to use locks?
The map format is map<transactionId map<sequenceNum, pair<head, body>>, each session will access a different transactionId, so there should be no clashes as far as i can figure. Also hypothetically, if they were all writing to the same place in memory -- something large enough that the operation would not be atomic; would i need locks? As far as I understand each async method dispatches a thread to handle the operation, which would make me assume yes. At the same time I read that one of the great uses of async functions is the fact that synchronization primitives are not needed. So I'm a bit confused.
First time using ASIO or any type of asynchronous functions altogether, and i'm not a very experienced coder. I hope the question makes sense! The code seems to run fine so far, but i'm curios if it's correct.
Thank you!
Asynchronous handlers will only be invoked in application threads processing the io_service event loop via run(), run_one(), poll(), or poll_one(). The documentation states:
Asynchronous completion handlers will only be called from threads that are currently calling io_service::run().
Hence, for a non-thread safe shared resource:
If the application code only has one thread, then there is neither concurrency nor race conditions. Thus, no additional form of synchronization is required. Boost.Asio refers to this as an implicit strand.
If the application code has multiple threads processing the event-loop and the shared resource is only accessed within handlers, then synchronization needs to occur, as multiple threads may attempt to concurrently access the shared resource. To resolve this, one can either:
Protect the calls to the shared resource via a synchronization primitive, such as a mutex. This question covers using mutexes within handlers.
Use the same strand to wrap() the ReadHandlers. A strand will prevent concurrent invocation of handlers dispatched through it. For more details on the usage of strands, particularly for composed operations, such as async_read(), consider reading this answer.
Rather than posting the entire ReadHandler into the strand, one could limit interacting with the shared resource to a specific set of functions, and these functions are posted as CompletionHandlers to the same strand. This subtle difference between this and the previous solution is the granularity of synchronization.
If the application code has multiple threads and the shared resource is accessed from threads processing the event loop and from threads not processing the event loop, then synchronization primitives, such as a mutex, needs to be used.
Also, even if a shared resource is small enough that writes and reads are always atomic, one should prefer using explicit and proper synchronization. For example, although the write and read may be atomic, without proper memory fencing to guarantee memory visibility, a thread may not observe a chance in memory even though the actual memory has chanced. Boost.Asio's will perform the proper memory barriers to guarantee visibility. For more details, on Boost.Asio and memory barriers, consider reading this answer.

Several limitation classes per one Job Object

In Windows Job Object can apply some amount of different limitations for processes. These limitations are available through the different job object info classes.
MSDN says "You can use the SetInformationJobObject function to set several limits in a single call. If you want to establish the limits one at a time or change a subset of the limits, call the QueryInformationJobObject function to obtain the current limits, modify these limits, and then call SetInformationJobObject."
But it's unclear: is it possible to set limitations from more than one job object info class for one job object?
Of course "rich" limit classes wrap the basic, so we have essentially limitations of two classes simultaneously. But I ask about the case of two non-basic classes.

Outlook Addin: Working with threads

I'm working on an Outlook Addin, and I have to process a large amount of items. This takes quite a lot of time, and I therefore tried to have the processing running in a different thread (using Task.Factory.StartNew). However, that results in Outlook randomly crashing.
I'm using Redemption to work with MAPITable, in order to reduce workload and load only relevant data.
I've tried initializing my RDOSession from both my main thread, and my worker thread.
I've tried getting the MAPIFolders on the main thread, and working with only the MAPITable on the worker thread
Currently, the only thing that works for me is running all my logic on the main thread (in the button click event), however that locks Outlook's user interface for a long period of time, which is unacceptable from a user's point of view.
Does anyone have some pointer on how to work with background threads from within an Outlook Addin?
Having similar code in my project I would suggest the following:
Create new thread using the Thread class and set it apartment to STA.
Loggin to session using "session.Logon("profileName", NoMail: true, NewSession: false);" and not using MAPIOBJECT. I found it has better performance than using MAPIOBJECT, my guess is it still marshal some calls back to the main thread as MAPIOBJECT was created on the main thread.
Use "Marshal.ReleaseComObject" on each and every COM object you use as soon as you are done with them. This is probably what causing the instability as Outlook really doesn't like when it's object are left too long. For example this line of code "var table = rdoFolder.Items.MAPITable;" create two COM objects: RDOItems and MAPITable, both of them must be released so you need to split this line to hold reference to RDOItems object.
Call GC.Collect and Application.DoEvents because if you don't call Marshal.ReleaseComObject on all COM object the finalizer will try to release them and will hang because the COM objects were created on thread that don't pump message loop and it's finalizer method must run on the thread that created them.
If you can, fire a secondary process and do this loop in the separate process. This will make maximum separation between the UI and your background work.
What was the problem using RDO objects in a secondary thread? As long as RDOSession is created on the secondary thread, MAPI should be properly initialized.
Also, TaskFactory uses a thread pool, you'd be better off using an explicit Thread class, o at least make sure that RDOSession is not shared between different threads - MAPI must be initialized on each thread.

Interprocess synchronization barrier in Windows

I am trying to establish a barrier between to different processes in Windows. They are essentially two copies of the same process (Running them as two separate threads instead of processes is not an option).
The idea is to place barriers at different stages of the program, to make sure that both processes start each stage at the same time.
What is the most efficient way of implementing this in Windows?
Use a named event (see CreateEvent and WaitForSingleObject API functions). You would need two events per barrier - each event created in another instance of the application. Then both instances wait for each other's event. Of course, these events can be reused later for another barrier.
There exists one complexity, though - as event names are globally unique (let's say so for simplicity), each event would have a different name, maybe prefixed by the instance's process ID. So each instance of the application would have to get another instance's ID in order to find the name of the event created by another instance.
If you have a windowed application, you can broadcast a message which will inform the second instance of the application about an existence of the first instance.

Resources