DosExitList (OS/2 1.x)
Description
This call maintains a list of routines that execute when the current process ends.
Syntax
DosExitList (FcnCode_Order, RtnAddress)
Parameters
- FcnCode_Order (USHORT) - input
- Two-byte fields. The low-order byte indicates the operation being performed by DosExitList, which can be used to update the list of routines, or to transfer to the next address on the termination list at the completion of a routine. The values of the byte and their meanings are:
Value Definition 1 Add address to termination list. 2 Remove address from termination list. 3 Transfer to next address on termination list.
The high-order byte indicates the invocation order. This value is valid only when the low-order byte is 1 (add an address). For the other low-order byte values, the high-order byte must be set to zero.
The invocation order determines the order in which routines are invoked. Routines given a value of 0 are invoked first and routines with a value of 255 are invoked last. If more than one routine is added with the same invocation order value, the last routine to be added is invoked first. The following values are used by OS/2 components:
Value Definition 80H-88H OS/2 Extended Edition Database Manager 90H-98H OS/2 Extended Edition Communications Manager A0H-A8H OS/2 Presentation Manager B0H OS/2 KBD component C0H OS/2 VIO component D0H OS/2 IPC Queues component
- RtnAddress (PFNEXITLIST) - input
- The address of a routine to be executed. This address cannot be in an IOPL segment.
Return Code
rc (USHORT) - return
Return code descriptions are:
- 0 NO_ERROR
- 8 ERROR_NOT_ENOUGH_MEMORY
- 13 ERROR_INVALID_DATA
Remarks
DosExitList maintains a list of addresses to routines that receive control when a process is terminated. These addresses must be in the address space of the terminating process. DosExitList routines perform clean-up operations on resources. For example, DosExitList can be used in a dynamic link library module to free resources and semaphores after a client program has ended.
During DosExitList processing, the process is in a state of partial termination. All threads of the process are terminated, except for the one executing the routines. Ownership of any exclusive semaphores created by the process with DosCreateSem was transferred to the DosExitList thread, so the thread can access protected resources. Termination routines should be short and fail-safe, so there is minimum delay in completing process termination.
Before transferring control to the termination routines, OS/2 resets the stack to its initial value. Transfer is by way of a JMP instruction. The first parameter on the stack (located at SS:SP+4) contains an indicator of why the process ended. The meanings of values returned are the same as those for termination codes returned by DosCwait or DosExecPgm requests. These values are:
- EXIT (normal exit)
- Hard error abort
- Trap operation
- Unintercepted DosKillProcess.
Each routine on the list receives control in numeric order by function high-order byte. For example, low (0) is first with high (0FFH) being last. In case of duplicate entries for the same value, the routines are executed in LIFO order.
When a routine has completed its processing, it issues DosExitList with function = 3. Control is then transferred to the next address in the invocation order. If a routine on the list does not issue DosExitList at the completion of its processing, the process hangs, and OS/2 prevents termination. When all addresses are serviced, the process completes exiting.
Most OS/2 system calls are valid in a DosExitList routine; however, certain functions such as DosCreateThread and DosExecPgm are not. Functions requested in a routine must not be higher in the function code order hierarchy than the invocation order specified for the routine.
Example Code
C Binding
#define INCL_DOSPROCESS USHORT rc = DosExitList(FcnCode_Order, RtnAddress); USHORT FcnCode_Order; /* Function request code/Order */ PFNEXITLIST RtnAddress; /* Address of routine */ USHORT rc; /* return code */
In this example, TestRoutine is added to the exitlist sequence. Routines in the exitlist sequence must use DosExitList instead of DosExit to end.
#define INCL_DOSPROCESS #define INCL_VIO #define ROUTINE_ORDER 0xEE00 #define VIO_HANDLE 0 USHORT rc; VOID APIENTRY TestRoutine2() { USHORT r; VioWrtTTY("This runs last...\n", /* String to be written */ 18, /* Length of string */ VIO_HANDLE); /* Video handle */ r = DosExitList(EXLST_EXIT, /* Function request code/order */ (PFNEXITLIST) TestRoutine2); /* Address of routine */ } main() { rc = DosExitList(EXLST_ADD | ROUTINE_ORDER, /* Function request code/order */ (PFNEXITLIST) TestRoutine2); /* Address of routine */ }
MASM Binding
EXTRN DosExitList:FAR INCL_DOSPROCESS EQU 1 PUSH WORD FcnCode_Order ;Function request code/Order PUSH DWORD RtnAddress ;Address of routine CALL DosExitList Returns WORD