COM EXE Server - please make me sane 
Author Message
 COM EXE Server - please make me sane

Hi

Here's the scenario:

EXE server with one COM object.

WinMain we have CoInitialize(NULL).

The COM object is an ATL one with a base class
CComObjectRootEx<CComMultiThreadModel>.

When this object is activated (externally) I think it just gets
instantiated in the default STA. Is that right?

However, this isn't my code, and the author has aggregated the FTM in
an effort to stop deadlocks [?!] - he means server busy messages due
to logical thread reentrancy I think. There are mutex operations in
some of the COM exposed methods which I think are probably causing the
blocking because he's not servicing the message loop during the
WaitForsingleObject and ReleaseMutex calls!

So, really - does this object get instantiated in the default STA or
the MTA? And am I on the right lines? I think the FTM is superfluous.
I think the lack of MsgWaitForMultiple is the problem.

Cheers and look forward to some answer to make me sane again!

Emma Middlebrook



Wed, 13 Jul 2005 01:34:54 GMT  
 COM EXE Server - please make me sane

FTM has nothing to do with deadlocks prevention. It ensures direct access
from any apartment in the process. Also, verify the component's threading
model is set to Both.

The detaill you provide convince me the component is intended to be used
only from worker threads. Essentially, the author assumend the client will
instantiate the component, then hand it over to another thread to do any
operations. Aggregation of FTM is an essential step in that regard. Shortly,
spin a thread to do your work and never call this component from your GUI
thread...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

Quote:

> Hi

> Here's the scenario:

> EXE server with one COM object.

> WinMain we have CoInitialize(NULL).

> The COM object is an ATL one with a base class
> CComObjectRootEx<CComMultiThreadModel>.

> When this object is activated (externally) I think it just gets
> instantiated in the default STA. Is that right?

> However, this isn't my code, and the author has aggregated the FTM in
> an effort to stop deadlocks [?!] - he means server busy messages due
> to logical thread reentrancy I think. There are mutex operations in
> some of the COM exposed methods which I think are probably causing the
> blocking because he's not servicing the message loop during the
> WaitForsingleObject and ReleaseMutex calls!

> So, really - does this object get instantiated in the default STA or
> the MTA? And am I on the right lines? I think the FTM is superfluous.
> I think the lack of MsgWaitForMultiple is the problem.

> Cheers and look forward to some answer to make me sane again!

> Emma Middlebrook




Wed, 13 Jul 2005 03:34:36 GMT  
 COM EXE Server - please make me sane

Oops, I'm not reading carefully it seems... I assumed you are using
a COM object from a DLL, didn't read you are implementing it in an
EXE server...

Alright, the FTM _is_ superfluous and can safely be removed. The
server must be changed to free-threaded (CoInitializeEx with
COINIT_MULTITHREADED). Alternatively, you can write a class
factory that instantiates only that object in the MTA (it is created
in the main and only STA of your single-threaded server right
now), but only do it if your server really needs to be single-
threaded for the other objects it exposes...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

Quote:

> Hi

> Here's the scenario:

> EXE server with one COM object.

> WinMain we have CoInitialize(NULL).

> The COM object is an ATL one with a base class
> CComObjectRootEx<CComMultiThreadModel>.

> When this object is activated (externally) I think it just gets
> instantiated in the default STA. Is that right?

> However, this isn't my code, and the author has aggregated the FTM in
> an effort to stop deadlocks [?!] - he means server busy messages due
> to logical thread reentrancy I think. There are mutex operations in
> some of the COM exposed methods which I think are probably causing the
> blocking because he's not servicing the message loop during the
> WaitForsingleObject and ReleaseMutex calls!

> So, really - does this object get instantiated in the default STA or
> the MTA? And am I on the right lines? I think the FTM is superfluous.
> I think the lack of MsgWaitForMultiple is the problem.

> Cheers and look forward to some answer to make me sane again!

> Emma Middlebrook




