More DCOM notes
rob at codeweavers.com
Sat Jan 22 16:29:54 CST 2005
Mike Hearn wrote:
>Here are some more notes in a convenient to read form. I'll turn these
>into a documentation patch later. Rob, can you double-check this?
>This document assumes you are familiar with the basics of DCOM. If you
>aren't read this first:
>This is not suitable study material for beginners. Don't say I didn't
>Before a thread can use COM it must enter an apartment. Apartments are
>an abstraction of a COM objects thread safety level. There are many
>types of apartment but the only two we care about right now are single
>threaded apartments (STAs) and the multi-threaded apartment (MTA).
>Any given process may contain at most one MTA and potentially many STAs.
You might want to add something like this:
This is because all objects in MTAs never care where they are invoked
from and hence can all be treated the same. Since objects in STAs do
care, they cannot be treated the same.
>The apartment system was originally designed to deal with the disparity
>between the Windows NT/C++ world in which threading was given a strong
>emphasis, and the Visual Basic world in which threading was barely
>supported and even if it had been fully supported most developers would
>not have used it. Visual Basic code is not truly multi-threaded, instead
>if you start a new thread you get an entirely new VM, with separate sets
>of global variables. Changes made in one thread do NOT reflect in
>another, which pretty much violates the expected semantics of multi-
>threading entirely but this is Visual Basic, so what did you expect?
Remove the "so what did you expect?" as this is a bit too hostile.
>you access a VB object concurrently from multiple threads, behind the
>scenes each VM runs in a STA and the calls are marshaled between the
>threads using DCOM.
>In the Windows 2000 release of COM, several new types of apartment were
>added, the most important of which are RTAs (the rental threaded
>apartment) in which concurrent access are serialised by COM using an
>apartment-wide lock but thread affinity is not guaranteed.
Do we have any details about how you use RTAs? I have a feeling this was
something that was due to be implemented for Windows 2000, but was
dropped before it shipped.
>After the SORF flags comes a count of the references represented by this
>marshaled interface. Typically this will 1 in the case of a normal
>marshal, but may be 5 for table-strong marshals and 0 for table-weak
>marshals (the difference between these is explained below).
This is wrong. It is 5 for normal marshals, and 0 for both table-weak
The reasoning is this:
In the general case, we want to know exactly when an object is
unmarshaled and released, so we can accurately control the lifetime of
the stub object. This is what happens when cPublicRefs is zero. However,
in many cases, we only want to unmarshal an object once. Therefore, if
we strengthen the rules to say when marshaling that we will only
unmarshal once, then we no longer have to know when it is unmarshaled.
Therefore, we can give out an arbitrary number of references when
marshaling and basically say "don't call me, except when you die."
>Unmarshaling one of these streams therefore means setting up a
>connection to the object exporter (the apartment holding the marshaled
>interface pointer) and being able to send RPCs to the right ifstub. Each
>apartment has its own RPC endpoint and calls can be routed to the
>correct interface pointer by embedding the IPID into the call using
>RpcBindingSetObject. IRemUnknown, discussed below, uses a reserved IPID.
Only in the implementation I've written and am currently testing now.
The native version generates an IPID as per any other object and simply
notifies the SCM of this IPID.
>There is one IRemUnknown implementation per apartment, not per stub
>manager as you might expect. This is OK because IPIDs are apartment not
In fact, according to the DCOM draft spec, they are machine-scoped, but
this implies apartment-scoped.
Other than that, it looks good!
More information about the wine-devel