Click here to Skip to main content
Click here to Skip to main content
Go to top

STA threading model issues

, 16 May 2001
Rate this:
Please Sign up or sign in to vote.
Describes STA threading issues
<!-- Download Links --> <!-- Main HTML starts here -->

Introduction

Here are two things that I think developers should be aware of when programming with STA threading model. I'm not trying to cover all pitfalls that one might encounter, but only specific two that I thought can bite developers..

Project: "Create an ActiveX component for some or other purpose."

At first I started with a simple ActiveX component using "Apartment" threading model. Then added another COM class, which will be passed to one of the events as argument. Created an events thread to fire the events to client. All seemed to work fine. I wrote various simple apps that tested the functionality in ATL/WTL, MFC, VB, and VBScript/JScript all using same threading model.

STA Deadlock

Then I've tried MTA for the container. Suddenly, it started to deadlock randomly. Why? I thought if it works for STA what difference does it make if the container is STA or MTA? COM should intervene and take care of apartment incompatibilities. It took some quick research to find the problem. Thanks to Valery Pryamikov's post on ATL list, "Designing Solutions with COM+ Technologies" (pp. 96-97) and "Transactional COM+" (pp. 130-131) things started to make sense. I've made a stripped down version that shows the problem and you can download the STA Deadlock sample project. Please run it in the debugger. The deadlock will happen when you quit the app. Notice that if you change the client's threading model to "Apartment" or in-proc COM server to "Both" everything works. The problem comes from the fact that client makes an outgoing call back on the COM component passed in the event's function. Now, if at the same time client calls back into main component for whatever reason and blocks with message loop (i.e. to shutdown events thread in the component while Unadvise is called), there will be a deadlock. When the client called back on the ISimpleObj methods, "channel" is already taken by the Unadvise where I tried to shutdown the events thread. So, both threads will be waiting for each other to get a hold of the "channel". It's just one scenario where the deadlock could happen and can easily be accomplished other ways. The nasty thing about this is that it may not happen all the time and may not happen at all. It all depends on the right circumstances. So be aware.

STA Reentrancy

This is widely known, but I just wanted to show it anyway because I never saw concrete examples when I was starting with COM. Maybe someone will find it helpful. So, after dealing with deadlock I got bitten by the STA reentrancy. The component was using windows sockets to communicate with the server. Now, that I've marked my component as "Both" and synchronized all access to the component I thought I'm safe...But...One of the methods is taking an interface pointer that is part of some object. Now, inside the method I call methods on the interface and send data out over the socket. Unfortunately, when I make the outgoing call on another component, "STA reentrancy model" will yield the thread to another incoming call if there is any. It can happen if client decides to call my method from the thread different from the object's creating thread. I can't assume that clients will do the right thing. So, this was unacceptable because the actual server that my component communicates with over sockets, expects a specific flow of information. I've made a simple project that shows it in action using file instead of sockets. Look at STA Reentrancy if you run it, you'll see that the output to log file is mixed up instead of having a sequential flow. Notice that if you change the client's threading model to MTA it will work fine. COM will come in and take care of synchronization for us.

After dealing with "Apartment", "Both", and "Free" I would take MTA anytime over STA model - if possible of course. I hope someone finds this article helpful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Leon Finker

United States United States
No Biography provided

Comments and Discussions

 
GeneralCOM PinmemberSeethalakshmi2-Sep-05 23:39 
GeneralRe: COM PinmemberJessn2-Nov-06 11:28 
GeneralServer\clients problem PinsussPascal75855-Jul-05 7:35 
GeneralRe: Server\clients problem PinmemberLeon Finker5-Jul-05 13:46 
GeneralRPC_E_WRONG_THREAD PinmemberPriyank Bolia13-May-04 1:06 
GeneralRe: RPC_E_WRONG_THREAD PinmemberLeon Finker13-May-04 1:16 
GeneralRe: RPC_E_WRONG_THREAD PinmemberPriyank Bolia13-May-04 3:03 
I can't understand that article, the problem is that I have a COleDispatchDriver pointer in the main thread : COleDispatchDriver *m_pVicApp which is used in some other thread to call InvokeHelper for the server function, whose code I don't have.
 
http://www.geocities.com/priyank_bolia/

GeneralRe: RPC_E_WRONG_THREAD PinmemberLeon Finker13-May-04 4:20 
GeneralRe: RPC_E_WRONG_THREAD PinsussAnonymous5-Apr-05 22:06 
GeneralI Think.................. Pinmemberzhenguri6-Aug-01 16:21 
GeneralMultiThread Problem PinmemberScott Tsai12-Jun-01 16:57 
GeneralRe: MultiThread Problem PinmemberLeon Finker15-Jun-01 6:14 
GeneralCan VB use MultiThreaded Object? PinmemberDaniel Stockdell5-Nov-01 6:02 
QuestionThreading model question? PinmemberAmit Dey29-May-01 19:39 
AnswerRe: Threading model question? PinmemberLeon Finker30-May-01 4:34 
GeneralRe: Threading model question? PinmemberMehta Jigar27-May-06 19:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 17 May 2001
Article Copyright 2001 by Leon Finker
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid