Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
platform
active.directory
adsi
adsi.iis-admin
base
com_ole
complus_mts
component_svcs
database
directx
gdi
graphics_mm
internet.client
internet.server
internet.server.isapi-dev
localization
mapi
messaging
msi
mslayerforunicode
multimedia
networking
networking.ipv6
sdk_install
security
shell
telephony.tapi_2
telephony.tapi_3
telephony.tsp
telephony.wte
tools
ui
ui_shell
win_base_svcs
win16
  
 
date: 3 Feb 2006 16:07:55 -0800,    group: microsoft.public.platformsdk.com_ole        back       


asynchronous-operation-managing object/thread architecture   
Hmm. After reading an article about threads/apartments/etc.
(http://www.codeproject.com/com/CCOMThread2.asp) I'm trying to muddle
through the possibilities for a COM server object S that manages a
shared resource (piece of hardware accessed through the serial port).
This will definitely be a standalone EXE server rather than a DLL.
(possibly on another machine as clients but probably on the same
machine)

Are there any good articles that talk about various the merits of
various COM server / apartment / thread architectures as they apply to
some common practical situations?

Back to my specific case, there will frequently be two clients in
simultaneous existence, possibly more.

The server must maintain state between client accesses, since the piece
of hardware may only be able to do a one-time handshake to exchange
some setup information (along with some other reasons which are hard to
explain briefly).

Each client must have the ability to engage in a lengthy,
exclusive-access operation with the server/hardware. (could be seconds,
could be minutes)

One client will be a scripting environment that has access to COM
IDispatch objects, where it is not possible to do multithreading (at
least not from the script's point of view) and it is not acceptible for
the COM object to block indefinitely unless the script really really
wants it to.

option a: S = STA server object. Pretends there's no such thing as
multithreading. Advantages: simple. Disadvantages: won't work. If
there's only one S, when it's servicing hardware & talking to one
client, it can block other clients indefinitely. If there are more than
one S, they will compete to maintain state... I get dizzy thinking
about a way this might be made to work.

option b: S is actually split into two types of objects defined in the
same EXE file. S0 = unique server object, and S1 = non-unique
"secretary" class to access S0. Both are STA. S0 does not talk to
clients (technically doesn't even have to be a COM object). There's a
mutex for the S1's to cooperate in accessing S0. S1's either tell
clients that requests to use S0 fail because S0 is busy, if a mutex is
in use, or they take the mutex and then relay methods to S0
accordingly, or if a client really wants to wait forever, S1 can block
until S0 is ready. Simple but adds an extra layer of communication, and
maybe it could lock up somehow in an abnormal situation...

option c: S is unique and MTA, and it uses all sorts of mutexes &
shared memory to serialize access. Blech.

option d: S is unique and STA, but it does not allow any blocking
calls. It can answer informational requests (like 'what's the
hardware's ID number?') immediately, but if something would require
communication over the serial report, it fires up a worker thread. It
only allows asynchronous methods which either return a failure code
because the hardware object is in use, or return some kind of
completion object Sc (also STA) that actually does the communication &
both tells the server S "Hey, here's what I'm doing, there's a state
change" & communicates with the client. (e.g. scripting client code
such as

Sc = S.AskHardwareSomething();
if (Sc.failed) { do something else, or try again later }
else { /* hurray! */ info = Sc.GetReply(timeout); }

or

Sc = S.AskHardwareSomethingWithTimeout();
if (Sc.WaitUntilComplete() == TRUE)
  info = Sc.GetReplyNow();
else
  { sulk; }

) Non-scripting clients could ask server S for events. (connection
points?)

This actually sounds similar to option B in a lot of ways.

All of the above use standard "dumb" proxies.

option e: Allow clients to use some kind of in-process smart proxy for
server S, because... I have no idea, maybe there's an advantage to it.
(Aside from being able to communicate quickly with the client & lump
requests together before the server is actually contacted.)

I think I'm leaning toward option D as it gives me the most flexibility
while still using simple STA stuff.

Are there gotchas I should be aware of when trying to make this stuff
work? Is there any reason to favor using an MTA object rather than STA
objects?
date: 3 Feb 2006 16:07:55 -0800   author:   Jason S

Re: asynchronous-operation-managing object/thread architecture   
Option c or d would work, although my preference is for c. When the first 
object accesses the hardware, it can set a "busy" boolean that is accessible 
to any other instantiated objects. These objects can return a "busy" HRESULT 
of your own creation if any methods are called when the first object is 
accessing the hardware.

I'm not sure what you mean when "S is unique". Avoid implementing a 
singleton, if that is what you are thinking. Permit each client to 
instantiate their own object. Since the objects live in the same process, 
they can share common resources by either using global variables or static 
class member variables.

Brian
date: Sat, 4 Feb 2006 14:33:52 -0800   author:   Brian Muth

Re: asynchronous-operation-managing object/thread architecture   
Brian Muth wrote:
> Option c or d would work, although my preference is for c. When the first
> object accesses the hardware, it can set a "busy" boolean that is accessible
> to any other instantiated objects. These objects can return a "busy" HRESULT
> of your own creation if any methods are called when the first object is
> accessing the hardware.
>
> I'm not sure what you mean when "S is unique". Avoid implementing a
> singleton, if that is what you are thinking. Permit each client to
> instantiate their own object. Since the objects live in the same process,
> they can share common resources by either using global variables or static
> class member variables.

Right, the "unique" statement was badly phrased. That really should
have been a unique non-COM object e.g. global variable, with
appropriate thread-synchronization mechanisms, wrapped by non-unique
COM accessors. (I took your sugg. last week on this topic for another
server & it worked quite well so far, thanks.)

This makes all these options even more similar.

What is the advantage of MTA over STA, to a COM object that is an
accessor to a shared non-COM singleton? I guess I am missing
something...

STA case: I have to instantiate each accessor object in a separate
thread. (Otherwise they will share apartments & block each other.) And
I'd have to use MsgWaitForMultipleObjects() instead of
WaitForSingleObject(), I think... Are these a big deal to implement? Or
is the point that if I have to be aware of these things anyway, I might
as well go to MTA since I can just do what I need to do to get my
desired synchronization behavior, instead of having to work around the
STA model to get an equivalent behavior?
date: 6 Feb 2006 07:03:30 -0800   author:   Jason S

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us