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.