[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here 4.3 Mailbox Function Codes
HP OpenVMS I/O User’s Reference Manual: OpenVMS Version 8.4 > Chapter 4 Mailbox Driver

4.3 Mailbox Function Codes

The mailbox I/O functions are:

  • read

  • write

  • write end-of-file

  • set attention AST

  • wait for writer/reader

  • set protection

  • get mailbox information

No buffered I/O byte count quota checking is performed on mailbox I/O messages. Instead, the byte count or buffer quota of the mailbox is checked for sufficient space to buffer the message being sent. The buffered I/O quota and AST quota are also checked.

4.3.1 Read

Read mailbox functions are used to obtain messages written to the mailbox. The operating system provides the following mailbox function codes:

  • IO$_READVBLK—Read virtual block

  • IO$_READLBLK—Read logical block

  • IO$_READPBLK—Read physical block

IO$_READVBLK, IO$_READLBLK, and IO$_READPBLK all perform the same operation. To issue a read request, a process can specify any of the read function codes.

The following device- or function-dependent arguments are used with these codes:

  • P1—The starting virtual address of the buffer that is to receive the message. If P2 specifies a zero-length buffer, P1 is ignored. On OpenVMS Alpha and Integrity server, P1 can be a 64-bit address.

  • P2—The size of the buffer in bytes (limited by the maximum message size for the mailbox). A zero-length buffer may be specified. If a message longer than the buffer is read, the alternate success status SS$_BUFFEROVF is returned in the I/O status block. In such cases, the message is truncated to fit the buffer. The driver does not provide a means for recovering the deleted portion of the message.

The following function modifiers can be specified with a read request:

  • IO$M_WRITERCHECK—Completes the I/O operation with SS$_NOWRITER status if the mailbox is empty and no write channels are assigned to the mailbox. If no writer is assigned to the mailbox when the $QIO is issued and no data is in the mailbox, the $QIO completes immediately. If no data is in the mailbox but a writer is assigned, the $QIO operation completes when either a message is written or all writers deassign their channels to the mailbox. IO$M_WRITERCHECK is ignored if the channel on which it is issued is read/write because a writer is always assigned.

  • IO$M_NOW—Completes the I/O operation immediately with no wait for a write request from another process.

  • IO$M_STREAM—Ignores QIO record boundaries. The read operation transfers message data to the user's buffer until either P2 bytes are transferred, all message data currently in the mailbox is transferred, or an end-of-file message is encountered. If a WRITEOF message is within the records required to be read in order to fulfill the request for P2 bytes, the read request terminates successfully with the bytes it was able to read before finding the WRITEOF message and the end-of-file message becomes the first message in the mailbox. The next read request processes the end-of-file message. If the read request is a READ STREAM, then the request must be for greater than 0 bytes. $QIO READ STREAM can return fewer than P2 bytes with a return value of SS$_NORMAL if the mailbox is emptied by the $QIO READ STREAM request or a WRITEOF message is encountered.

    Figure 4-2 shows $QIO READ STREAM operations.

    Figure 4-2 $QIO READ STREAM Operation

    $QIO READ STREAM Operation

    A READ IO$M_STREAM (without IO$M_NOW specified) on an empty mailbox waits until some data has been written to the mailbox. It terminates with:

    • 0 bytes read if the next data written is an end-of-file message.

    • Fewer than P2 bytes read if the next data written is less than P2 bytes but greater than 0 bytes. (READ IO$M_STREAM ignores writes of 0 bytes.)

    • P2 bytes read if the next data written is greater than or equal to P2 bytes.

    If a $QIO READ STREAM is fulfilled by multiple $QIO WRITE requests, the sender PID returned in the IOSB of the $QIO READ STREAM reflects the first write request. A $QIO READ STREAM is charged BUFQUO for the request. This BUFQUO is released when the read request is met. A $QIO READ STREAM request that would cause BUFQUO to be exceeded for the mailbox when the mailbox has no writes pending returns an SS$_EXQUOTA error.

    A $QIO READ STREAM issued to a mailbox that would cause BUFQUO to be exceeded because BUFQUO is occupied by write requests still executes. This happens because by allowing the mailbox to temporarily exceed BUFQUO, BUFQUO is freed. Similarly, a $QIO WRITE that is issued to a mailbox that would cause BUFQUO to be exceeded, because the BUFQUO is occupied by read stream requests, still executes.

Reads of 0 bytes are handled differently depending on which functional modifiers are specified. If IO$M_STREAM is specified, then the $QIO returns SS$_NORMAL with 0 bytes read. The contents of the mailbox remain exactly as they were before the $QIO was issued. A $QIO READ STREAM of 0 bytes does not remove a 0 byte record, nor does it remove an end-of-file marker. If IO$M_STREAM is not specified, then $QIO returns one of the following:

  • SS$_NORMAL (if 0 bytes were written with the corresponding $QIO WRITE performed)

  • SS$_BUFFEROVF (if the corresponding $QIO WRITE wrote more than 0 bytes with 0 bytes read)

  • SS$_ENDOFFILE (if a WRITEOF function was performed as the corresponding $QIO write function)

For a 0-byte nonstream read, a record is actually removed from the mailbox to meet the $QIO READ request. Note that the use of the word “immediately” does not imply that synchronization of the $QIO request should not be performed.

Figure 4-3 shows the read mailbox functions. In this figure, Process A reads a mailbox message written by Process B. As the figure indicates, a mailbox read request requires a corresponding mailbox write request (except in the case of an error). The requests can be made in any sequence; the read request can either precede or follow the write request.

Figure 4-3 Read Mailbox

Read Mailbox

If Process A issues a read request before Process B issues a write request, one of two events can occur. If Process A did not specify the function modifier IO$M_NOW, Process A's request is queued before Process B issues the write request. When Process B's write request occurs, the data is transferred from Process B, through the system buffers, to Process A to complete the I/O operation.

However, if Process A did specify the IO$M_NOW function modifier, the read operation is completed immediately. That is, no data is transferred from Process B to Process A, and Process A's request is not queued. In this case, the I/O status returned to Process A is SS$_ENDOFFILE.

If Process B sends a message (with no function modifier; see “Write”) before Process A issues a read request (with or without a function modifier), Process A finds a message in the mailbox. The data is transferred and the I/O operation is completed immediately, regardless of whether IO$M_NOW is specified on the read request.

4.3.2 Write

Write mailbox functions are used to transfer data from a process to a mailbox. The operating system provides the following mailbox function codes:

  • IO$_WRITEVBLK—Write virtual block

  • IO$_WRITELBLK—Write logical block

  • IO$_WRITEPBLK—Write physical block

IO$_WRITEVBLK, IO$_WRITELBLK, and IO$_WRITEPBLK all perform the same operation. To issue a write request, a process can specify any of the write function codes.

These function codes take the following device- or function-dependent arguments:

  • P1—The starting virtual address of the buffer that contains the message being written. If P2 specifies a zero-length buffer, P1 is ignored. On OpenVMS Alpha and Integrity servers, P1 can be a 64-bit address.

  • P2—The size of the buffer in bytes (limited by the maximum message size for the mailbox). A zero-length buffer produces a zero-length message to be read by the mailbox reader.

The following function modifiers can be specified with a write request:

  • IO$M_READERCHECK—Completes the I/O operation immediately, with SS$_NOREADER status, if no read channels are assigned to the mailbox. If a $QIO WRITE with IO$M_READERCHECK is issued and is outstanding and all read channels assigned to the mailbox are then deassigned, the $QIO completes with SS$_NOREADER status. IO$M_READERCHECK is ignored if the channel on which it is issued is bidirectional read/write, because there is always a reader assigned. If SS$_NOREADER is returned for a write request, the $QIO WRITE operation does not place any data in the mailbox. If SS$_NOREADER is returned for a write end-of-file message request, the $QIO WRITE operation does not place the end-of-file marker in the mailbox.

  • IO$M_NOW—Completes the I/O operation immediately without waiting for another process to read the mailbox message. $QIO WRITE, without IO$M_NOW specified, does not complete until the data is read. $QIO WRITE NOW completes when the data is in the mailbox. If both IO$M_READERCHECK and IO$M_NOW are specified and no read channel is assigned to the mailbox, a status of SS$_NOREADER is returned and the data is not placed in the mailbox. If a read channel is assigned, the IO$M_READERCHECK modifier is ignored.

  • IO$M_NORSWAIT—If the mailbox is full, the I/O operation fails with a status return of SS$_MBFULL rather than placing the process in resource wait mode. Note that IO$M_NORSWAIT does not disable resource waits that may occur elsewhere in the $QIO operation. For example, IO$M_NORSWAIT does not affect any resource waiting that occurs when I/O processing routines try to allocate an I/O request packet while passing the I/O request to the mailbox driver.

A $QIO WRITE of 0 bytes causes a 0-byte long message to be placed in the mailbox. When this data is read by a $QIO READ without IO$M_STREAM specified, the $QIO READ returns an SS$_NORMAL status and 0 bytes. When this data is read by a $QIO READ STREAM in an attempt to read P2 bytes (P2 being greater than 0), the data is ignored. However, a $QIO READ STREAM of 0 bytes has no effect on the mailbox. A $QIO WRITE READERCHECK of 0 bytes, when no read channel is assigned to the mailbox, returns an SS$_NOREADER error and the 0-byte record is not placed in the mailbox. A message that is 0 bytes long is charged 1 byte of mailbox BUFQUO.

Figure 4-4 shows the write mailbox function. In this figure, Process A writes a message to be read by Process B. As in the read request example, a mailbox write request requires a corresponding mailbox read request (unless an error occurs) and the requests can be made in any sequence.

If Process A issues a write request before Process B issues a read request, one of two events can occur. If Process A did not specify the function modifier IO$M_NOW, Process A's write request is queued before Process B issues a read request. When this request occurs, the data is transferred from Process A to Process B to complete the I/O operation.

However, if Process A did specify the IO$M_NOW function modifier, the write operation is completed immediately. The data is available to Process B and is transferred when Process B issues a read request.

If Process B issues a read request (with no function modifier) before Process A issues a write request (with or without the function modifier), Process A finds a request in the mailbox. The data is transferred and the I/O operation is completed immediately.

Figure 4-4 Write Mailbox

Write Mailbox

4.3.3 Write End-of-File Message

Write end-of-file message functions are used to insert a special message in the mailbox. The process that reads the end-of-file message is returned the status code SS$_ENDOFFILE in the I/O status block. The message count of the Get Mailbox Information function reflects this end-of-file message; however, the mailbox byte count of this function does not include end-of-file markers. An end-of-file message is charged 1 byte of mailbox BUFQUO.

This function takes no arguments. The operating system provides the following function code:

  • IO$_WRITEOF—Write end-of-file message

The following function modifiers can be specified with a write end-of-file request:

  • IO$M_READERCHECK—Completes the I/O operation immediately, with SS$_NOREADER status, if no read channels are assigned to the mailbox. If a $QIO WRITEOF with IO$M_READERCHECK is issued and is outstanding and all read channels assigned to the mailbox are then deassigned, the $QIO completes with SS$_NOREADER status. IO$M_READERCHECK is ignored if the channel on which it is issued is bidirectional read/write, because there is always a reader assigned. If SS$_NOREADER is returned for a write end-of-file message request, the $QIO WRITEOF operation does not place the end-of-file marker in the mailbox.

  • IO$M_NOW—Completes the I/O operation immediately without waiting for another process to read the mailbox message. If both IO$M_READERCHECK and IO$M_NOW are specified, and no read channel is assigned to the mailbox, a status of SS$_NOREADER is returned and the end-of-file message is not placed in the mailbox.

  • IO$M_NORSWAIT—If the mailbox is full, the I/O operation fails with a status return of SS$_MBFULL instead of placing the process in resource wait mode. Note that IO$M_NORSWAIT does not disable resource waits that may occur elsewhere in the $QIO operation. For example, IO$M_NORSWAIT does not affect any resource waiting that occurs when I/O processing routines try to allocate an I/O request packet while passing the I/O request to the mailbox driver.

4.3.4 Set Attention AST

Set attention AST functions specify that an asynchronous system trap (AST) be delivered to the requesting process in the following cases:

  • When a cooperating process places a read request for which no write request is pending in a designated mailbox. This is called an unsolicited read request.

  • When a cooperating process places a write request for which no read request is pending in a designated mailbox. This is called an unsolicited write request.

  • When room becomes available in the mailbox.

If a message exists in the mailbox when a request to enable a write attention AST is issued, the AST routine is activated immediately. If no message exists, the AST is delivered when a write request message arrives; therefore, the requesting process need not repeatedly check the mailbox status. You must have both logical I/O and read access to the mailbox prior to performing a set attention AST function.

The operating system provides the following function codes:

  • IO$_SETMODE!IO$M_READATTN—Read attention AST

  • IO$_SETMODE!IO$M_WRTATTN—Write attention AST

  • IO$_SETMODE!IO$M_MB_ROOM_NOTIFY—Room in the mailbox attention AST

These function codes take the following device- or function-dependent arguments:

  • P1—AST address (request notification is disabled if the address is 0)

  • P2—AST parameter returned in the argument list when the AST service routine is called

  • P3—Access mode to deliver AST; maximized with requester's mode

These functions are enabled only once; they must be explicitly reenabled after the AST has been delivered if you desire repeat notification. All types of enable functions, and more than one of each type, can be set at the same time. The number of enable functions is limited only by the AST quota for the process.

Figure 4-5 shows the write attention AST function. In this figure, an AST is set to notify Process A when Process B sends an unsolicited message.

Figure 4-5 Write Attention AST (Read Unsolicited Data)

Write Attention AST (Read Unsolicited Data)

Process A uses the IO$_SETMODE!IO$M_WRTATTN function to request an AST. When Process B sends a message to the mailbox, the AST is delivered to Process A. Process A responds to the AST by issuing a read request to the mailbox. The data is then transferred to complete the I/O operation.

If several requesting processes have set ASTs for unsolicited messages at the same mailbox, all ASTs are delivered when the first unsolicited message is placed in the mailbox; however, only the first process to respond to the AST with a read request receives the data. Therefore, when the next process to respond to an AST issues a read request to the mailbox, it might find the mailbox empty. If this request does not include the function modifier IO$M_NOW, it is queued before the next message arrives in the mailbox.

Figure 4-6 shows the read attention AST function. In this figure, an AST is set to notify Process A when Process B issues a read request for which no message is available.

Figure 4-6 Read Attention AST

Read Attention AST

Process A uses the IO$_SETMODE!IO$M_READATTN function to specify an AST. When Process B issues a read request to the mailbox, the AST is delivered to Process A. Process A responds to the AST by sending a message to the mailbox. The data is then transferred to complete the I/O operation.

If several requesting processes set ASTs for read requests for the same mailbox, all ASTs are delivered when the first read request is placed in the mailbox. Only the first process to respond with a write request is able to transfer data to Process B.

4.3.5 Wait for Writer/Reader

The wait for writer/reader mailbox driver function waits until a channel is assigned to the mailbox with the requested access direction. This function returns immediately if a channel is already assigned to the mailbox with the proper access direction. This function always returns immediately if issued on a bidirectional mailbox channel. Any channel assigned bidirectionally to the mailbox satisfies both types of wait requests.

The wait function requires the same synchronization techniques as all other $QIO functions. $QIO Wait should not be issued without any synchronization of its completion. If no synchronization is performed, the program behaves as if no $QIO Wait function had been issued (except for the small delay caused by issuing the $QIO Wait).

The following function codes and modifiers are provided:

  • IO$_SETMODE!IO$M_READERWAIT—Waits for a read channel to be assigned to the mailbox.

  • IO$_SETMODE!IO$M_WRITERWAIT—Waits for a write channel to be assigned to the mailbox.

These function codes require no function-dependent arguments.

These functions are enabled only once. Once the $QIO operation completes, these functions must be explicitly reenabled.

4.3.6 Set Protection

The set protection functions allow the user to set volume protection on a mailbox (see “Mailbox Protection”). The requester must either be the owner of the mailbox or have BYPASS privilege. The OpenVMS operating system provides the following function code:

  • IO$_SETMODE!IO$M_SETPROT—Set protection

This function code takes the following device- or function-dependent argument:

  • P2—A volume protection mask

The protection mask specified by P2 is a 16-bit mask with 4 bits for each class of owner: SYSTEM, OWNER, GROUP, and WORLD, as shown in Figure 4-7.

Figure 4-7 Protection Mask

Protection Mask

Only logical I/O, read, and write functions have meaning for mailboxes. A clear (0) bit implies that access is allowed. If P2 is 0 or unspecified, the mask is set to allow all read, write, and logical operations.

The I/O status block for the set protection function (see Figure 4-10 ) returns SS$_NORMAL in the first word if the request was successful. If the request was not successful, the $QIO system service returns SS$_NOPRIV and both longwords of the I/O status block are returned as zeros.

4.3.7 Get Mailbox Information

The get mailbox information function allows the user to find out the number of unread messages and bytes in the mailbox. The following function code is provided:

  • IO$_SENSEMODE—Get mailbox contents information

The following function codes and modifiers are provided:

  • IO$_SENSEMODE!IO$M_READERCHECK—If a $QIO SENSEMODE with IO$M_READERCHECK is issued and no read channels are assigned to the mailbox, then the SS$_NOREADER condition value is returned in the IOSB.

  • IO$_SENSEMODE!IO$M_WRITERCHECK—If a $QIO SENSEMODE with IO$M_WRITERCHECK is issued and no write channels are assigned to the mailbox, then the SS$_NOWRITER condition value is returned in the IOSB.

These function codes require no function-dependent arguments.

The I/O status block for the get information function (see Figure 4-11