What is the equivalent of Thread.SetApartmentState in C++? - c++

In C# there is a method SetApartmentState in the class Thread.
How do I do the same thing in C++?

For unmanaged processes, you control the apartment model used for a thread by passing appropriate parameters to CoInitializeEx(). Larry Osterman wrote up a great little guide to these:
...
When a thread calls CoInitializeEx (or
CoInitialize), the thread tells COM
which of the two apartment types it’s
prepared to host. To indicate that
the thread should live in the MTA, you
pass the COINIT_MULTITHREADED flag to
CoInitializeEx. To indicate that the
thread should host an STA, either call
CoInitialize or pass the
COINIT_APARTMENTTHREADED flag to
CoInitializeEx.
...
-- http://blogs.msdn.com/larryosterman/archive/2004/04/28/122240.aspx

c++ doesn't have built in thread support. What you are looking for depends on how you are implementing threads in your application. Win32? pthreads? boost::threads? Whichever API you are using will determine the answer to your question.
EDIT: looks like this may have an example for you: http://msdn.microsoft.com/en-us/library/system.threading.apartmentstate.aspx
It looks like it applies to managed c++.

Related

Why use CoInitialize(0); in C++

I have been writing a C++ program where I am creating a shortcut link for an exe file, and to do that I need to write the CoInitialize(0); at the starting. And without it the code does not work. Can someone help me to know why we use it?
I just want to know why we use this function.
CoInitialize(), and the extended and more recommended version CoInitializeEx(), are used to initialize the COM library for the current thread:
Initializes the COM library on the current thread
...
New applications should call CoInitializeEx instead of CoInitialize.
It has to be called for each thread that uses COM.
Note that CoInitialize() identifies the concurrency model as single-thread apartment (STA), whereas with CoInitializeEx() you have the freedom to specify the concurrency model.
More about COM threads and other related issues: Processes, Threads, and Apartments.
In case you are not familiar with COM (from the documentation):
COM is a platform-independent, distributed, object-oriented system for creating binary software components that can interact. COM is the foundation technology for Microsoft's OLE (compound documents) and ActiveX (Internet-enabled components) technologies.
If your program requires calling one of the initialization functions above, it means that either you directly, or any library you use, are using COM.
Note that each successful call to CoInitialize/Ex() must be matched with a call to CoUninitialize().
Edit:
As #IInspectable commented, using a COM object on a thread does not strictly require calling CoInitialize/Ex().
But, since COM objects have threading requirements as noted above, calling it ensures that the current thread uses the proper COM concurrency model.
See Why does CoCreateInstance work even though my thread never called CoInitialize? The curse of the implicit MTA.

Use COM STA or MTA Without Shared COM Objects?

This thread is great at explaining STA vs MTA for COM, however it doesn't address how to code for such or when to use one or the other, and only just discusses technicalities about COM apartments being used by thread-safe objects or not. I'd be willing to bet most users just want to know how to use the Win API through COM without any COM objects shared among multiple threads.
Should you use STA always if your COM objects aren't shared among threads, and your code makes use of multiple threads or a single thread each with its own COM object instances, none of the objects shared? Does it depend on the object you are using? If you don't always use STA for such when do you use MTA? Do you ever need a message pump in this case?
In my case I use the Task Scheduler API (ITaskService) and the Shell Links/Create Shortcut API (IShellLink) from the main GUI thread (using the Qt Framework), and the File Operation API (IFileOperation) and the Volume Shadow Copy Service API from a worker thread.
I call CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); from each thread before initializing and using the COM objects and CoUninitialize(); after. Is this proper usage of COM? Would the same apply using COM objects from the main GUI thread without a worker thread?
For making outbound COM calls to objects that you instantiated via CoCreateInstance, STA should be good enough, and is almost a must for your GUI thread (the one that has a GetMessage/DispatchMessage loop).
MTA starts to become relevant when hosting your own thread safe COM objects that are expected to be invoked from other processes.
The documentation for IFileOperation states this:
IFileOperation can only be applied in a single-threaded apartment
(STA) situation. It cannot be used for a multithreaded apartment (MTA)
situation. For MTA, you still must use SHFileOperation.
See all, this link: INFO: Calling Shell Functions and Interfaces from a Multithreaded Apartment
I suspect what the documentation is really trying to say is this:
The class implementing IFileOperation is not thread safe
It's ThreadingModel is declared "apartment" in the registry and will incur marhsalling overhead if accessed from an MTA thread.
On our application, have used ITaskScheduler on the main STA thread. And we use IFileOperation on a background STA thread that has its own message pump.
Some other links that I think are very useful:
https://support.microsoft.com/en-us/help/150777/info-descriptions-and-workings-of-ole-threading-models
https://devblogs.microsoft.com/oldnewthing/?p=22603

