|
|
|
Creates and/or opens a port. The port can be opened to allow for the
asynchronous receipt of incoming messages by enabling a user specified handler.
Syntax
I32 REC CA16 CA16
port_id := AIFPORTOPEN ( overall_status, port_name, port_password,
I32 I32 I32A @64A
access_mode, user_id, itemnum_array, item_array,
RECA
itemstatus_array );
Functional Return
- port_id
- 32-bit signed integer by reference (required)
Returns a unique identifier, a port ID, to be used with other port AIFs
to manage the opened port. The maximum number of open AIF ports is 2048.
If the call to AIFPORTOPEN is unsuccessful,
port_id is undefined. Check
overall_status to determine which error occurred.
Parameters
- overall_status
- record by reference (required)
Returns the overall status of the call. A zero indicates a successful
call. A negative value indicates an error in the overall call, not
specific to any particular item. A positive value indicates the last
element in itemstatus_array, signaling an error condition. Refer to
appendix A for meanings of status values.
Record type: status_type (Refer to appendix B.)
- port_name
- character array by reference (required)
Passes name used to identify this particular port. This name must be
unique across the entire system. It should be padded on the right with
blanks if it is fewer than 16 characters. The name will be upshifted, so
it is not case sensitive.
If a totally blank port name is specified, a unique name is established,
a port with that name is created, and the name is returned in the
port_name parameter.
Array type: pac16 (Refer to appendix B.)
- port_password
- character array by reference (required)
Passes a password to associate with the port being opened. This password
can be up to 16 characters in length. It should be padded on the right
with blanks if it is fewer than 16 characters. The password will be
upshifted, so it is not case sensitive. The first open of a port
establishes the password, which must be matched by all subsequent opens.
Array type: pac16 (Refer to appendix B.)
- access_mode
- 32-bit signed integer by value (required)
Passes a value determining the access mode for the port being opened.
Values and their meanings are as follows:
| 1 | Receive access |
| 2 | Send access |
| 3 | Both receive and send access |
- user_id
- 32-bit signed integer by value (optional)
The user ID assigned to a vendor at the time of purchase of the
Architected Interface Facility: Operating System product. If it is not
passed, the caller must have previously called AIFACCESSON.
Default: 0
- itemnum_array
- 32-bit signed integer array by reference (optional)
This is an array of integers, terminated by an element containing the
value zero, used to define the corresponding option given in the
item_array parameter. If this optional parameter is
specified, the item_array parameter and the
itemstatus_array parameter must both be supplied.
Default: nil
- item_array
- 64-bit address array by reference (optional)
An array with the same number of elements as the
itemnum_array parameter, each of which is a
globalanyptr that points to the appropriate type needed by each
particular item number. The value used for each option is taken from, or
returned to, the location pointed to by the globalanyptr in
this array. When this parameter is supplied, the
itemnum_array parameter and the
itemstatus_array parameter must both be supplied.
Array type: globalanyptr
Default: nil
- itemstatus_array
- record array by reference (optional)
If problems are detected with specific items, an error status is placed
in the corresponding element of this array for each item with an error.
The overall status parameter indicates whether any individual items
contained errors, and the element of the last detected error. This array
must contain as many elements as are contained in the
itemnum_array and item_array parameters.
A non-zero value indicates an error, but a valid option does not set the
value to zero, so this array should be initialized to all zeros before
making the call.
Array type: status_type (Refer to appendix B.)
Default: nil
Operation Notes
The AIF Port Facility is an application interface that provides a fast means
of interprocess communication by sending messages from one process to another.
Messages can be received in a synchronous or asynchronous fashion. The ability
to receive messages asynchronously is determined when the port is created.
The remaining notes will reference details from the AIFPORTOPEN item
descriptions (Table 3-23).
Please review the item descriptions before reading further.
Opening An AIF Port
The first time that AIFPORTOPEN is called for a named port that does
not exist, it is created by default. If the named port already exists, it is
opened. AIFPORTOPEN returns an integer value that must be supplied to
all other port AIFs to identify the port being referenced. The default
AIFPORTOPEN creates the port as temporary and does not allow for the
asynchronous receipt of messages.
An asynchronous port is a port that provides the capability of
interrupting the creator upon receipt of a message and transfers control to a
user specified handler. To create an asynchronous port specific items must be
passed to the AIFPORTOPEN routine. The following example illustrates
the creation of an asynchronous port.
readln (user_id);
portname := 'aifport1 ';
portpass := 'aifpass1 ';
accessmode := 1; { receive access }
itemnum_ports := Init_Itemnum_Array; { zero array }
item_ports := Init_Item_Array;
item_status_ports := Init_Item_Status_Array;
createoptions := 2; { create new }
itemnum_ports [1] := 11201;
item_ports [1] := ADDR(createoptions);
maxmsgsize := 80; { message size }
itemnum_ports [2] := 11202;
item_ports [2] := ADDR(maxmsgsize);
proc_name := '#PORTHANDLER#';
proc_file := '#ASYNC1#';
HPGETPROCPLABEL ( proc_name, createhandler,
overall_status, proc_file, False );
if overall_status.all <> 0 then
ERROR_IN_CALL('HPGETPROCPLABEL',overall_status);
itemnum_ports [3] := 11206;
item_ports [3] := addr(createhandler); { handler address }
createstate := True;
itemnum_ports [4] := 11207; { next element initialized to 0 }
item_ports [4] := addr(createstate); { enabled }
portid1 := AIFPORTOPEN ( overall_status, portname, portpass,
accessmode,,itemnum_ports,
item_ports, item_status_ports );
if overall_status.all <> 0 then
ERROR_IN_CALL ( 'AIFPORTOPEN', overall_status,
item_status_ports );
The creator of an asynchronous port is the only process that may receive
messages from this port, and must provide the handler address when opening the
port. If the creating process abnormally terminates, subsequent sends to the
port will return an error.
AIF ports that do NOT specify a handler at creation time, receive messages
synchronously and allow multiple receivers. In addition, synchronous ports can
be permanent, however, asynchronous ports are always temporary.
Handlers
Handlers for asynchronous ports must be coded to certain conventions in order
to function properly. The address of the handler can be acquired by calling
the intrinsic HPGETPROCLABEL as shown in the previous example.
When defining the handler routine, the calling sequence must have one
parameter. This parameter will contain the portid of the AIF port which
received the asynchronous message.
In Pascal/iX, a handler is declared as follows:
procedure INT_HANDLER ( port_id : integer );
In C/iX, it would be:
void INT_HANDLER ( int portid )
Handlers should do only what is absolutely necessary. It is NOT a good idea to
do the AIFPORTRECEIVE using the "all ports" option, as this can
result in unnecessary delays. When using item 11003 of AIFPORTRECEIVE
to retrieve envelope information, be sure to do the actual receive of the
message, otherwise the message will remain queued to the port. Also, consider
potential traps and escapes and do not allow your handler to be exited in this
fashion. If a handler does escape, it will be caught by AIF ports code and
will NOT be propagated out to the user.
Finally, a handler may never call AIFPORTCLOSE to close an
asynchronous port. This will result in unpredictable behavior, and possible
system failure. Handlers that are written in C, may not use the longjump
function and must have a return-type of void. Handlers execute at ring level 2
or privileged mode. Calls to GETUSERMODE are not allowed inside the
handler, this will cause an IMEM protection trap, which results in a process
abort.
Special Considerations
The asynchronous receipt of incoming messages has been implemented through
Process Interrupts. A process interrupt is generated to signal the arrival of
a message on an asynchronous port. The process interrupt will "interrupt" the
creator process transferring control to the user supplied interrupt handler.
As with other types of process interrupts (eg., Break, Cntrl-Y), control will
not be transferred to the user's handler until the creator process is in the
appropriate state. For asynchronous port interrupts, the process interrupt
will be postponed if the creator is critical, in system code, or executing at
ring level 0 or 1. This is done to protect critical system operations from
being interrupted by the user application.
A waited receive against an asynchronous port takes precedence over
notification by a process interrupt. Therefore, a process which blocks,
waiting for a message from its asynchronous port has effectively disabled
process interrupt notification. Several possible uses of asynchronous ports
are described to illustrate the systems behavior.
Example 1
A process opens an asynchronous port with port interrupt handling enabled. The
handler does a nowait receive to get the message and it does not access any
global data.
When a send is issued against the port the message is queued by the send
request. Messages sent to a process NOT blocked on an asynchronous port
receive, will result in a process interrupt. When the receiving process is in
the appropriate state (ring level 2 or 3) the user handler will be invoked.
It is possible for the user interrupt handler to nest multiple levels deep if
additional process interrupts occur. In this case, the user should do a single
receive against the port for each call of the handler. The user should also
handle error messages appropriately.
However, if the receiver chooses to explicitly wait for the arrival of a
message on an asynchronous port, when the send is issued, the dispatcher is
notified to unblock the process. When the receiver process is awoken, it will
complete the receive operation on a single message. It is possible for
multiple messages to queue while the process is blocked. If a user waits on an
asynchronous port in this fashion, they are responsible for checking for
multiple messages once the receive completes.
Example 2
The user opens an asynchronous port. AIFPORTINT is called to disable
port interrupt handling around critical areas in the user code. Also
AIFPORTINT is used in the handler to disable interrupt handling after
entry, and later re-enabled before exiting the handling routine.
Again, the message is queued to the port when the send request is issued. If
the receiver is not currently waiting on the port, the process interrupt will
occur. Further process interrupts will nest until the user calls
AIFPORTINT inside their handler. Once interrupt handling is disable,
additional messages which arrive will cause a pending count to be incremented
and the handler invokation will be delayed. When AIFPORTINT is called
to re-enable interrupt handling, the user handler will be called once for each
time the pending count was incremented. This is repeated until the pending
interrupts have been serviced.
If the user is sitting in a waited receive, multiple messages can be sent, and
the receiver will unblock. The receive will return the first message, but the
user is responsible for clearing the port. If the user calls
AIFPORTINT around the waited receive, it is possible the user can
clear messages from the port, and when AIFPORTINT is called to enable
interrupt handling, the handler could get invoked for messages which have
already been read. Therefore, the handler should be coded to handle the case
where no messages exist on the port.
AIFPORTOPEN Item Descriptions
The following table provides detailed descriptions of item numbers and
corresponding items associated with AIFPORTOPEN.
Table 3-23 AIFPORTOPEN Item Descriptions
| Item Number |
Item Name (Data Type) Release First Available Description |
| 11201 |
Create option (I32); Release 3.0
Passes a port creation option. Values and their meanings are as follows:
| 1 |
Create a new port if the named port does not exist; otherwise,
open the existing port. |
| 2 |
Create a new port and open it. Return an error if the port
already exists. |
| 3 |
Open an existing port. Return an error if it does not exist. |
Default: 1 |
| 11202 |
Maximum message size (I32); Release 3.0
Passes the maximum message size, in bytes, to allow through this port. An
error is returned if an attempt is made to send a message larger than this
value.
Default: 256 bytes Maximum: 8144 |
| 11203 |
Normal message size (I32); Release 3.0
Passes the normal message size, in bytes. When this number is multiplied
by the maximum number of normal messages, the result must be greater than
or equal to the maximum message size.
Default: 64 bytes |
| 11204 |
Maximum # of normal messages (I32); Release 3.0
Passes the maximum number of normal-sized messages (refer to item number
11203) to allow in this port. When this number is multiplied by the normal
message size, the result must be greater than or equal to the maximum
message size (refer to item number 11202).
The absolute maximum number of normal messages is 32,767; however, this
value may be smaller based on the following calculation:
Maximum # of normal messages = 1,048,256 words / ( maximum message size
rounded up in words + 16 words)
NOTE: The system allocates message pools based on the message size and
number of normal messages when the port is created. These resources should
be allocated sparingly since they are allocated out of system space.
Shortages of system space can result in a system failure.
Default: 32 |
| 11205 |
Make permanent (B); Release 3.0
Passes a value specifying the final disposition of the port (whether
permanent or removed) after the last process has done a close on it. If
the port is to remain after the last process has done a close on it, a
value of true must be passed with this parameter for all opens of the port.
The last open of the port establishes the final permanence of the port. If
the last opener passes this option with a true value, the port is permanent.
If the last opener does not specify this option, or specifies it and
passes a false value, the port is removed after the last process closes it.
To remove a permanent port from the system, all that is required is for a
process to open the port without specifying this parameter, or specifying
this parameter as false; the port is then destroyed when the last accessor
closes the port.
An asynchronous port is always temporary. When an asynchronous port is
opened, an error is returned if this option is specified as permanent.
Default: FALSE (port is temporary) |
| 11206 |
Handler address (@32); Release 4.0
Passes the handler address for an asynchronous port. The address of the
user defined handler can be acquired by calling the intrinsic
HPGETPROCLABEL. See the operational notes for handler
requirements. This item can only be specified when the port is first
created (refer to item 11201). Any attempt to pass this item to an already
open port results in an error. An asynchronous port may not be permanent.
(Refer to item 11205.)
Default: nil |
| 11207 |
Interrupt handler state (B); Release 4.0
Passes a Boolean that enables or disables the port interrupt handler at
creation time. A value of TRUE means that the interrupt handler is enabled
upon return from AIFPORTOPEN, while FALSE means that the
interrupt handler is disabled and a call to AIFPORTINT is
required to enable it.
Default: FALSE |
|