Wed, 13 Jul 2005 03:41:33 GMT  
 COM EXE Server - please make me sane

SImply disregard this reply and read my other reply.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

FTM has nothing to do with deadlocks prevention. It ensures direct access
from any apartment in the process. Also, verify the component's threading
model is set to Both.

The detaill you provide convince me the component is intended to be used
only from worker threads. Essentially, the author assumend the client will
instantiate the component, then hand it over to another thread to do any
operations. Aggregation of FTM is an essential step in that regard. Shortly,
spin a thread to do your work and never call this component from your GUI
thread...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

Quote:

> Hi

> Here's the scenario:

> EXE server with one COM object.

> WinMain we have CoInitialize(NULL).

> The COM object is an ATL one with a base class
> CComObjectRootEx<CComMultiThreadModel>.

> When this object is activated (externally) I think it just gets
> instantiated in the default STA. Is that right?

> However, this isn't my code, and the author has aggregated the FTM in
> an effort to stop deadlocks [?!] - he means server busy messages due
> to logical thread reentrancy I think. There are mutex operations in
> some of the COM exposed methods which I think are probably causing the
> blocking because he's not servicing the message loop during the
> WaitForsingleObject and ReleaseMutex calls!

> So, really - does this object get instantiated in the default STA or
> the MTA? And am I on the right lines? I think the FTM is superfluous.
> I think the lack of MsgWaitForMultiple is the problem.

> Cheers and look forward to some answer to make me sane again!

> Emma Middlebrook




Wed, 13 Jul 2005 03:43:56 GMT  
 COM EXE Server - please make me sane
OK, without the waffle might help, I only want a Yes/No or explanation
to this:

Here's the scenario:
EXE server with one COM object.
WinMain we have CoInitialize(NULL).
The COM object is an ATL one with a base class
CComObjectRootEx<CComMultiThreadModel>.

When this object is activated externally (e.g. from another .exe) I
think it just gets instantiated in the default STA. Is that right?

Come on: Yes/No and/or explanation please!

Thanks

emma



Wed, 13 Jul 2005 09:04:50 GMT  
 COM EXE Server - please make me sane
Hello Alexander

Listen: the point I wish to be clarified is exactly that which I
described. So are you saying that the COM object is actually serviced
like an apartment threaded object? I don't care about any other
complications or augmentations beyond those which I stated exactly so
any comments on those are appreciated. So far, it's just padding from
you Alexander and I want some closure based on my facts only :-))))

Emma

Quote:

> Oops, I'm not reading carefully it seems... I assumed you are using
> a COM object from a DLL, didn't read you are implementing it in an
> EXE server...

> Alright, the FTM  is  superfluous and can safely be removed. The
> server must be changed to free-threaded (CoInitializeEx with
> COINIT MULTITHREADED). Alternatively, you can write a class
> factory that instantiates only that object in the MTA (it is created
> in the main and only STA of your single-threaded server right
> now), but only do it if your server really needs to be single-
> threaded for the other objects it exposes...

> --
> =========================
> ============
> Alexander Nickolov
> Microsoft MVP [VC], MCSD

> MVP VC FAQ: http://www.mvps.org/vcfaq
> =========================
> ============



> > Hi

> > Here's the scenario:

> > EXE server with one COM object.

> > WinMain we have CoInitialize(NULL).

> > The COM object is an ATL one with a base class
> > CComObjectRootEx<CComMultiThreadModel>.

> > When this object is activated (externally) I think it just gets
> > instantiated in the default STA. Is that right?

> > However, this isn't my code, and the author has aggregated the FTM in
> > an effort to stop deadlocks [?!] - he means server busy messages due
> > to logical thread reentrancy I think. There are mutex operations in
> > some of the COM exposed methods which I think are probably causing the
> > blocking because he's not servicing the message loop during the
> > WaitForsingleObject and ReleaseMutex calls!

> > So, really - does this object get instantiated in the default STA or
> > the MTA? And am I on the right lines? I think the FTM is superfluous.
> > I think the lack of MsgWaitForMultiple is the problem.

