Previous section.

Data Link Provider Interface (DLPI), Version 2
Copyright © 2000 The Open Group

Precedence of DLPI Primitives

Overview

This appendix presents the precedence of DLPI primitives relative to one another. Two queues are used to describe DLPI precedence rules. One queue contains DLS user-originated primitives and corresponds to the STREAMS write queue of the DLS provider. The other queue contains DLS provider-originated primitives and corresponds to the STREAMS read queue of the DLS user. The DLS provider is responsible for determining precedence on its write queue and the DLS user is responsible for determining precedence on its read queue as indicated in the precedence tables given in this appendix.

For each precedence table, the rows (labeled "PRIM X") correspond to primitives that are on the given queue and the columns (labeled "PRIM Y") correspond to primitives that are about to be placed on that queue. Each pair of primitives (PRIM X, PRIM Y) may be manipulated resulting in:

The precedence rules define the allowed manipulations of a pair of DLPI primitives. Whether these actions are performed is the choice of the DLS provider for user-originated primitives and the choice of the DLS user for provider-originated primitives.

Write Queue Precedence

The following table presents the precedence rules for DLS user-originated primitives on the DLS provider's STREAMS write queue. It assumes that only non-local primitives (i.e. those that generate protocol data units to a peer DLS user) are queued by the DLS provider.

For connection establishment primitives, this table represents the possible pairs of DLPI primitives when connect indications/responses are single-threaded. For the multi-threading scenario, the following rules apply:

A DL_DISCONNECT_REQ does not have precedence over a queued DL_CONNECT_REQ. The DLS provider, however, need not actually process the DL_CONNECT_REQ. Instead, both primitives may be removed from the queue, provided that the DLS provider acknowledges the DL_DISCONNECT_REQ by a DL_OK_ACK.

PRIM Y P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
PRIM X (on queue)                              
P1 DL_INFO_REQ                              
P2 DL_ATTACH_REQ                              
P3 DL_DETACH_REQ                              
P4 DL_BIND_REQ                              
P5 DL_UNBIND_REQ                              
P6 DL_UNITDATA_REQ           1                  
P7 DL_UDQOS_REQ                              
P8 DL_CONNECT_REQ                     1        
P9 DL_CONNECT_RES                     3 1 1    
P10 DL_TOKEN_REQ                              
P11 DL_DISCONNECT_REQ               1              
P12 DL_DATA_REQ                     5 1 3 3  
P13 DL_RESET_REQ                     3        
P14 DL_RESET_RES                     3 1 1    
P15 DL_SUBS_BIND_REQ                              

Table: Write Queue Precedence
 

KEY:-
Code
"blank" Empty box indicates a scenario which cannot take place.
1 Y has no precedence over X and should be placed on queue behind X.
2 Y has precedence over X and may advance ahead of X.
3 Y has precedence over X and X must be removed.
4 Y has precedence over X and both X and Y must be removed.
5 Y may have precedence over X (DLS provider's choice) - if so X must be removed.

Read Queue Precedence

The following table presents the precedence rules for DLS provider-originated primitives on the DLS user's STREAMS read queue.

For connection establishment primitives, this table represents the possible pairs of DLPI primitives when connect indications/responses are single-threaded. For the multi-threading scenario, the following rules apply:

  1. A DL_CONNECT_IND primitive has no precedence over either a DL_CONNECT_IND or a DL_DISCONNECT_IND primitive that is associated with another connection correlation number (dl_correlation), and should therefore be placed on the queue behind such primitives.

  2. Similarly, a DL_DISCONNECT_IND primitive has no precedence over either a DL_CONNECT_IND or a DL_DISCONNECT_IND primitive that is associated with another connection correlation number, and should therefore be placed on the queue behind such primitives.

  3. A DL_DISCONNECT_IND does have precedence over a DL_CONNECT_IND primitive that is associated with the same correlation number (this is indicated in the table below). If a DL_DISCONNECT_IND is about to be placed on the DLS user's read queue, the user should scan the read queue for a possible DL_CONNECT_IND primitive with a matching correlation number. If a match is found, both the DL_DISCONNECT_IND and matching DL_CONNECT_IND should be removed.

If the DLS user is a user-level process, it's read queue is the stream head read queue. Because a user process has no control over the placement of DLS primitives on the stream head read queue, a DLS user cannot straightforwardly initiate the actions specified in the following precedence table. Except for the connection establishment scenario, the DLS user can ignore the precedence rules defined in the table below. This is equivalent to saying the DLS user's read queue contains at most one primitive.

The only exception to this rule is the processing of connect indication/response primitives. A problem arises if a user issues a DL_CONNECT_RES primitive when a DL_DISCONNECT_IND is on the stream head read queue. The DLS provider will not be expecting the connect response because it has forwarded the disconnect indication to the DLS user and is in the DL_IDLE state. It will therefore generate an error upon seeing the DL_CONNECT_RES.To avoid this error, the DLS user should not respond to a DL_CONNECT_IND primitive if the stream head read queue is not empty. The assumption here is a non-empty queue may be holding a disconnect indication that is associated with the connect indication that is being processed.

When connect indications/responses are single-threaded, a non-empty read queue can only contain a DL_DISCONNECT_IND, which must be associated with the outstanding DL_CONNECT_IND. This DL_DISCONNECT_IND primitive indicates to the DLS user that the DL_CONNECT_IND is to be removed. The DLS user should not issue a response to the DL_CONNECT_IND if a DL_DISCONNECT_IND is received.

The multi-threaded scenario is slightly more complex, because multiple DL_CONNECT_IND and DL_DISCONNECT_IND primitives may be interspersed on the stream head read queue. In this scenario, the DLS user should retrieve all indications on the queue before responding to a given connect indication.

If a queued primitive is a DL_CONNECT_IND, it should be stored by the user process for eventual response. If a queued primitive is a DL_DISCONNECT_IND, it should be matched (using the correlation number) against any stored connect indications. The matched connect indication should then be removed, just as is done in the single-threaded scenario.

PRIM Y P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14
PRIM X (on queue)                            
P1 DL_INFO_ACK     1 1 1 1   1 1 1 1      
P2 DL_BIND_ACK     1   1                  
P3 DL_UNITDATA_IND 2   1 2               2 2  
P4 DL_UDERROR_IND 2   1 1               2 2  
P5 DL_CONNECT_IND 2           2 4            
P6 DL_CONNECT_CON 2           2 3 1 1        
P7 DL_TOKEN_ACK         1 1   1 1 1 1      
P8 DL_DISCONNECT_IND 2       1   2           2  
P9 DL_DATA_IND 2           2 5 1 3 3   2  
P10 DL_RESET_IND 2           2 3         2  
P11 DL_RESET_CON 2           2 3 1 1     2  
P12 DL_OK_ACK     1 1 1     1 1 1        
P13 DL_ERROR_ACK     1 1 1     1 1 1 1      
P14 DL_SUBS_BIND_ACK     1   1                  

Table: Read Queue Precedence

KEY:-
Code
"blank" Empty box indicates a scenario which cannot take place.
1 Y has no precedence over X and should be placed on queue behind X.
2 Y has precedence over X and may advance ahead of X.
3 Y has precedence over X and X must be removed.
4 Y has precedence over X and both X and Y must be removed.
5 Y may have precedence over X (DLS provider's choice) - if so X must be removed.

Contents Next section Index