DosExitList (OS/2 1.x)

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:
 * 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: 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.
 * EXIT (normal exit)
 * Hard error abort
 * Trap operation
 * Unintercepted DosKillProcess.

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.

C

 * 1) 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 */ 

MASM
 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 

Example
In this example, TestRoutine is added to the exitlist sequence. Routines in the exitlist sequence must use DosExitList instead of DosExit to end. 
 * 1) define INCL_DOSPROCESS
 * 2) define INCL_VIO
 * 3) define ROUTINE_ORDER 0xEE00
 * 4) 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 */ } 