A thread can defer the handling of asynchronous exceptions by creating a must-complete section. A must-complete section is a section of code that cannot be safely interrupted; it must be allowed to complete its execution even if an asynchronous exception occurs while within its boundaries. For example, a must-complete section can be used:

Creating a must-complete section ensures that the execution of critical instructions will be completed and that resources will be cleaned up before the thread ends. When used in conjunction with a mutual exclusion (mutex) semaphore, a must-complete section also ensures that a thread will have exclusive access to a resource.

The boundaries of the must-complete section are defined by DosEnterMustComplete and DosExitMustComplete requests. While a thread is executing instructions in a must-complete section, the system will hold asynchronous exceptions, which include signal exceptions and asynchronous process terminations.

The system increments a counter each time DosEnterMustComplete is called, and decrements the counter when DosExitMustComplete is called. Any asynchronous exceptions that have been held are dispatched when the counter reaches 0. A count greater than 1 indicates the degree of nesting of the must-complete section. If DosExitMustComplete is called when the count is already 0, ERROR_ALREADY_RESET is returned.

The handling of synchronous system exceptions and user-defined exceptions is not deferred by the system. To defer the handling of these exceptions, a procedure typically registers an exception handler (by calling DosSetExceptionHandler) and initializes a local Raise Exception flag to 0 before entering the must-complete section. The flag is set to 1, and the information is stored, if the exception handler receives a synchronous exception that it wants to reraise later.

If the value of the raise exception flag is 0 after the thread exits from the must-complete section, then no exceptions occurred, and the thread continues its normal operation.

If the value of the flag is 1 after the must-complete section has been completed, then an exception occurred, and the thread must call DosRaiseException to raise the deferred exception for handling.

Note: A thread must not call a function that is outside the scope of the must-complete section (for example, a DLL routine), because an error in the called routine could cause the process to end without returning. Keep must-complete sections as short as possible.


[Back] [Next]