Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

OLE Automation, Events, Threads and "Input-Synchronous Calls"

3 views
Skip to first unread message

Warren Postma

unread,
Sep 21, 1999, 3:00:00 AM9/21/99
to

I have written a first version of an OLE Automation Client and Server objects
with Events, in delphi 4, developing in Windows NT 4.0, and using Binh Ly's
threaded comlib.pas code to help through the toughest parts.

My EXE server is a serial communications oriented server using the Async
Professional components from Turbo Power.

I also wrote a Client Component, which you drop on your client application's
form and just use it. The client sends a command or query (a string) to the
server ( MyClient.Execute('COMMAND') ), which the server then queues up until
the serial port is free, and it returns a handle for the client to hold onto,
then it does the protocol stuff, and then stores the resulting information
(packets coming back in the serial port) and then sends an event back to the
client object when the data has been received, along with a handle so that the
client can verify that this is the data it has been waiting for. The event
contains a string array, and in this way we pass the results back to the client.
If the client wishes, the data can be "polled" repeatedly and the handle helps
the client identify who owns the resultant data.

This allows several different client applications to make requests from this
slow serial device simultaneously. The requests are serialized in a queue of my
own creation. Because serial communications are slow (device connection speeds
on the various modems we use vary from 1200 bps to 33.6kbps) it's important that
the Server.Execute('command') returns a handle (an integer) and that an event is
fired when the command has been executed.

I initially thought of a design using named pipes or sockets, and not using COM
at all, but I actually have a complex COM interface now with 20 events and 30 or
so different commands, not just the Execute command, and the Results event. So
I'd like to stay with COM now, but I'm having problems.

My serial communications components (Async Professional, from Turbo Power
Software) give me results through standard Delphi VCL event notifications (a
callback, basically). From inside these Callbacks, I'm calling Binh Ly's
implementation of an IConnectionPointContainer which notifies all connected
parties of things like a connection being dropped, or some other error
condition, or of new data being available to read, etc. The
IConnectionPointContainer implementation iterates through the list of connected
parties and tries to call them with IDispatch.Invoke(...), which fails with the
following error:

"An outgoing call cannot be made since the application is dispatching an
input-synchronous call."

The HResult from IDispatch.Invoke is $8001010D and this means that it was an
error from the RPC facility, and the error code
is defined as RPC_E_CANTCALLOUT_ININPUTSYNCCALL

Is this likely caused because AsyncPro is calling my event code from inside it's
own thread context? If so could this error be caused when that thread context
not initialized for COM to use?

Should I set up some kind of marshalling?

My own quick hack was to manually serialize using a PostMessage() type hack. The
problem is I have 20 events to handle, and I have a feeling that posting 20
different things into a message queue, and then manually decoding the incoming
messages from the queue, and then calling COM I would be going around the
procedure that COM would intend me to use.

Any ideas what I should do?

Warren


John Romedahl

unread,
Sep 21, 1999, 3:00:00 AM9/21/99
to
I had the exact same problem (iterating a ConnectionPoint from within an
AsyncPro-Event )

It took me a day before I figured out that this was the reason :-(
I to created a windows, and posted messages from the AsyncPro event.

I hope someone here can show a better way

regards John

Binh Ly

unread,
Sep 22, 1999, 3:00:00 AM9/22/99
to
Your problem is not in Async Pro nor any COM threading issue. It's simply a
limitation in COM. I suspect Async Pro somehow uses windows messages (or a
message queue) to trigger events to the Async components.

If that's the case, whenever you receive an event from Async Pro, and then
make a COM call out from your object, COM will normally ensure that you
don't make a synchronous call that can possibly block because while you're
making the call, COM will allow and process pending messages in your
object's apartment (that may include messages coming in from Async Pro). If
your object makes a blocking call that may take a while, that will probably
disrupt your serial data processing because your object might process
incoming data while it's still making a call to the client.

The solution as you've found is to post a message to yourself and make the
outgoing call later. You don't have to post to a single main thread. You can
also create additional secondary threads and use the PostThreadMessage call
and handle them as if you were handling normal windows messages.

If you want further info in input-synchronized calls in COM, check out
Inside OLE 2 by Kraig Brockshmidt.

have fun
--
Binh Ly
Visit my COM Notes at http://www.castle.net/~bly/com


Warren Postma <em...@geocities.com> wrote in message
news:7s8fth$17...@forums.borland.com...

0 new messages