Creating Windows and Threading - C++

When a new window is created using CreateEx does its code execute in its own thread or that of its parent (i.e. the thread in which the its instantiating code was executed)? Thanks.
The window doesn't actually run any code on its own, all the code is called from the message loop which is part of your own code. You can run into huge issues trying to interact with the Windows UI with multiple threads, so you should always respond to the messages within a single thread.
CreateWindowEx() does not create a new thread. If you want a new thread you have to call
either _beginthreadex() (usually preferred) or CreateThread().
In case you're wondering, _beginthreadex() is preferred over CreateThread() because the former initializes parts of the CRT that the latter does not.
Windows have thread affinity – see Raymond Chen's article on this matter.
No, create window dont start new thread
Cross-thread GUI stuff usually ends in disaster. The windows libraries actively discourage it by throwing exceptions.
Even if it was allowed, CreateWindowEx could not do this by default because it would be making some very big assumptions about your code (locks, thread safety, etc); and most Windows development is probably still essentially single threaded.

COM calls from multiple threads

If I call the same COM function from multiple threads to an in proc COM Dll, how thread safe is that?
Do all my objects in the COM DLL also need to be thread safe for this to work reliably?
COM takes care of threading on behalf of the COM server. The server publishes the kind of threading it supports with the ThreadingModel registry key. Very common settings are Apartment or Both. Free is very rare. A missing key is equivalent to Apartment.
COM requires a single-threaded apartment (STA) for apartment threaded servers. If you don't provide one (CoInitialize/Ex call) then it will create a dedicated thread for the server. A hard requirement for an STA thread is that it also pumps a Windows message loop. The message loop is the mechanism by which COM automatically marshals a method call from one thread to another.
So, the general answer to your question is, yes, it normally is thread-safe. There are still things that can go wrong. Deadlock is possible when a call is made from a worker thread but the STA thread isn't pumping. Or the server could be fibbing about the ThreadingModel it registered. Not uncommon with servers implemented in .NET. They get registered as Both, but there are few .NET classes that are actually thread-safe.
See this very detaled article. Basically COM will take care of synchronization - you don't need to bother. However in certain cases the consumer can experience significant slowdown because of synchronization.
Depends upon the COM objects threading model. If its free threaded then you are responsible for thread safety. If its in a single threaded apartment then you can only call it from one, and if it's in a multithreaded apartment, then you can can but as always you have to consider the implications for the object's state. there is a very good answer on SO Could you explain STA and MTA? explaining this.

Boost Thread Specific Storage Question (boost/thread/tss.hpp)

The boost threading library has an abstraction for thread specific (local) storage. I have skimmed over the source code and it seems that the TSS functionality can be used in an application with any existing thread regardless of weather it was created from boost::thread --i.e., this implies that certain callbacks are registered with the kernel to hook in a callback function that may call the destructor of any TSS objects when the thread or process is going out of scope. I have found these callbacks.
I need to cache HMAC_CTX's from OpenSSL inside the worker threads of various web-servers (see this, detailed, question for what I am trying to do), and as such I do not controll the life-time of the thread -- the web-server does. Therefore I will use the TSS functionality on threads not created by boost::thread.
I just wanted to validate my assumptions before I started implementing the caching logic, are there any flaws in my logic ?
You're right. You can use it for threads not created by boost::thread.
If you look in test_tss.cpp you can see they test exactly that, and it should work with both POSIX and Windows threads.
This is partially right, as the destructor is not called when the main thread finish.