> > Cheers and look forward to some answer to make me sane again!

> > Emma Middlebrook




Wed, 13 Jul 2005 09:08:47 GMT  
 COM EXE Server - please make me sane
I think you should be using something like CoWaitForMultipleHandles()
instead to allow message dispatch to continue in case of STA.

The following article has more details:

COM Threading and Application Architecture in COM+ Applications
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnco...

SG


Quote:

> There are mutex operations in
>some of the COM exposed methods which I think are probably causing the
>blocking because he's not servicing the message loop during the
>WaitForsingleObject and ReleaseMutex calls!



Wed, 13 Jul 2005 09:37:05 GMT  
 COM EXE Server - please make me sane

Quote:

> OK, without the waffle might help, I only want a Yes/No or explanation
> to this:

> Here's the scenario:
> EXE server with one COM object.
> WinMain we have CoInitialize(NULL).
> The COM object is an ATL one with a base class
> CComObjectRootEx<CComMultiThreadModel>.

> When this object is activated externally (e.g. from another .exe) I
> think it just gets instantiated in the default STA. Is that right?

> Come on: Yes/No and/or explanation please!

> Thanks

> emma


The answer depends ... but you can determine this empirically yourself
with GetCurrentThreadId() and OutputDebugString().

Create several objects - observe resulting RPC thread ids and also
compare to the COM EXE's main thread id.

-rick



Wed, 13 Jul 2005 11:53:41 GMT  
 COM EXE Server - please make me sane
Thanks, but from the docs you can see that this call is just a wrapper
to be used in code implemented in objects marked 'both'. An STA simply
needs its message queue serviced correctly, nothing more.
Quote:

> I think you should be using something like CoWaitForMultipleHandles()
> instead to allow message dispatch to continue in case of STA.

> The following article has more details:

> COM Threading and Application Architecture in COM+ Applications
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnco...

> SG



> > There are mutex operations in
> >some of the COM exposed methods which I think are probably causing the
> >blocking because he's not servicing the message loop during the
> >WaitForsingleObject and ReleaseMutex calls!



Fri, 15 Jul 2005 06:43:26 GMT  
 COM EXE Server - please make me sane
Well, if you are saying the answer depends on whether
_ATL_APARTMENT_THREADED is defined why didn't you just say that?! I
don't think it depends on anything else.

Is that what you meant? That's the only 'parameter' I failed to
mention.

So,

EXE server with one COM class.
Class derives from CComObjectRootEx<CComMultiThreadModel>.
In WinMain, we have CoInitialize(NULL).
_ATL_APARTMENT_THREADED is defined.

So we have that object sitting in the default STA. Therefore this
programmer's FTM antics and mutexes are a red herring and useless. The
mutexes will be essentially ignored as it is OK to 'reenter' mutexes
on the same thread.

Thanks.



Fri, 15 Jul 2005 06:51:44 GMT  
 COM EXE Server - please make me sane
Thanks Alexander - I think I misread yours too :-)

I agree that the server must be change to free-threaded COM
initialization for it to make this programmer's efforts seem a bit
more consistent but there's a whole load of GUI code wrapped up in
this object too. So STA it is.

You define either of these to get your start up code working
correctly:
_ATL_FREE_THREADED
_ATL_APARTMENT_THREADED

One thing you might be able to help me with is understanding this
auto-generated code below in WinMain. If we initialize our start-up
thread to be in the MTA then what's the point of the message loop at
the bottom of this? Has a message queue got any place here really?
Messages will just be incoming on arbitrary RPC threads. I suppose the
point of the message loop is just in case objects decided to do a bit
of message posting or sending? Am I right in thinking that that's all
it can be for? I suspect it could actually be removed for a typical
exe server containing just free threaded objects?

    if (bRun)
    {
        _Module.StartMonitor();
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
        hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
        _ASSERTE(SUCCEEDED(hRes));
        hRes = CoResumeClassObjects();
#else
        hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE);
#endif
        _ASSERTE(SUCCEEDED(hRes));

        MSG msg;
        while (GetMessage(&msg, 0, 0, 0))
            DispatchMessage(&msg);

        _Module.RevokeClassObjects();
        Sleep(dwPause); //wait for any threads to finish
    }

Quote:

> Oops, I'm not reading carefully it seems... I assumed you are using
> a COM object from a DLL, didn't read you are implementing it in an
> EXE server...

> Alright, the FTM  is  superfluous and can safely be removed. The
> server must be changed to free-threaded (CoInitializeEx with
> COINIT MULTITHREADED). Alternatively, you can write a class
> factory that instantiates only that object in the MTA (it is created
> in the main and only STA of your single-threaded server right
> now), but only do it if your server really needs to be single-
> threaded for the other objects it exposes...

> --
> =========================
> ============
> Alexander Nickolov
> Microsoft MVP [VC], MCSD

> MVP VC FAQ: http://www.mvps.org/vcfaq
> =========================
> ============



> > Hi

> > Here's the scenario:

> > EXE server with one COM object.

> > WinMain we have CoInitialize(NULL).

> > The COM object is an ATL one with a base class
> > CComObjectRootEx<CComMultiThreadModel>.

> > When this object is activated (externally) I think it just gets
> > instantiated in the default STA. Is that right?

> > However, this isn't my code, and the author has aggregated the FTM in
> > an effort to stop deadlocks [?!] - he means server busy messages due
> > to logical thread reentrancy I think. There are mutex operations in
> > some of the COM exposed methods which I think are probably causing the
> > blocking because he's not servicing the message loop during the
> > WaitForsingleObject and ReleaseMutex calls!

> > So, really - does this object get instantiated in the default STA or
> > the MTA? And am I on the right lines? I think the FTM is superfluous.
> > I think the lack of MsgWaitForMultiple is the problem.

> > Cheers and look forward to some answer to make me sane again!

> > Emma Middlebrook




Fri, 15 Jul 2005 07:01:12 GMT  
 COM EXE Server - please make me sane
Emma,

As far as I can see: Yes.

If I'm not a complete ass, CComObjectRootEx< CComMultiThreadModel > has
nothing to do with it. In EXE servers, object threading model is determined
by the apartment in which their class factories are registered.

I got this from [1], and kind of got it confirmed by the super-people on
Developmentor's ATL list [2].

Does this clear things up?

[1]
http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0897/free.htm...
sj/0897/newnav.htm
[2]
http://discuss.develop.com/archives/wa.exe?A2=ind0301b&L=atl&T=0&F=&S...

--
Kim Gr?sman, Visual C++ MVP
http://www.winwonk.com


Quote:
> OK, without the waffle might help, I only want a Yes/No or explanation
> to this:

> Here's the scenario:
> EXE server with one COM object.
> WinMain we have CoInitialize(NULL).
> The COM object is an ATL one with a base class
> CComObjectRootEx<CComMultiThreadModel>.

> When this object is activated externally (e.g. from another .exe) I
> think it just gets instantiated in the default STA. Is that right?

> Come on: Yes/No and/or explanation please!

> Thanks

> emma




Fri, 15 Jul 2005 16:57:11 GMT  
 COM EXE Server - please make me sane

It's just an artifact of the ATL implementation. The message loop only
waits for WM_QUIT to be posted to exit from the main thread. It could
safely be replaced by WaitForSingleObject and the code in the monitor
thread modified accordingly.

And, yes, your object _is_ serviced in the main STA now. Sorry, kind of
posted more than you asked for... :)

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

Quote:

> Thanks Alexander - I think I misread yours too :-)

> I agree that the server must be change to free-threaded COM
> initialization for it to make this programmer's efforts seem a bit
> more consistent but there's a whole load of GUI code wrapped up in
> this object too. So STA it is.

> You define either of these to get your start up code working
> correctly:
> _ATL_FREE_THREADED
> _ATL_APARTMENT_THREADED

