![]() |
Using IO Timeout and Interrupt on NTThis technical memo is a cautionary note on using NSPR's IO timeout and interrupt on Windows NT 3.51 and 4.0. Due to a limitation of the present implementation of NSPR IO on NT, programs must follow the following guideline:
NSPR IO on NTThe IO model of NSPR 2.0 is synchronous and blocking. A thread calling an IO function is blocked until the IO operation finishes, either due to a successful IO completion or an error. If the IO operation cannot complete before the specified timeout, the IO function returns with PR_IO_TIMEOUT_ERROR. If the thread gets interrupted by another thread's PR_Interrupt() call, the IO function returns with PR_PENDING_INTERRUPT_ERROR.On Windows NT, NSPR IO is implemented using NT's overlapped (also called asynchronous) IO. When a thread calls an IO function, the thread issues an overlapped IO request using the overlapped buffer in its PRThread structure. Then the thread is put to sleep. In the meantime, there are dedicated internal threads (called the idle threads) monitoring the IO completion port for completed IO requests. If a completed IO request appears at the IO completion port, an idle thread fetches it and wakes up the thread that issued the IO request earlier. This is the normal way the thread is awakened. IO Timeout and InterruptHowever, NSPR may wake up the thread in two other situations:These two errors are generated by the NSPR layer, so the OS is oblivious of what is going on and the overlapped IO request is still in progress. The OS still has a pointer to the overlapped buffer in the thread's PRThread structure. If the thread subsequently exists and its PRThread structure gets deleted, the pointer to the overlapped buffer will be pointing to freed memory. This is problematic. Canceling Overlapped IO by Closing the File DescriptorTherefore, we need to cancel the outstanding overlapped IO request before the thread exits. NT's CancelIo() function would be ideal for this purpose. Unfortunately, CancelIo() is not available on NT 3.51. So we can't go this route as long as we are supporting NT 3.51.The only reliable way to cancel outstanding overlapped IO request that works on both NT 3.51 and 4.0 is to close the file descriptor, hence the rule of thumb stated at the beginning of this memo. LimitationsThis seemingly harsh way to force the completion of outstanding overlapped IO request has the following limitations:
Note: A related known bug is that timeout and interrupt don't work for PR_Connect() on NT. This bug is due to a different limitation in our NT implementation. ConclusionsAs long as we need to support NT 3.51, we need to program under the guideline that after an IO timeout or interrupt error, the thread must make sure the file descriptor is closed before it exits. Programs should also take care in sharing file descriptors and using IO timeout or interrupt on files that need to stay open throughout the process.When we stop supporting NT 3.51, we can look into using NT 4's CancelIo() function to cancel outstanding overlapped IO requests when we get IO timeout or interrupt errors. If CancelIo() really works as advertised, that should fundamentally solve this problem. If these limitations with IO timeout and interrupt are not acceptable
to the needs of your programs, you can consider using the Win95 version
of NSPR. The Win95 version runs without trouble on NT, but you would
lose the better performance provided by NT fibers and asynchronous IO.
Last updated: Wed Jul 15 13:31:25 PDT 1998
|
|
|
Copyright © 1998-2000 The Mozilla Organization.
Last modified July 22, 1998. |
|