z/OS UNIX System Services File System Interface Reference
Previous topic | Next topic | Contents | Contact z/OS | Library | PDF


Waiting and posting

z/OS UNIX System Services File System Interface Reference
SA23-2285-00

OSI_Operations are provided to the PFS to wait for internal events and to post the waiting thread when the event occurs.

Three important reasons for using the OSI wait and post services rather than native MVS™ WAIT and POST are:
  • The OSI services allow signals to interrupt a wait.
  • Users are not left hanging if z/OS UNIX or the PFS is stopped.
  • The PFS is protected from any system integrity exposures that might result from the cross-memory post operation.
There are two kinds of wait, distinguished by whether signals are enabled during the wait:
  • The not signal-enabled waits are used to wait for internal serialization or other activities that are independent of external forces likely to take a long time. These waits should generally not be used with human interactions. Examples are: waiting for data to be read from disk, or waiting for an available output buffer from a pool that is shared by all users.
  • The signal-enabled waits usually correspond to the blocking situations that are defined by POSIX, and often involve waiting for an end user to do something. Examples are: waiting for data to be read or written by another independent program, such as a socket session, or reading input from a terminal.

    Signals should be enabled when the end user may need to break out of an indefinite wait.

When a signal-enabled wait is entered, all serialization that was obtained by the LFS is dropped before the wait and reobtained after it. This means that other operations may intrude on an otherwise exclusive operation. The PFS must take this into account if it uses signal-enabled waits. This does not mean that two exclusive operations will actually be running in the PFS for the same vnode-inode at the same time, but that a second operation may run while the first is blocked. When the first is resumed there may have been state changes made by the second. For writes on stream sockets, the default socket option of exclusive write will prevent the dropping of LFS serialization during single-enabled waits.

The WAITX option also allows LFS serialization to be dropped around the wait, independent of whether signals are enabled. See the LFS-PFS control block serialization for details on LFS serialization.

As a consequence of dropping LFS serialization, it is possible for a file system to be unmounted, with the IMMEDIATE or FORCE operands, while a task is waiting. If this happens, the wait service returns with an OSI_UNMOUNTED return code when it is posted, and the PFS must cancel the rest of the operation and return to the LFS with some care. Because it is expected that vfs_umount will have cleaned up all file-system-related resources, the current operation may have to avoid references to internal file system structures that are freed by vfs_umount.

Waits that are signal-enabled or that request the LFS to drop its serialization cannot be used on some vnode and VFS operations. The implementation notes for those operations state this.

The OSI sleep and wakeup functions are similar to wait and post, with these advantages:
  • Osi_sleep
    • Does not require a separate setup call
    • Associates a Resource_id and Pfs_id with the sleeping thread
  • Osi_wakeup
    • Wakes up all threads that match Resource_id and Pfs_id
Implementation details: The PFS implementation for waiting and posting involves the steps described in this section. There are two threads involved: the waiting thread and the posting thread.
  1. The waiting thread is running on behalf of some VFS or vnode operation when it must wait for an event to occur. It calls osi_wait to set up for the wait, performs internal coordination to schedule the eventual wakeup, and calls osi_wait again to actually suspend the thread.
  2. The posting thread may be an independent PFS task, or it may be running on behalf of some other user's VFS or vnode operation. It determines that a thread is waiting for the resource it is dealing with, and calls osi_post to wake that thread up.
  3. When the waiting thread wakes up, it checks the return code from osi_wait and reacts accordingly.
This table lists the PFS implementation for the waiting thread.
Waiting thread Posting thread
  • Determine that a wait is necessary.
    osi_wait(OSI_SETUPSIG, OSI, RC)
  • Create an internal wait structure that is used by the posting thread to recognize that the waiting thread is waiting.
  • Save the osi_token in this structure.
  • Chain the wait structure where the posting thread will find it.
    osi_wait(OSI_SUSPEND, OSI, RC)
(None)
(None)
  • When an event occurs, scan the wait structures to see if anyone is waiting for this event. Unchain and free the wait structure.
    osi_post(saved_token, RC)
  • If the return code is not zero, the waiting thread did not get this post and you may need to go on to the next waiting thread.
  • Select on return code:
    • When (OSI_POSTED): proceed with what you were going to do.
    • When (OSI_SIGNALRCV): a signal has arrived (when using SETUPSIG rather than SETUP). Back out of this operation and return EINTR.
    • Otherwise: an abnormal end or unexpected error occurred. Back out of this operation and return EMVSERR.
    • End
(None)
Note:
  1. This example assumes that the PFS has its own serialization around the chaining and unchaining of the wait structure.
  2. A variation of the steps in this table would be to unchain and free the wait structure on the waiting thread. In this case, the posting thread marks the structure as "posted" so that another event occurrence cannot result in the same structure's being used again. Recovery is more complicated with this approach, though.
  3. One also has to consider abnormal ends while waiting—for instance, the user might be canceled. In that case, control does not return to the code after the osi_wait. If the PFS supports vn_recovery, or has an ESTAE or FRR active, it gets control there and the situation can be handled as when a signal is received.
  4. For abnormal ends and any return code other than OSI_POSTED, additional serialization between the waiting thread and the posting thread is necessary. In these cases the waiting thread is ending before, or even while, the posting thread is trying to wake it up.

    This is why it is important to save a copy of the osi_token from the waiting thread's OSI, rather than just the address of the waiting thread's OSI. The waiting thread's OSI storage could be gone by the time the posting thread tries to refer to it.

  5. Another consideration is user address space end-of-memory, which abnormally terminates the waiting thread without activating any ESTAE or FRR. In this case, the LFS uses the OSI recovery token to invoke vfs_recovery, which gives the PFS a chance to clean up.

Go to the previous page Go to the next page




Copyright IBM Corporation 1990, 2014