> One thing you might be able to help me with is understanding this
> auto-generated code below in WinMain. If we initialize our start-up
> thread to be in the MTA then what's the point of the message loop at
> the bottom of this? Has a message queue got any place here really?
> Messages will just be incoming on arbitrary RPC threads. I suppose the
> point of the message loop is just in case objects decided to do a bit
> of message posting or sending? Am I right in thinking that that's all
> it can be for? I suspect it could actually be removed for a typical
> exe server containing just free threaded objects?

>     if (bRun)
>     {
>         _Module.StartMonitor();
> #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
>         hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
>             REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
>         _ASSERTE(SUCCEEDED(hRes));
>         hRes = CoResumeClassObjects();
> #else
>         hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
>             REGCLS_MULTIPLEUSE);
> #endif
>         _ASSERTE(SUCCEEDED(hRes));

>         MSG msg;
>         while (GetMessage(&msg, 0, 0, 0))
>             DispatchMessage(&msg);

>         _Module.RevokeClassObjects();
>         Sleep(dwPause); //wait for any threads to finish
>     }


> > Oops, I'm not reading carefully it seems... I assumed you are using
> > a COM object from a DLL, didn't read you are implementing it in an
> > EXE server...

> > Alright, the FTM  is  superfluous and can safely be removed. The
> > server must be changed to free-threaded (CoInitializeEx with
> > COINIT MULTITHREADED). Alternatively, you can write a class
> > factory that instantiates only that object in the MTA (it is created
> > in the main and only STA of your single-threaded server right
> > now), but only do it if your server really needs to be single-
> > threaded for the other objects it exposes...

> > --
> > =========================
> > ============
> > Alexander Nickolov
> > Microsoft MVP [VC], MCSD

> > MVP VC FAQ: http://www.mvps.org/vcfaq
> > =========================
> > ============



> > > Hi

> > > Here's the scenario:

> > > EXE server with one COM object.

> > > WinMain we have CoInitialize(NULL).

> > > The COM object is an ATL one with a base class
> > > CComObjectRootEx<CComMultiThreadModel>.

> > > When this object is activated (externally) I think it just gets
> > > instantiated in the default STA. Is that right?

> > > However, this isn't my code, and the author has aggregated the FTM in
> > > an effort to stop deadlocks [?!] - he means server busy messages due
> > > to logical thread reentrancy I think. There are mutex operations in
> > > some of the COM exposed methods which I think are probably causing the
> > > blocking because he's not servicing the message loop during the
> > > WaitForsingleObject and ReleaseMutex calls!

> > > So, really - does this object get instantiated in the default STA or
> > > the MTA? And am I on the right lines? I think the FTM is superfluous.
> > > I think the lack of MsgWaitForMultiple is the problem.

> > > Cheers and look forward to some answer to make me sane again!

> > > Emma Middlebrook




Sat, 16 Jul 2005 04:43:53 GMT  
 COM EXE Server - please make me sane
Thanks Alexander for clearing that up. I'm getting there!
Quote:

> It's just an artifact of the ATL implementation. The message loop only
> waits for WM QUIT to be posted to exit from the main thread. It could
> safely be replaced by WaitForSingleObject and the code in the monitor
> thread modified accordingly.

> And, yes, your object  is  serviced in the main STA now. Sorry, kind of
> posted more than you asked for... :)

> --
> =========================
> ============
> Alexander Nickolov
> Microsoft MVP [VC], MCSD

> MVP VC FAQ: http://www.mvps.org/vcfaq
> =========================
> ============



> > Thanks Alexander - I think I misread yours too :-)

> > I agree that the server must be change to free-threaded COM
> > initialization for it to make this programmer's efforts seem a bit
> > more consistent but there's a whole load of GUI code wrapped up in
> > this object too. So STA it is.

> > You define either of these to get your start up code working
> > correctly:
> >  ATL FREE THREADED
> >  ATL APARTMENT THREADED

