> [ long win32 proposal ] > > I've to read through that some more times.
OK; let me know if you have any questions on how the Win32 stuff works. I tried to explain things that are unlike POSIX, but of course it makes sense to me. > Do you alread have ideas for a common API, or where to split the > existing threads.c into platform and common code? I didn't see anything in thread.c that was platform specific -- or at least nothing that looked like it wouldn't work on Win32. Obviously thr_win32.h will be much different than thr_pthreads.h. As for a common API, I suppose we would have to figure out how the modules would interact. In the case of IO (any function names I made up have capital letters to distinguish them from anything that may be in the current codebase): * There is some generic IO code that sets up IO and event objects, and it sits below the buffering layer. All this stuff is going to be thread-safe so the low-level IO code shouldn't have to worry about it. This generic IO code sets up the IO and Event objects indicating what file, which operation (read/write/lock/unlock), what to do when the operation completes, how many bytes, file position, and any memory buffer needed. Then it would pass this information to the OS-specific code. So this generic code (say, StartIO()) would create an IO object that contains the file object, a pointer to the r/w buffer if the operation requires it, and a file position and byte count if the operation uses it. It would also contain an event object indicating what to do in case of failure or completion. StartIO pins the memory buffer, locks the IO object, and calls Win32AsyncRead or whatever. The XXXAsyncYYY funtcion starts the IO and returns to StartIO which unlocks the IO object and returns it to the caller. That can then be passed into functions to find out if it's complete, cancel it, etc. If XXX is Win32, the module would just start Read/WriteFile; if it's Solaris, maybe it'll call aioread/write; if it's POSIX without aio (e.g. Linux), it'll start up a new thread to do a blocking read/write. When the IO completes, the XXX code figures out the return code and how many bytes read/written. This information is passed to the generic CompleteIO(), which locks the IO object, updates the status (return code, byte count), unpins the buffer, dispatches the event as described by the Event object, and unlocks the IO object. * In the case of timers, there would be XXXCreateTimer and XXXCancelTimer, while the XXX code would need to call FireTimer(). * I suppose there should be an XXXQueueEvent function as well, but I'm not certain of its uses. Actual EventDispatch() would be a generic function that puts an event into a thread's queue and notifies the thread. I am not sure how to handle general events like RunGC. * GUI message handlers need to dispatch events synchronously. So the generic check_events function would call XXXGetGUIMessages which would need to dispatch the messages to whatever registered for them in that thread. Since this would amount to method dispatch instead of event dispatch, it would probably need something special for this. GNS