diff options
Diffstat (limited to 'docs/comm/rts-libs/non-blocking.html')
-rw-r--r-- | docs/comm/rts-libs/non-blocking.html | 133 |
1 files changed, 0 insertions, 133 deletions
diff --git a/docs/comm/rts-libs/non-blocking.html b/docs/comm/rts-libs/non-blocking.html deleted file mode 100644 index 627bde8d88..0000000000 --- a/docs/comm/rts-libs/non-blocking.html +++ /dev/null @@ -1,133 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> - <head> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> - <title>The GHC Commentary - Non-blocking I/O on Win32</title> - </head> - - <body BGCOLOR="FFFFFF"> - <h1>The GHC Commentary - Non-blocking I/O on Win32</h1> - <p> - -This note discusses the implementation of non-blocking I/O on -Win32 platforms. It is not implemented yet (Apr 2002), but it seems worth -capturing the ideas. Thanks to Sigbjorn for writing them. - -<h2> Background</h2> - -GHC has provided non-blocking I/O support for Concurrent Haskell -threads on platforms that provide 'UNIX-style' non-blocking I/O for -quite a while. That is, platforms that let you alter the property of a -file descriptor to instead of having a thread block performing an I/O -operation that cannot be immediately satisfied, the operation returns -back a special error code (EWOULDBLOCK.) When that happens, the CH -thread that made the blocking I/O request is put into a blocked-on-IO -state (see Foreign.C.Error.throwErrnoIfRetryMayBlock). The RTS will -in a timely fashion check to see whether I/O is again possible -(via a call to select()), and if it is, unblock the thread & have it -re-try the I/O operation. The result is that other Concurrent Haskell -threads won't be affected, but can continue operating while a thread -is blocked on I/O. -<p> -Non-blocking I/O hasn't been supported by GHC on Win32 platforms, for -the simple reason that it doesn't provide the OS facilities described -above. - -<h2>Win32 non-blocking I/O, attempt 1</h2> - -Win32 does provide something select()-like, namely the -WaitForMultipleObjects() API. It takes an array of kernel object -handles plus a timeout interval, and waits for either one (or all) of -them to become 'signalled'. A handle representing an open file (for -reading) becomes signalled once there is input available. -<p> -So, it is possible to observe that I/O is possible using this -function, but not whether there's "enough" to satisfy the I/O request. -So, if we were to mimic select() usage with WaitForMultipleObjects(), -we'd correctly avoid blocking initially, but a thread may very well -block waiting for their I/O requests to be satisified once the file -handle has become signalled. [There is a fix for this -- only read -and write one byte at a the time -- but I'm not advocating that.] - - -<h2>Win32 non-blocking I/O, attempt 2</h2> - -Asynchronous I/O on Win32 is supported via 'overlapped I/O'; that is, -asynchronous read and write requests can be made via the ReadFile() / -WriteFile () APIs, specifying position and length of the operation. -If the I/O requests cannot be handled right away, the APIs won't -block, but return immediately (and report ERROR_IO_PENDING as their -status code.) -<p> -The completion of the request can be reported in a number of ways: -<ul> - <li> synchronously, by blocking inside Read/WriteFile(). (this is the - non-overlapped case, really.) -<p> - - <li> as part of the overlapped I/O request, pass a HANDLE to an event - object. The I/O system will signal this event once the request - completed, which a waiting thread will then be able to see. -<p> - - <li> by supplying a pointer to a completion routine, which will be - called as an Asynchronous Procedure Call (APC) whenever a thread - calls a select bunch of 'alertable' APIs. -<p> - - <li> by associating the file handle with an I/O completion port. Once - the request completes, the thread servicing the I/O completion - port will be notified. -</ul> -The use of I/O completion port looks the most interesting to GHC, -as it provides a central point where all I/O requests are reported. -<p> -Note: asynchronous I/O is only fully supported by OSes based on -the NT codebase, i.e., Win9x don't permit async I/O on files and -pipes. However, Win9x does support async socket operations, and -I'm currently guessing here, console I/O. In my view, it would -be acceptable to provide non-blocking I/O support for NT-based -OSes only. -<p> -Here's the design I currently have in mind: -<ul> -<li> Upon startup, an RTS helper thread whose only purpose is to service - an I/O completion port, is created. -<p> -<li> All files are opened in 'overlapping' mode, and associated - with an I/O completion port. -<p> -<li> Overlapped I/O requests are used to implement read() and write(). -<p> -<li> If the request cannot be satisified without blocking, the Haskell - thread is put on the blocked-on-I/O thread list & a re-schedule - is made. -<p> -<li> When the completion of a request is signalled via the I/O completion - port, the RTS helper thread will move the associated Haskell thread - from the blocked list onto the runnable list. (Clearly, care - is required here to have another OS thread mutate internal Scheduler - data structures.) - -<p> -<li> In the event all Concurrent Haskell threads are blocked waiting on - I/O, the main RTS thread blocks waiting on an event synchronisation - object, which the helper thread will signal whenever it makes - a Haskell thread runnable. - -</ul> - -I might do the communication between the RTS helper thread and the -main RTS thread differently though: rather than have the RTS helper -thread manipluate thread queues itself, thus requiring careful -locking, just have it change a bit on the relevant TSO, which the main -RTS thread can check at regular intervals (in some analog of -awaitEvent(), for example). - - <p><small> -<!-- hhmts start --> -Last modified: Wed Aug 8 19:30:18 EST 2001 -<!-- hhmts end --> - </small> - </body> -</html> |