Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 May : Re: Making server interact with GUI

www.cryer.info
Managed Newsgroup Archive

Re: Making server interact with GUI

Subject:Re: Making server interact with GUI
Posted by:"Martin James" (mjames_falc..@dial.pipex.com)
Date:Thu, 11 May 2006 18:30:43

>
> I can't just call context.connection.IOHandler.write in the button
> event, because that would block the GUI.

The write call would only block if the write call could not be completed
immediately, ie. the link was down and the write buffer space is full.

> Surely I want to do the writing in the same thread that the reading is
> done in.

With Indy, maybee not :(

>  How can I achieve this?

I'm not surprised that you are having a problem with this - you are by no
means the first.  There are several possiblities, none of them ideal:

a) Write directly from the main thread/form event-handler to the context.
Easy, straightforward and might block :(

b) Queue the send data to the peer thread that is bound to the client,
either by directly storing it on some sort of thread-safe list, or storing
it in an object/record and queueing that in a thread-safe queue.  The
problem is, as you know, that the peer thread is stuck on a blocking read
call and cannot dequeue the data to send it.  There are sub-possibilities
for handling this:

    i)  Use a short timeout on the read call and poll the queue.  Fairly
simple, easily implemented.  Wastes CPU and adds latency, in proportions
dependent on the read timeout :(

    ii) Turn the blocking socket into an non-blocking one and wait on both
the socket and a an OS synchro-object, (eg. event, semaphore), associated
with the queue.  This removes the CPU-waste and latency,  has been done, and
appears to work OK, but starts to introuduce non-Indy-like state-machines to
handle the reads and writes :(

c) Queue the send data, and context, (possibly in a 'write class' instance
that contains the context, data and calls to do the write), to a completely
seperate thread, or small pool of threads, that then perform the writes.
This works OK but is more complex and requires a producer-consumer queue for
the write thread/s to wait on for data.  Another problem is that the system
can only stand as many blocked write calls as there are write threads in the
pool, after which writes to clients that are still writeable will just queue
up because there are no write threads left.

d) Whatever other solution that Remy will doubtless come up with :)

>  Seems to me like I want to send a
> message back to the thread, but I'm not sure where to get the threadID
> or how to trap that message within the thread object.  Or am totally
> barking up the wrong tree?

I'm afraid that Indy servers bark a bit when asked to do unsolicited writes
to clients <g>

Rgds,
Martin

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive