[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Events lib and Win32
- From: Wim Couwenberg <debosberg@...>
- Date: Sun, 27 Jun 2004 11:19:33 -0700 (PDT)
By his request I cc a private mail to Mike Pall to the
list. It's about some Win32 issues that might play a
role in an events lib that Mike and Diego are putting
together. FYI
--
Wim
Hi Mike and Diego,
your event efforts are much needed. I know I've been
thinking about a win32 version off and on so I hope
you can help me out!
Just some comments from the Win32 world to help you
form a picture of what is going on (I leave the
details for now, though I'm willing to discuss those
of course.)
1. Waitable objects
2. Event categories?
3. Events and Message queues (relevant for the UI
thread)
4. Events vs. overlapped I/O
5. Sockets and events
1. Just like David Burgess pointed out a useful event
lib for win32 should only rely on waitable objects,
represented by the HANDLE type in Win32. Other
interesting types like file descriptors, sockets, etc.
can only be used sensibly if you map them to a
waitable HANDLE object. There are several ways to do
these mappings. I'll sketch some possibilities below.
There is a fairly convenient set of waitable objects
in Win32: mutex, event (condition), semaphore, thread,
process, timer and more. The equivalents of a
"select" call are the "WaitForMultipleObjects" and
"MsgWaitForMultipleObjects" calls in Win32. Both
block until a waitable object becomes signalled (or a
message is pending, see below.) However, in contrast
to select, these calls only report one event at a time
(it is possible to then iterate over and probe all
events without blocking, a bit like
pthread_mutex_trylock.)
2. Waitable objects can not be simply categorised
into
read/write/exception/timer events. For example,
waiting for a synchronisation object (mutex,
semaphore, event) does not logically fall into any of
these categories (waiting for a thread is more or less
equivalent to a pthread_join call.) Another example
is a directory change notification object that can
signal a range of interesting events in a directory
(tree.) This implies that an event lib should not
rely on such a categorisation but concentrate solely
on the concept of an event as "something happened" and
leave the interpretation to the respective event
objects / handlers.
3. If you want to use events in an application's main
thread then the event iterator should include arrival
of messages in the thread's queue. This event is not
represented by some waitable object but requires using
a MsgWaitForMultipleObjects call to wait for objects
to become signalled and reports pending messages
through its return value. Personally I dislike the
use of events in the main thread, but it is an issue
nonetheless.
4. To complicate things, events in Win32 are
sometimes coupled to a pending activity. This is most
obvious in the concept of "overlapped I/O." Instead
of waiting for an event "data available" and then
doing a read or receive (as in the socket select
scheme) overlapped I/O works the other way around:
you do an overlapped read/receive and then wait for
the "data available" event for this specific activity.
Overlapped I/O is available for file, pipe and socket
I/O (at least, there may be others.) So overlapped
I/O does not strictly match the "select" paradigm.
For file handles, overlapped I/O is the only way to
make a distinction between read/write events on the
handle. Two scenarios exist for overlapped I/O:
"manual" and "completion routines." The "manual"
scenario means that you wait for an overlapped event
signal and then take some action. A completion
routine is a callback function that is called
automatically if the thread enters an "alertable" wait
state. This means that completion routines are called
(if data was sent/received) implicitly and before a
wait function returns. The
implicit character of completion routines make them
less suitable for an event system where events are
typically decoupled from their interpretation (that is
only invoked explicitly.) This again hints at
separation between an event and its interpretation,
even in the read/write categories.
5. Finally (for now at least) sockets allow two ways
to be mapped onto an event object (a bit like a
pthread condition): through a WSAEventSelect call or
through overlapped I/O. The overlapped I/O option
initiates an actual send/receive activity without
blocking and you can wait for its completion,
signalled by a specified event object. Overlapped I/O
on sockets is done through WSARecv and WSASend.
WSAAccept does not support overlapped operation
however (because it does not involve read/write?) The
other option more closely resembles the select
approach: with WSAEventSelect you can associate an
event object with a socket and the event object
becomes
signalled if certain specified socket conditions are
met. These conditions include read/write/accept and
more. A socket can only be bound to a single
event object. You can probe the actual socket
conditions with a call to WSAEnumSocketEvents. There
is also a WSAAsyncSelect call but it should be
avoided as it relies on the message queue to signal
events and it does not fit in with the general event
approach.
I hope this helps a bit. You see that there are many
ways to go about. Further discussions are more than
welcome!
Bye,
Wim
__________________________________
Do you Yahoo!?
Yahoo! Mail is new and improved - Check it out!
http://promotions.yahoo.com/new_mail