| OpenSS7 SS7 for the Common Man | © Copyright 1997-2007 OpenSS7 Corporation All Rights Reserved. Last modified: Sat, 01 Nov 2008 10:41:56 GMT | ||||||||||||||||
| |||||||||||||||||
| Manpage of QI_SRVPDescription: Manual PageKeywords: ss7 ss7/ip ss7 over ip ss7 mtp ss7 sccp ss7 tcap sigtran mtp sccp tcap openss7 acb56 linux telephony pstn linux telephony linux nebs linux compactpciQI_SRVPSection: Linux Fast-STREAMS DDI/DKI (9)Updated: 2008-10-31 Index Return to Main Contents NAMEsrv, service, qi_srvp, qi_srvp_t - STREAMS driver or module service procedureSYNOPSIS
ARGUMENTS
INTERFACEDESCRIPTIONqi_srvp() is one of 5 principal synchronous entry points into a STREAMS driver or module that form part of its definition. The principal entry points are: qi_qopen(9), qi_qclose(9), qi_qadmin(9), qi_putp(9), and qi_srvp(). The qi_srvp() procedure is specified in both the read and write queue qinit(9) structure that is associated with each queue in an existing queue pair forming an instance of the driver or module from the definitions in the module- and driver-defining streamtab(9) structure. The qi_srvp() procedure is called by STREAMS whenever the queue, q, has been scheduled for service and reaches the front of the STREAMS scheduler run queue. Queues are scheduled for service either explicitly, using STREAMS utility functions such as enableq(9) and qenable(9); or, implicitly by STREAMS message queue functions such as putq(9) and getq(9). The qi_srvp() procedure is the primary mechanism for deferring message processing and handling flow control within the STREAMS framework. Although qi_srvp() is declared to return a value, any returned value is ignored by STREAMS, and is not available to the caller of enableq(9), qenable(9), putq(9), or getq(9). The argument passed to the qi_srvp() procedure is as follows:
STREAMS maintains a list of queues that are scheduled for service. When a queue is scheduled that has not already been scheduled, it is placed on the tail of the list. When the STREAMS scheduler runs [see runqueues(9)], queues are taken off of the head of this run queues list and the qi_srvp() procedure of the queue is invoked with the queue pointer as the argument. Therefore, qi_srvp() procedures are always invoked within the context of the STREAMS scheduler, and are invoked single-threaded for a given queue, q. Scheduling a queue's qi_srvp() procedure for execution is termed enabling the queue. Once a queue's qi_srvp() procedure has been scheduled (i.e., the queue has been enabled), the procedure cannot be scheduled again until it has been executed. In other words, a queue cannot be enabled when it is already enabled. If a queue does not have a qi_srvp() procedure defined (i.e., the qi_srvp member of the associated qinit(9) structure is NULL), then the queue cannot be enabled: there is no service procedure to schedule. When flow control blocking by a forward queue subsides and STREAMS causes a feeding message queue with a defined qi_srvp() procedure to be enabled, this is termed back-enabling . The qi_srvp() procedure is scheduled for execution under the following circumstances:
When the qi_srvp() procedure is executed for a queue by the STREAMS scheduler, the following conditions prevail:
In constrast to the qi_putp(9) procedure, that handles immediate processing of messages, the qi_srvp() procedure is responsible for delayed or deferred processing of messages that were placed on the message queue by the qi_putp(9) procedure. Another difference is that qi_srvp() procedures run under STREAMS scheduler context, whereas qi_putp(9) procedures run under whatever context prevailed when the put(9) or putnext(9) utility invoking them were called. The qi_srvp() procedure is responsible for taking messages from the message queue in turn, using getq(9), and processing them. There are four actions that a qi_srvp() procedure can take with regard to the disposition of message on the queue:
If a message is left on the queue, a message is placed back on the queue with putbq(9), or, a call to getq(9) to get the next message for processing returns NULL, the qi_srvp() procedure must exit. Otherwise, the qi_srvp() procedure continues to take messages off of the queue with getq(9) and processes them in turn. Just as the qi_putp(9) procedure, qi_srvp() procedure is allowed to modify messages that are removed from the message queue at its discretion before applying one of the above terminal dispositions to the message. However, the qi_srvp() procedure should not modify the contents of the data buffer associated with any data block, datab(9), that has a reference count, db_ref, greater thatn one (1) [see dupmsg(9)]. Message blocks with a data block reference greater than one should be copied and the copy altered instead. Any other actions taken with regard to the message form part of the definition of the module or driver concerned. The more specific steps taken by a qi_srvp() procedure are as follows:
See below under EXAMPLES ® for examples of these steps. USAGEThe driver or module qi_srvp() procedure is responsible for maintaining proper operations of the Stream by handling specific message types in specific fashions. The following sections provide some guidelines for the design of qi_srvp() procedures from a driver or module, and rules for handling of messages within the procedure: Driver and Module qi_srvp() Design RulesThe following design rules apply to both drivers and modules:
Module qi_srvp() Design RulesThe following design rules apply to modules:
Driver qi_srvp() Design RulesThe following design rules apply to drivers:
RETURNThe qi_srvp() procedure returns an integer value. This value is ignored by STREAMS and should always be zero (0). ERRORSAlthough the qi_srvp() procedure is capable of returning an error code, the returned value is always ignored by STREAMS and cannot be passed back to the caller of any function. CONTEXTA driver or module qi_srvp() procedure, when invoked correctly, can be called by STREAMS either in STREAMS scheduler context (kernel thread), or in the context of a user process executing on behalf of the STREAMS scheduler before returning from a system call. MP-STREAMSSynchronized Modules and DriversIf mp-streams(9) synchronization has been specified for the driver or module, the inner synchronization barrier, if any, is entered shared or exclusive in accordance with the synchronization specification for the driver or module, across the call to the qi_srvp() procedure. If synchronization has not been specified for the driver or module (that is, the module or driver is specified as MP-safe), the qi_srvp() procedure is invoked without synchronization. MP-Safe Modules and Driversqi_srvp() is called by STREAMS either in STREAMS scheduler context (kernel thread), or in the context of a user process executing on behalf of the STREAMS scheduler before returning from a system call. Regardless of context, when properly invoked, STREAMS is aware of which queue is being processed on a per-processor basis. STREAMS acquires and holds a Stream head plumbing read lock, for the Stream within which the queue resides, across the call to the qi_srvp() procedure. This permits the qi_srvp() procedure, and any STREAMS utility functions called by the qi_srvp() procedure, to dereference any q_next pointer in the Stream, and the dereference will remain valid for the duration of the qi_srvp() call. Note that this does not provide any assurances of the validity of a q_next pointer dereference in any other Stream, such as another Stream in an upper or lower multiplex: the qi_srvp() procedure is responsible for asserting its own assurances in that regard. (Note that freezing a Stream with freezestr(9) guarantees validity of all subsequent q_next pointer derefernces until the Stream is thawed with unfreezestr(9)). If the Stream containing the queue, q, has been frozen with a call to freezestr(9), by a processor, STREAMS running on another processor will not enter any qi_srvp() procedure in the Stream, but will spin awaiting the thawing of the Stream by the processor that froze it, with a call to unfreezestr(9). If the Stream was frozen after the qi_srvp() procedure began execution, any attempt by the procedure to alter the state of the queue targetted in the freezestr(9) command that froze the Stream, will spin until the Stream is thawed by unfreezestr(9). No qi_srvp() procedure for a queue pair that has not yet had qprocson(9) called for the queue pair, or that has not returned from its qi_qopen(9) routine, will be executed by STREAMS. Once a qi_srvp() is executing, any call to qprocsoff(9) for the queue pair will spin until the qi_srvp() procedure exits and releases the Stream head plumbing read lock. If a qi_srvp() procedure has been scheduled for execution, has procedures turned off for its queue pair with qprocsoff(9) before the procedure has a chance to execute, when it is the qi_srvp() procedure's turn to execute, STREAMS will cancel it and release its reference to the queue pair. For MP-Safe drivers and modules, only one thread can be executing the qi_srvp() procedure for a given queue; however, other threads may be executing the qi_putp(9), qi_qopen(9), q_qclose(9), or q_qadmin(9), procedures and routines concurrently. It is the responsible of the writer of the qi_srvp() procedure to acquire and hold the necessary locks to provide exclusive access to data structures shared across these calls. freezestr(9) is inadequate in this case, and the procedures should use driver or module private locks. NOTICESA queue qi_srvp() procedure is an internal STREAMS entry point to the driver or module, that is not intended to be called directly by the module or driver writer. See enableq(9) and qenable(9) for accepted methods of invoking this procedure. STYLEIt is common practise to name qi_srvp() procedures as follows, (where prefix is the configuration prefix chosen for the driver or module and typically derived from the name of the driver or module, and which may contain a trailing underscore):
EXAMPLESExample #1 - Module qi_srvp()The following example of a module qi_srvp() procedure comes directly from the read and write side of the bufmod(4) module located in src/modules/bufmod.c source file in the streams-0.9.2.4 distribution:
1 static int
2 bufmod_srv(queue_t *q)
3 {
4 mblk_t *mp;
5
6 while ((mp = getq(q))) {
7 if (likely
8 (mp->b_datap->db_type >= QPCTL
9 || bcanputnext(q, mp->b_band))) {
10 putnext(q, mp);
11 continue;
12 }
13 putbq(q, mp);
14 break;
15 }
16 return (0);
17 }
The operation of the bufmod(4) module is described in the bufmod(4) manual page. The write qi_srvp() procedure passes all messages downstream and performs flow control and buffering.
See the src/modules directory in the streams-0.9.2.4 distribution for more working examples of module service procedures. Example #2 - Driver qi_srvp()The following example of a driver qi_srvp() procedure comes directly from the lower read side of the mux(4) multiplexing driver located in src/modules/mux source file in the streams-0.9.2.4 distribution: If the lower read put procedure encounters flow control on the queue beyond the accepting upper read queue, or if the lower read service procedure is invoked for a lower Stream that is not connected across the multiplexer, it places the message back on its queue and waits for the upper read queue service procedure to enable it when congestion has cleared, or when a connection is formed. If the upper read queue disconnects from the lower read queue (or has not connected yet), the procedure leaves these messages on the queue to (potentially) be processed by the Stream head after unlinking, or to be processed by an upper read queue after connection across the multiplexer.
1 static int
2 mux_lrsrv(queue_t *q)
3 {
4 struct mux *mux = q->q_ptr;
5 queue_t *rq = NULL;
6 mblk_t *mp;
7
8 read_lock(&mux_lock);
9 if (mux->other)
10 rq = mux->other->rq;
11 if (rq) {
12 while ((mp = getq(q))) {
13 if (mp->b_datap->db_type >= QPCTL
14 || bcanputnext(rq, mp->b_band)) {
15 putnext(rq, mp);
16 continue;
17 }
18 putbq(q, mp);
19 break;
20 }
21 } else
22 noenable(q);
23 read_unlock(&mux_lock);
24 return (0);
25 }
The operation of the mux(4) multiplexing driver is described in the mux(4) manual page.
See the src/drivers directory in the streams-0.9.2.4 distribution for more working examples of driver service procedures. SEE ALSOqueue(9), datab(9), qi_qopen(9), qi_qclose(9), qi_qadmin(9), qi_putp(9), qinit(9), streamtab(9), enableq(9), qenable(9), freeb(9), freemsg(9), dupmsg(9), put(9), putnext(9), putq(9), insq(9), qppq(9), getq(9), rmvq(9), putbq(9), flushq(9), flushband(9), enableq(9), qenable(9), noenable(9), enableok(9), canenable(9), runqueues(9), canput(9), canputnext(9), bcanput(9), bcanputnext(9), freezestr(9), unfreezestr(9), putctlnext(9), putctl1next(9), putctl2next(9), M_FLUSH(9), bufmod(4), mux(4), qprocson(9), qprocsoff(9), mp-streams(9), STREAMS(9). BUGSLinux Fast-STREAMS invocation of the qi_srvp() entry point has no known bugs. COMPATIBILITYThe qi_srvp() procedure is compatible with SVR 4.2[1] and implementations based on SVR 4[2], with the following portability considerations:
See STREAMS(9) for additional compatibility considerations. CONFORMANCEHISTORYThe qi_qsrvp_t type first appeared in OSF/1® 1.1[4]. The queue qi_srvp() service procedure first appeared in SVR 3[7]. REFERENCES
TRADEMARKS
Other trademarks are the property of their respective owners. IDENTIFICATION
Copyright©1997-2008OpenSS7 Corp.
All Rights Reserved.
Index
This document was created by man2html, using the manual pages. Time: 15:56:16 GMT, May 22, 2013 | ||||||||||||||||
| OpenSS7 SS7 for the Common Man |
| ||||||||||||||||
| Last modified: Sat, 01 Nov 2008 10:41:56 GMT © Copyright 1997-2007 OpenSS7 Corporation All Rights Reserved. |