I know that most XPCOM methods are not thread safe, but is it safe to send events from WinAPI worker thread to XPCOM main thread using NS_DispatchToMainThread?
NS_DispatchToMainThread is safe to be used from any thread.
Related
I have wrote one sample com server which implements com connection point. I am calling one method in this COM object which in turn calling some other method in my client code using connection point mechanism.
But all the above listed operation is synchronous communication. I would like to make COM server pure async so that if my COM server get some event it should fire the data back to its client.
please suggest how it is possible using COM connection point.
Note :- My COM server is running as a exe out of proc.
Thanks in advance!!!
Regards
Ashish
Threading is never a minor detail in COM, just as it isn't in any runtime environment. You must observe the apartment state that the COM client program selected. And if it is STA, by far the most common selection, then it is your duty to fire the event on the thread that the client code selected. Ignoring that requirement just produces impossible to diagnose bugs in the client program.
So if you fire the event from a worker thread in your own code, the only way to get event handlers to run async, then you must marshal the interface pointer. CoMarshalThreadInterfaceInStream() or the easier-to-use IGlobalInterfaceTable gets that job done. Rock-hard requirement. It will run asynchronously when the client program opted-in by using COINIT_MULTITHREADED when it called CoInitializeEx(). The only thing you can do is publish the fact that your code is thread-safe by picking the ThreadingModel registry value, using "Both" or "Free".
Same as you do it without COM:
the client of your server object calls a method;
the method starts a background operation and returns;
The background operation can use a separate thread, an async I/O API, a timer API, etc. When the background operation has completed, it fires an event (calls a method on the client-provided sink interface);
the client handles the event.
Back to COM, all method invocations in COM are synchronous by default. When you fire an event on the client-provided sink interface, the call will block until the client returns. There's one exception to this behavior: IAdviseSink. The methods of this interface are asynchronous, if the callee resides in a different COM apartment from the caller. However, IAdviseSink is probably not what you're looking for.
The standard way to use asynchronous COM requires that the interface have an separate UUID for the asynchronous interface. IConnectionPoint does not have an async UUID, so you can't use ICallFactory to implement asynchronous COM.
The synchronous calls in C# can be converted to a asynchronous calls by creating a new delegate, and then the BeginInvoke can be called on that delegate. The same operation can be done by without creating a delegate, but call the ThreadPool::QueueWorkerItem method. As I understand both methods do the same job. The delegate::BeginInvoke is little more coding but easy to understand. Do these operations both use thread pool to do the asynchronous operation internally?
After testing a sample app, I have found out that delegate::BeginInvoke invokes the call in a different thread. Internally it might be using ThreadPool to create a background worker thread to complete the job because the callback can't modify the controls which is created by the UI thread.
I am using an FTP client in a seperate thread. The FTP client uses a job list to up-/download files to a connected server. If the thread wants to communicate with my main thread it will use an event queue. The thread will create an event, put it into the queue and then post a windows message to my main thread telling me that there are new events in the queue.
The main thread then fetches the latest event from the queue and removes it. The queue is held in the thread object but I am using a lock to make it thread-safe.
I created a function within my main thread which is listening for messages from the FTP thread. I also registered a handle for this method (via AllocateHwnd()) so that the thread is posting it's messages excactly to the listening method of my main thread.
Now I want to know if the following scenario is possible:
I destroy the thread. Right before it gets destroyed the thread will post a windows message to the main thread because there is a new event. The windows message however has some delay (for whatever reason). Now the thread gets destroyed and the thread object is gone. Of course, the event queue is also gone. The main thread now receives the delayed windows message telling him that there is a new event in the queue. It tries to fetch the queue which will result in an invalid pointer operation since there the queue and the thread object have been free'd.
To avoid this problem, I implemented a check into my message listening method. Right before I access the event queue from the thread I will check if the thread still exists. If yes, then I access the event queue, if no, then I will simply drop the message.
However, what if the thread gets destroyed right after I checked it, but before I access the queue. The sequence would be like this:
Check if thread exists
(thread gets destroyed NOW)
Access event queue
Can this scenario still happen? I know that this does sound like a very specific and tiny scenario since the thread would have to get destroyed right between those two commands in order to fail but I want to make sure that I do not access the event queue when the thread is actually not existing anymore.
I hope I could explain my problem well enough. Thanks in advance for any provided answers.
fellow programmers :-)
Is there a way to know if any thread is blocked on the specific semaphore (queue isn't empty), using win32 api and c++?
Thanks in advance :-)
How about waiting on the semaphore with at timeout? If the timeout fires, immediately lock the queue and check the count. This will only give a rough guide - it's posible for a producer to enqueue an object netween the timeout and locking the queue, but it might enable you to debug your P-C queue.
How to gracefully stop a windows service with multi-threaded processing on a timer thread? Is it possible to add some infinite loop logic in the OnStop method to postpone the service shutting down.
You have to handle cancellation of the threads in your service in the OnStop() method.
Try some logic with ManualResetEvent or AutoResetEvent
You probably also have to stop your timer.
You will probably need to use some sort of flag to indicate whether a Thread should stop or not. There is already a similar question on SO - here