Event code 24 — POSIX events event

Purpose

The event handler is a member supplied routine that is invoked at various times throughout the execution of a program when an event had occurred. The address of each member's event handler is held in the Language Environment member list, in the third word of the appropriate member's block.

During Language Environment initialization, Language Environment loads CEEEVxxx, where xxx is the member number, if there is a corresponding signature CSECT in the load module. Language Environment saves this address in the appropriate slot in the member list.

Linkage to the member event handler is by BALR 14,15, and R1 contains the address of a standard parameter address list. The first parameter always indicates the type of event for which the event handler has been called. Additional parameters are dependent upon the specific event.

With the introduction of POSIX support, a new event code has been added to the existing set of event codes to identify various POSIX-related events that occur during the execution of the application. An accompanying function code, or event sub-code, uniquely identifies the POSIX event.

Syntax

Call CEEEVnnn (24, function_code, additional_parms)
INT4       *function_code;
POINTER    *ppsd_addr;
INT        *dsa_fmt;
POINTER    *valid_interrupt_dsa;
POINTER    *caa_copy_addr;
INT        *interrupt_flags 
function_code (input)
Each of the POSIX-related events are discussed here:
1
POSIX fork() notification. This event is invoked before requesting the kernel to fork a new process when the calling process is not multi-threaded. It allows the members to indicate if they can tolerate a fork() request. Toleration is indicated by setting R15 to zero. If the member cannot tolerate a fork(), R15 is set to -4. If any member in the application cannot tolerate the fork(), the request to fork is denied. In a multi-threaded environment, function code 9 is used.
2
POSIX fork() in child. This event allows the members in the newly-forked child process to refresh their control blocks before the application code gains control. It is called when the process is not multi-threaded. In a multi-threaded environment, function code 12 is used.
3
POSIX asynchronous signal. This event is invoked when an asynchronous signal is received on a particular thread. The BPXYPPSD contains the information regarding the action to take for the specific signal. It is the responsibility of the member to either terminate the application or to resume at the next sequential instruction following the point of interrupt.
4
POSIX thread initialization. This event is driven on the newly created thread with a new CAA. A copy of the parent thread's CAA is passed to the event handler. This allows selective inheriting or copying of fields from the parent's CAA into the new CAA addressed by R12. There is no guarantee that the parent thread exists at the time of this event. It is the member's responsibility to access only those pointers that do not cause a reference to freed storage.
5
POSIX thread termination. This event offers the members the opportunity to clean up any thread-related resource that was allocated.
6
POSIX process initialization. This event is driven for POSIX(ON) applications under the Initial Process Thread (IPT). The POSIX environment has been initialized and all POSIX services are available. This event is driven after the Language Environment process initialization and after Language Environment enclave initialization.
7
POSIX process termination. This event is driven on the thread that requested termination, and not necessarily on the IPT. All threads have been terminated except the one driving this event. All POSIX functions are available. However, the use pthread_create() is restricted. This event is driven before the Language Environment enclave termination event. The intent of this event is to allow the cleanup of POSIX-related resources for the POSIX process.

By contrast, the Language Environment enclave termination event is always driven on the IPT to allow z/OS-related resources to be released. The POSIX environment has been terminated when this event is invoked and the POSIX flag in the EDB has been turned off.

9
POSIX multi-threaded fork() notification. This event is invoked before requesting the kernel to fork a new process in a multi-threaded environment. It allows the members to indicate if they can tolerate a multi-threaded fork() request. Toleration is indicated by setting R15 to zero. If the member cannot tolerate a fork() from a multi-threaded environment, R15 is set to -4. If any member in the application cannot tolerate the fork(), the request to fork is denied.
10
POSIX multi-threaded fork() lock. If the member tolerates the fork() request, any locking needed to prepare for the fork() is done.
11
POSIX multi-threaded fork() in parent after fork(). This event allows the members to undo any locking that occurred for the POSIX multi-threaded fork() notification. Any member that returned a zero return code for the POSIX multi-threaded fork() notification event is called for this event.
12
POSIX multi-threaded fork() in child. This event allows the members in the newly-forked child process to refresh their control blocks before the application code gains control.
13
POSIX process cleanup. This event is driven just prior to Language Environment requesting cleanup of the POSIX process.
additional_parms (input)
Parameters specific to a certain function code. The following diagram shows the parameters for each event.

Call CEEEVnnn  (24, 1)
Call CEEEVnnn  (24, 2)
Call CEEEVnnn  (24, 3, ppsd_ptr, dsa_fmt, valid_interrupt_dsa,
interrupt_flags)
Call CEEEVnnn  (24, 4, caa_copy_addr)
Call CEEEVnnn  (24, 5, last_thread)
Call CEEEVnnn  (24, 6)
Call CEEEVnnn  (24, 7)
Call CEEEVnnn  (24, 9)
Call CEEEVnnn  (24, 10)
Call CEEEVnnn  (24, 11)
Call CEEEVnnn  (24, 12)
Call CEEEVnnn  (24, 13)

ppsd_addr (input)
A fullword binary integer containing the address of the BPXYPPSD, which is a z/OS UNIX control block. For a description of the fields in the BPXYPPSD, see z/OS UNIX System Services Programming: Assembler Callable Services Reference.
dsa_fmt (input)
The format of the active DSA when the signal was received. This DSA is pointed to by register 4 or 13 saved in the PPSD pointed to by ppsd_ptr. Possible values for dsa_fmt are:
0
non-XPLINK
1
XPLINK
valid_interrupt_dsa (input)
This is a pointer to the valid DSA that was used to expand the Language Environment stack from when the member event 24 handler was called. This may differ from the value in PPSD register 4 or 13. This value should be passed through to CEE3RSUM (in the valid_interrupt_dsa field in the CEE3RSUM resume information area) when resuming the user application after handling the signal.
caa_copy_addr (input)
A fullword binary integer containing the address of the copy of the parent's CAA.
last_thread (input)
Flag to indicate if this event is being called by the last thread in a terminating process. Possible values for last_thread are:
0
It is not the last thread
1
It is the last thread
interrupt_flags (input)
A fullword flag area. Bit 4 in the flags is ON if the valid_interrupt_dsa was saved in the CEECAA_SAVSTACK field at the time of interrupt. If the application is resumed where it was interrupted, the valid_interrupt_dsa must be restored to the CEECAA_SAVSTACK field.

Bit 5 in the flags is ON if valid_interrupt_dsa was saved in the field pointed to by the CEECAA_SAVSTACK_ASYNC field at the time of interrupt. If the application is resumed where it was interrupted, the valid_interrupt_dsa must be restored to the field pointed to by the CEECAA_SAVSTACK_ASYNC field. The remaining bits are reserved for future use and must be zero.

A return code is placed in R15 by the event handler. The following return codes (in decimal) are defined:
-4
Event handler does not want to process the event
0
Event handler was successful
16
Event handler encountered an unrecoverable error

Typically, all Language Environment services are available during the handling of the event, including the stack and heap.