DevHlp Block: Difference between revisions
No edit summary |
|||
(One intermediate revision by the same user not shown) | |||
Line 15: | Line 15: | ||
:0 - Block is interruptible | :0 - Block is interruptible | ||
: 1 - Block is noninterruptible | : 1 - Block is noninterruptible | ||
;''&Error'' ( | ;''&Error'' (FARPOINTER): Far Pointer to error returned | ||
: 1 - Block timed out | : 1 - Block timed out | ||
: 2 - Block interrupted by control-C | : 2 - Block interrupted by control-C | ||
==Remarks== | ==Remarks== | ||
Line 32: | Line 31: | ||
==Example Code== | ==Example Code== | ||
if (Block(WriteID,blockcount, 0, &err)) | if (Block(WriteID,blockcount, 0, &err)) | ||
if (err == 2) // interrupted | if (err == 2) // interrupted | ||
return(RPDONE|RPERR|ERROR_CHAR_CALL_INTERRUPTED); | return(RPDONE|RPERR|ERROR_CHAR_CALL_INTERRUPTED); |
Latest revision as of 15:25, 22 May 2025
Block This Thread From Running
The Block DevHlp blocks the current requesting thread and removes it from the run queue until it is released by a call to the Run DevHlp.
- Block Mode
- Kernel
Syntax
Block(BlockID, Timeout, Flag, &Error)
Parameters
- BlockID (ULONG) - input
- ID used for Block and subsequent Run
- Timeout (ULONG) - input
- Timeout in milliseconds or -1L Block forever
- Flag (USHORT)- input
- 0 - Block is interruptible
- 1 - Block is noninterruptible
- &Error (FARPOINTER)
- Far Pointer to error returned
- 1 - Block timed out
- 2 - Block interrupted by control-C
Remarks
The return from the Block call indicates whether the wake-up occurred as the result of a Run DevHlp call or an expiration of the time limit. Block removes the current thread from the run queue, allowing any other waiting threads to run. The thread blocked in the device driver is reactivated and Block returns when Run is called with the same event identifier, when the time limit expires, or when the thread is signalled. The event identifier is an arbitrary 32-bit value, but an acceptable convention is to use the address of the Request Packet that made the request.
Since the device driver may be Blocked in one mode and Run in the other, using the address of the Request Packet is the best choice, as this bimodal address is valid in either mode. It is up to the device driver writer to insure that the Block was woken up by the correct mechanism, and not accidentally. To avoid a deadlock condition by getting a Run before the Block call is completed, the device driver should disable interrupts before issuing the Block. The Block DevHlp re-enables the interrupts.
A timeout value of -1 means that Block waits indefinitely until Run is called. Only the Strategy sections of the device driver can call Block, but Run can be called by the Strategy section, interrupt handler, or timer handler. When using Block to block a thread, the device driver can specify whether or not the Block may be interrupted. If the Block is interruptible, then the kernel can abort the blocked thread and return from the Block without using a corresponding Run. In general, the Block should be marked as interruptible so that a signal such as a control C will UnBlock the thread.
The Block call will return when the thread has been run, when the timeout has expired, or if the thread was UnBlock by a signal, such as a control C. If the Block returns with a 1, the Block has timed out. If the Block returns a 2, the Block was interrupted. If the Block returns a 0, or valid return, then the Block was released by a call to the Run DevHlp, and the device driver should take the appropriate action.
Example Code
if (Block(WriteID,blockcount, 0, &err)) if (err == 2) // interrupted return(RPDONE|RPERR|ERROR_CHAR_CALL_INTERRUPTED); if (err == 1) return (RPDONE|RPERR|ERROR_NOT_READY);