[libdispatch-dev] libdispatch for Win32
DrPizza
DrPizza at quiscalusmexicanus.org
Fri Apr 22 20:07:19 PDT 2011
So, I've got the basics working tolerably well. Is this something that people
care about/want source for?
What I've done so far is as follows:
Get most of the code building properly in VC++ 2010:
* Replace C99 named initializers with old-fashioned aggregate initializers.
* Replace gcc typeof with real type names.
* Replace gcc's fancy macros with less fancy standard C89 ones.
* VC++ has no equivalent (AFAIK) to gcc's transparent_union, so insert
casts as necessary.
* Minor bits and pieces like get rid of the ?: gccism.
* Provide minimal Win32 equivalents to missing UNIX headers that seem
necessary.
Blocks:
* Only Microsoft is in a position to produce built-in block support for
VC++ and I'm sure as hell not going to write a source-source translator.
Instead, I have a C++ lambda wrapper that works in conjunction with the
_f function variants. This seems more than enough for most purposes.
Port pthread_workqueues to Win32:
* Built on top of "new-style" (Vista and up) Win32 threadpools.
* Reasonably complete.
* Reasonably inadequately tested.
Rework dispatch_sources:
* The Windows overlapped I/O model is better than the traditional UNIX one,
but doesn’t readily support:
DISPATCH_SOURCE_TYPE_READ
DISPATCH_SOURCE_TYPE_WRITE
* And Windows in general doesn't have any good analogues to:
DISPATCH_SOURCE_TYPE_VNODE
DISPATCH_SOURCE_TYPE_SIGNAL
DISPATCH_SOURCE_TYPE_PROC
DISPATCH_SOURCE_TYPE_MACH_RECV
DISPATCH_SOURCE_TYPE_MACH_SEND
* But what I do have instead is initial support
DISPATCH_SOURCE_TYPE_OIO (for "overlapped I/O")
example: https://gist.github.com/938097
* Overlapped I/O supports files, sockets, named pipes, and more. All of
these need testing.
* The loss of READ/WRITE/SIGNAL/MACH_* is no big deal on Windows, as they
don't really fit into Win32 anyway. Only one PROC feature (EXIT)
translates into Win32, and I'm not seeing any clearly compelling reason
to replicate it, as it doesn't seem especially useful. However, the loss
of VNODE is unfortunate, as it both have interesting features. But this
may not be fatal. ReadDirectoryChangeNotificationsW supports overlapped
I/O, so should plumb into my existing DISPATCH_SOURCE_TYPE_OIO with no
changes anyway, though the interface will not be quite as tidy.
* I still need to test:
DISPATCH_SOURCE_TYPE_DATA_ADD
DISPATCH_SOURCE_TYPE_DATA_OR
* I need to fix:
DISPATCH_SOURCE_TYPE_TIMER
I ripped out part of the machinery to make the code clearer temporarily;
now I need to add it back.
* I also need to examine the ins and outs of cancellation and suspension
and so on and so forth. Win32 doesn't allow a handle to be detached from
an IOCP except by closing the handle, so there are some sadnesses there.
I'm not sure how much impact they'll have in practice, possibly none.
* I am toying with the idea of something along the lines of
DISPATCH_SOURCE_TYPE_WAITABLE, which would perform a wait on any Win32
waitable object (so mutex, event, waitable timer handles, amongst others)
and dispatch a message to a queue when that wait occurs. This would give
us back the one PROC scenario that makes sense in Win32, too, as you can
wait on a process handle, and the wait resumes when the process
terminates. Due to the annoying traits of WaitForMultipleObjects (it's
limited to 64 HANDLEs), however, this might be a little awkward to
implement without moving to a rather wasteful thread-per-wait model.
* There are almost certainly memory leaks, bugs, etc.. My focus has been on
validating the general approach more than writing a bunch of test cases.
Main queues:
* From my understanding of Mac OS X, Windows has no real meaningful
equivalent of Cocoa's blessed main queue. Any thread can have a message
pump and associated windows, which it's then responsible for drawing,
etc.. Processes have an M:N model (M threads, controlling N windows),
with each window being affinitized to its own thread.
* However, the ability to post a message back into a window's message loop
is obviously invaluable, so I want to create as close a workalike as
makes sense in Win32. Something that captures the spirit, if not the
exact same API. I've not yet written any code for this, but my plan of
action is to do something along these lines:
1) allow creation of serial queues bound to an HWND or HWNDs.
Callbacks posted to these queues will be pumped into the WndProc
one-by-one.
2) Either a WndProc hook or a helper function (or both) to respond to
the callbacks posted to the WndProc and execute them.
3) Possibly some convenience helpers to allow the retrieval of a
queue given an HWND and so on.
Distant future:
* There would be certain benefits to ripping out the pthread_workqueues and
using the new-style Win32 threadpools directly. The Win32 threadpools
directly support timers, so they might allow DISPATCH_SOURCE_TYPE_TIMER to
be moved off the dispatch_mgr queue/thread. Likewise, they directly
support overlapped I/O, so might allow DISPATCH_SOURCE_TYPE_OIO to be
moved off the dispatch_mgr thread too. They also directly support
waits on handles, which would greatly simplify
DISPATCH_SOURCE_TYPE_WAITABLE (if I do indeed go down that route).
So the advantages would be many--but I am wary of diverging too far from
the existing source, which is why thus far I've implemented
pthread_workqueues instead; it was the easy solution.
* Going in the opposite direction, some might prefer switching to Windows
2000-style thread pools, so as to support Windows XP instead. This would
work (and I think someone on the list mentioned that they had implemented
pthread_workqueue on that API already), but it also means eliminating the
possibility of the streamlined implementations described above.
Source code:
My plan was to dump it into my github, if people find the whole thing
interesting, though I was going to wait until I'd fixed timer sources,
since they're rather important.
Peter
More information about the libdispatch-dev
mailing list