> > One thing you might be able to help me with is understanding this
> > auto-generated code below in WinMain. If we initialize our start-up
> > thread to be in the MTA then what's the point of the message loop at
> > the bottom of this? Has a message queue got any place here really?
> > Messages will just be incoming on arbitrary RPC threads. I suppose the
> > point of the message loop is just in case objects decided to do a bit
> > of message posting or sending? Am I right in thinking that that's all
> > it can be for? I suspect it could actually be removed for a typical
> > exe server containing just free threaded objects?

> >     if (bRun)
> >     {
> >          Module.StartMonitor();
> > #if  WIN32 WINNT >= 0x0400 & defined( ATL FREE THREADED)
> >         hRes =  Module.RegisterClassObjects(CLSCTX LOCAL SERVER,
> >             REGCLS MULTIPLEUSE | REGCLS SUSPENDED);
> >          ASSERTE(SUCCEEDED(hRes));
> >         hRes = CoResumeClassObjects();
> > #else
> >         hRes =  Module.RegisterClassObjects(CLSCTX LOCAL SERVER,
> >             REGCLS MULTIPLEUSE);
> > #endif
> >          ASSERTE(SUCCEEDED(hRes));

> >         MSG msg;
> >         while (GetMessage(&msg, 0, 0, 0))
> >             DispatchMessage(&msg);

> >          Module.RevokeClassObjects();
> >         Sleep(dwPause); //wait for any threads to finish
> >     }



> > > Oops, I'm not reading carefully it seems... I assumed you are using
> > > a COM object from a DLL, didn't read you are implementing it in an
> > > EXE server...

> > > Alright, the FTM  is  superfluous and can safely be removed. The
> > > server must be changed to free-threaded (CoInitializeEx with
> > > COINIT MULTITHREADED). Alternatively, you can write a class
> > > factory that instantiates only that object in the MTA (it is created
> > > in the main and only STA of your single-threaded server right
> > > now), but only do it if your server really needs to be single-
> > > threaded for the other objects it exposes...

> > > --

> =========================

> > > ============
> > > Alexander Nickolov
> > > Microsoft MVP [VC], MCSD

> > > MVP VC FAQ: http://www.mvps.org/vcfaq

> =========================

> > > ============



> > > > Hi

> > > > Here's the scenario:

> > > > EXE server with one COM object.

> > > > WinMain we have CoInitialize(NULL).

> > > > The COM object is an ATL one with a base class
> > > > CComObjectRootEx<CComMultiThreadModel>.

> > > > When this object is activated (externally) I think it just gets
> > > > instantiated in the default STA. Is that right?

> > > > However, this isn't my code, and the author has aggregated the FTM
>  in
> > > > an effort to stop deadlocks [?!] - he means server busy messages
>  due
> > > > to logical thread reentrancy I think. There are mutex operations
>  in
> > > > some of the COM exposed methods which I think are probably causing
>  the
> > > > blocking because he's not servicing the message loop during the
> > > > WaitForsingleObject and ReleaseMutex calls!

> > > > So, really - does this object get instantiated in the default STA
>  or
> > > > the MTA? And am I on the right lines? I think the FTM is
>  superfluous.
> > > > I think the lack of MsgWaitForMultiple is the problem.

> > > > Cheers and look forward to some answer to make me sane again!

> > > > Emma Middlebrook




Sun, 17 Jul 2005 02:27:54 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. Lifetime of EXE COM server that uses DLL COM server

2. Making Type Library for normal Windows DLL (not a COM server)

3. EXE COM Server Possible in C#?

4. Serialize access to COM exe Server (long)

5. Using one COM exe server within another

6. COM servers in EXE

7. COM EXE Server Registration?

8. COM exe server

9. Shutdown EXE COM Server

10. Using BSTR in COM Exe server

11. COM Exe Server locking...

12. Beep problem with COM EXE server after 30 minutes

 

 
Powered by phpBB® Forum Software