DosExitList: Difference between revisions
mNo edit summary |
|||
(3 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Keeps a list of routines that run when the current process ends. | Keeps a list of routines that run when the current process ends. | ||
==Syntax== | ==Syntax== | ||
DosExitList (ordercode, pfn) | |||
==Parameters== | ==Parameters== | ||
; ordercode (ULONG) - input : DosExitList action and invocation order. | ;ordercode (ULONG) - input : DosExitList action and invocation order. | ||
:ordercode contains two one-byte fields in the low-order word. The high-order word is zero. | |||
ordercode contains two one-byte fields in the low-order word. The high-order word is zero. | :The low-order byte of the low-order word indicates which action DosExitList performs. This function can update the list of routines or transfer to the next address on the termination list at the completion of a routine. The values of the byte and their meanings are as follows: | ||
::1 EXLST_ADD Add an address to the termination list. | |||
The low-order byte of the low-order word indicates which action DosExitList performs. This function can update the list of routines or transfer to the next address on the termination list at the completion of a routine. The values of the byte and their meanings are as follows: | ::2 EXLST_REMOVE Remove an address from the termination list. | ||
::3 EXLST_EXIT When termination processing completes, transfer to the next address on the termination list. | |||
The high-order byte of the low-order word 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 of the low-order word must be set to zero. | The high-order byte of the low-order word 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 of the low-order word must be set to zero. | ||
The invocation order indicates where the routine address is to be placed in an ordered list. This list determines the order in which the exit list routines are invoked. Routines with 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: | The invocation order indicates where the routine address is to be placed in an ordered list. This list determines the order in which the exit list routines are invoked. Routines with 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: | ||
{| | |||
|0x80 - 0x88||OS/2 Extended Edition Database Manager | |||
|- | |||
|0x90 - 0x98||OS/2 Extended Edition Communications Manager | |||
|- | |||
|0xA0 - 0xA8||OS/2 Presentation Manager | |||
|- | |||
|0xB0||OS/2 Keyboard (KBD) component | |||
; pfn (PFNEXITLIST) - input : The address of a routine to be run. | |- | ||
|0xC0||OS/2 Video (VIO) component | |||
|- | |||
|0xD0||OS/2 Interprocess Communication (IPC) Queues component | |||
|} | |||
;pfn (PFNEXITLIST) - input : The address of a routine to be run. | |||
==Return Code== | ==Return Code== | ||
ulrc (APIRET) - returns | ulrc (APIRET) - returns | ||
DosExitList returns one of the following values: | DosExitList returns one of the following values: | ||
* 0 NO_ERROR | |||
* 0 | * 1 ERROR_INVALID_FUNCTION | ||
* 1 | * 8 ERROR_NOT_ENOUGH_MEMORY | ||
* 8 | *13 ERROR_INVALID_DATA | ||
* 13 | |||
==Remarks== | ==Remarks== | ||
Line 67: | Line 51: | ||
When the exit list routine receives control, the first parameter on the stack (located at ESP+4) contains a termination code that describes why the process ended. The values of the termination codes are as follows: | When the exit list routine receives control, the first parameter on the stack (located at ESP+4) contains a termination code that describes why the process ended. The values of the termination codes are as follows: | ||
0 TC_EXIT Normal exit | |||
1 TC_HARDERROR Hard-error halt | |||
2 TC_TRAP Trap operation for a 16-bit child process | |||
3 TC_KILLPROCESS Unintercepted DosKillProcess | |||
4 TC_EXCEPTION Exception operation for a 32-bit child process | |||
When the exit list routine receives control, all system semaphores owned by the process have their ownership transferred to the thread that performs exit list processing. This allows the thread to request serialization semaphores without danger of blocking in case the semaphore was held by another thread in the process that has already ended. | When the exit list routine receives control, all system semaphores owned by the process have their ownership transferred to the thread that performs exit list processing. This allows the thread to request serialization semaphores without danger of blocking in case the semaphore was held by another thread in the process that has already ended. | ||
Line 89: | Line 62: | ||
==Example Code== | ==Example Code== | ||
This example adds an exit routine named "ExitRtn1" to the exit-list sequence. Routines in this sequence must use DosExitList instead of DosExit to end. | This example adds an exit routine named "ExitRtn1" to the exit-list sequence. Routines in this sequence must use DosExitList instead of DosExit to end. | ||
<PRE> | <PRE> | ||
#define INCL_DOSPROCESS /* Process and thread values */ | #define INCL_DOSPROCESS /* Process and thread values */ | ||
#define INCL_DOSERRORS /* DOS error values */ | #define INCL_DOSERRORS /* DOS error values */ | ||
Line 136: | Line 108: | ||
return; | return; | ||
} | } | ||
</PRE> | </PRE> | ||
==Related Functions== | ==Related Functions== | ||
* [[ | *[[DosCreateThread]] | ||
* [[ | *[[DosExecPgm]] | ||
* [[ | *[[DosExit]] | ||
* [[ | *[[DosKillProcess]] | ||
* [[ | *[[DosKillThread]] | ||
[[Category: | [[Category:Dos]] |
Latest revision as of 15:07, 10 December 2022
Keeps a list of routines that run when the current process ends.
Syntax
DosExitList (ordercode, pfn)
Parameters
- ordercode (ULONG) - input
- DosExitList action and invocation order.
- ordercode contains two one-byte fields in the low-order word. The high-order word is zero.
- The low-order byte of the low-order word indicates which action DosExitList performs. This function can update the list of routines or transfer to the next address on the termination list at the completion of a routine. The values of the byte and their meanings are as follows:
- 1 EXLST_ADD Add an address to the termination list.
- 2 EXLST_REMOVE Remove an address from the termination list.
- 3 EXLST_EXIT When termination processing completes, transfer to the next address on the termination list.
The high-order byte of the low-order word 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 of the low-order word must be set to zero.
The invocation order indicates where the routine address is to be placed in an ordered list. This list determines the order in which the exit list routines are invoked. Routines with 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:
0x80 - 0x88 | OS/2 Extended Edition Database Manager |
0x90 - 0x98 | OS/2 Extended Edition Communications Manager |
0xA0 - 0xA8 | OS/2 Presentation Manager |
0xB0 | OS/2 Keyboard (KBD) component |
0xC0 | OS/2 Video (VIO) component |
0xD0 | OS/2 Interprocess Communication (IPC) Queues component |
- pfn (PFNEXITLIST) - input
- The address of a routine to be run.
Return Code
ulrc (APIRET) - returns
DosExitList returns one of the following values:
- 0 NO_ERROR
- 1 ERROR_INVALID_FUNCTION
- 8 ERROR_NOT_ENOUGH_MEMORY
- 13 ERROR_INVALID_DATA
Remarks
DosExitList is issued to define a routine that is to be given control when a process completes its execution. Multiple routines may be defined to receive control when a process is ending. For each process, the operating system maintains a list of addresses of defined exit list routines.
When the process is ending, the operating system transfers control to each address in this list. If there are multiple addresses in the list, they will each get control in numerical order by function invocation order, that is, low (0) will be first, and high (0xFF) will be last. In case of duplicate entries for the same value, the routines will be run in LIFO (last in, first out) order.
Library modules can issue DosExitList to free resources or to clear flags and semaphores in case the client process ends without notifying them.
Before transferring control to the routines in the termination list, the operating system resets the stack to its initial value. The routine must be in the address space of the ending process. The termination routine should perform its processing and then issue DosExitList with a value of 3 (EXLST_EXIT) for ordercode. The termination routine should be as short as possible.
Most system functions are allowed in an exit list routine. However, DosCreateThread and DosExecPgm are not.
An exit list routine must not call functions that have a better function order priority (that is, a lower value for ordercode) than itself. For example, an exit list routine with a function order value of 0x9A can use Presentation Services functions but not Communications Manager functions.
When the exit list routine receives control, the first parameter on the stack (located at ESP+4) contains a termination code that describes why the process ended. The values of the termination codes are as follows:
0 TC_EXIT Normal exit 1 TC_HARDERROR Hard-error halt 2 TC_TRAP Trap operation for a 16-bit child process 3 TC_KILLPROCESS Unintercepted DosKillProcess 4 TC_EXCEPTION Exception operation for a 32-bit child process
When the exit list routine receives control, all system semaphores owned by the process have their ownership transferred to the thread that performs exit list processing. This allows the thread to request serialization semaphores without danger of blocking in case the semaphore was held by another thread in the process that has already ended.
Note: All exit list routines must be declared as VOID APIENTRY. This ensures the integrity of the stack.
Example Code
This example adds an exit routine named "ExitRtn1" to the exit-list sequence. Routines in this sequence must use DosExitList instead of DosExit to end.
#define INCL_DOSPROCESS /* Process and thread values */ #define INCL_DOSERRORS /* DOS error values */ #include <os2.h> #include <stdio.h> VOID APIENTRY ExitRtn1(VOID); /* Our exit routine */ int main(VOID) { APIRET rc = NO_ERROR; rc = DosExitList(EXLST_ADD /* Add to exit-list sequence */ | 0x00002A00, /* Invocation order is 42 (0x2A) */ (PFNEXITLIST) ExitRtn1); /* Specify added exit routine */ if (rc != NO_ERROR) { printf("DosExitList error: return code = %u\n", rc); return 1; } printf("Routine main ends...\n"); return NO_ERROR; } /* All exit list routines must be declared as VOID APIENTRY. This ensures the integrity of the stack. */ VOID APIENTRY ExitRtn1(VOID) { APIRET erc = NO_ERROR; /* Return code */ printf("... but ExitRtn1 runs last.\n"); /* Might want to save data or close files here */ erc = DosExitList(EXLST_EXIT, /* Exit */ (PFNEXITLIST) NULL); if (erc != NO_ERROR) { printf("DosExitList error: return code = %u\n", erc); } return; }