OpenSS7
SS7 for the
Common Man
© Copyright 1997-2007 OpenSS7 Corporation All Rights Reserved.
Last modified: Sat, 01 Nov 2008 10:41:53 GMT
Home TopIndex FirstPrev Next LastMore Download Info FAQ Mail  Home -> Documentation -> Man Pages -> Manpage of APPQ
Quick Links

Download

SCTP

SIGTRAN

SS7

Hardware

STREAMS

Asterisk

Related

Package

Manual

FAQ

Man Pages

Applications

SS7 Stack

ISDN Stack

SIGTRAN Stack

VoIP Stack

MG Stack

SS7/ISDN Devices

IP Transport

Embedded Systems

OS

Documentation

FAQ

SIGTRAN

Design

Conformance

Performance

References

Man Pages

Manuals

Papers

Home

Overview

Status

Documentation

Resources

About

News

Manpage of APPQ

Description: Manual Page

Keywords: 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 compactpci


APPQ

Section: Linux Fast-STREAMS DDI/DKI (9)
Updated: 2008-10-31
Index Return to Main Contents

NAME

appq - append one STREAMS message after another

SYNOPSIS

#define _LIS_SOURCE
#include <sys/stream.h>

int appq(queue_t *q, mblk_t *emp, mblk_t *nmp);

ARGUMENTS

q

a pointer to a STREAMS message queue.
emp
a pointer to an existing message block on queue q.
nmp
a pointer to a new message block to append after emp on q.

INTERFACE

STREAMS, implementation extension.

DESCRIPTION

appq() appends the STREAMS message nmp just after the message emp already on queue q. If there is no message after emp in the queue q, or emp is NULL, this has the same effect as calling putq(9) with q and nmp.

appq() performs all of the normal STREAMS scheduler functions associated with putq(9) including enabling of the queue, q, when the first message or a high priority message is placed on the queue. If queue scheduling has been disabled with noenable(9), only high priority messages will result in the queue being scheduled.

Message Queueing Priority

STREAMS queues messages based on message queueing priority. There are three priority classes for messages that can be tested with pcmsg(9):

1.High Priority(pcmsg(db_type) != 0 && b_band == 0)
2.Normal Priority(pcmsg(db_type) == 0 && b_band >= 0)
3.Ordinary(pcmsg(db_type) == 0 && b_band == 0)

appq() only examines the message class and priority band of the first message block of a message. If a high priority message is passed to appq() with a non-zero b_band value, b_band is reset to zero (0) before placing the message on the queue. If a normal priority message is passed to appq() with b_band value greater than the number of qband(9) structures associated with the queue, appq() attempts to allocate a new qband(9) structure for each band up to and including the band of the message. (But, see COMPATIBILTY , below.)

Messages must be placed in order in the queue. If the message is a high priority message, it must be placed on the queue with other high priority messages and ahead of normal priority and ordinary messages. If the message is a normal priority message with a non-zero b_band, it must be placed with other messages in the queue band. If the message is a ordinary message (with a zero b_band), it must be placed with other ordinary messages, after all other messages. Attempts to insert a message out of order in the queue with appq() will cause appq() to fail.

Placing the first message for a queue band onto the queue can result in the allocation of a qband(9) structure to provide flow control accounting for the queue band. Failure to allocate a qband(9) structure can cause appq() to fail. Failure can be avoided by ensuring that a qband(9) structure exists for the band, b_band, using strqget(9) or strqset(9).

Whether a qband(9) exists for a given b_band can be determined by examining the q_nband member of the queue(9) structure. When q_nband>=b_band, a structure exists; when q_nband<b_band, one needs to be allocated.

Flow Control

If a high priority message is placed onto the queue, the queue will always be enabled, as with qenable(9); that is, the queue's qi_srvp(9) procedure will be scheduled if it exists (and is not already scheduled). This is true for appq(), insq(9), putq(9), and putbq(9). Because this is true, a high priority message should never be placed back on a queue by the queue's qi_srvp(9) procedure with putbq(9), otherwise and indefinite loop could result.

appq() is allowed to enable the queue (QNOENB is not set) if the message is a normal priority message, or the QWANTR flag is set indicating that the qi_srvp(9) procedure is ready to read the queue.

If a normal priority message with a non-zero b_band is placed onto an empty queue band, the queue will be enabled, as with enableq(9); that is, the queue's qi_srvp(9) procedure will be scheduled if it exists (and is not already scheduled) and the QNOENB flag has not been set for the queue with noenable(9).

If a ordinary message with a zero b_band is placed onto an empty queue and the QWANTR flag is set for the queue, then the queue will be enabled, as with enableq(9); that is, the queue's qi_srvp(9) procedure will be scheduled if it exists (and is not already scheduled) and the QNOENB flag has not been set for the queue with noenable(9). Another way of putting this is that appq() will enable the queue if the queue is not inhibited with noenable(9) and one of the following conditions also holds true:

*
The driver or module has just been opened for the first time: that is, the queue is empty and has always been empty.
*
getq(9) found no message queued on its last call and no message has been queued since.

When an ordinary message is enqueued by appq(), it will cause the qi_srvp(9) procedure to be scheduled only if the queue was previously empty, and a previous getq(9) call returns NULL (that is, the QWANTR flag is set). If there are messages on the queue, appq() presumes that the qi_srvp(9) procedure is blocked by flow control and the procedure will be rescheduled by STREAMS when the block is removed.

As a general rule for appq(), insq(9), putq(9), and putbq(9), the queue is enabled whenever the message placed on the message queue becomes the first message on the queue, unless the message is a normal priority message and the queue has been disabled with noenable(9), or the message was placed with putbq(9).

USAGE

appq() is an LiS-specific function that should not be called by portable STREAMS drivers and modules. Instead, the driver or modules should use the DDI/DKI defined insq(9).

RETURN

Upon success, appq() returns true (1) and the message pointed to by mp has been appended into the queue.

Upon failure, appq() returns false (0) and the message pointed to by mp remains unaltered.

ERRORS

appq() fails silently if nmp is associated with a non-existent queue band and a queue band structure could not be allocated. This error can be avoided by assuring that a queue band structure exists with strqset(9) before the call to appq() is made with a banded nmp.

CONTEXT

appq() can be called from any context, including process context, module procedures, callouts, callbacks, soft interrupts, and interrupt service routines.

MP-STREAMS

appq() is MP-safe; however, the caller is responsible for the validity of the passed in queue and message pointers, and exclusive access to the passed in messages.

Validity of q

The caller is responsible for the validity of the passed in queue pointer, q. q is valid from all procedures synchronous on q, including qi_qopen(9), qi_qclose(9), qi_putp(9), qi_srvp(9), procedures and synchronous callback functions.

For process context, asynchronous callback functions, soft interrupts (tasklets and bottom halves), and interrupt service routines, that is, when calling appq() from a non-STREAMS context, any valid queue pointer, q, can be passed to appq(); however, the caller must ensure that the queue pointer remains valid across the call. In general, q is valid from the moment that qprocson(9) returns until the moment that qprocsoff(9) is called, so, if the non-STREAMS code sections are passed a pointer from q's qi_qopen(9) procedure and invalidated by its qi_qclose() procedure, validity can be ensured. (This is the case with timeout(9) and bufcall(9) asynchronous callbacks. These callbacks are passed a queue pointer only after qi_qopen(9) and must be cancelled before qi_qclose(9) returns.)

Otherwise, from outside of STREAMS context, it is still possible to derive a queue pointer from a validated queue pointer, provided that the Stream is frozen with a call to freezestr(9). Under Linux Fast-STREAMS[1], it is permissible to call appq() on a Stream that is frozen with freezestr(9), and freezestr(9) can be called from any context. appq() takes a recursive freeze lock that can be acquired by the caller when the Stream is frozen. If another thread has the Stream frozen with freezestr(9), the calling processor will spin until the Stream is thawed by the other thread with unfreezestr(9).

Validity and Exclusion for emp

Ensuring validity and exclusion for emp is difficult on SMP systems, because concurrent calls to appq(9), insq(9), putq(9), putbq(9), can change emp->b_next and rmvq(9), getq(9), flushq(9), flushband(9), can change emp->b_prev and invalidate a previous emp pointer dereference (e.g., by removing the message from the queue and freeing it).

Validity and exclusion for emp on both UP and SMP systems can be readily ensured by freezing the queue, q, using freezestr(9) before referencing emp, and across the call to appq(). However, it is also possible to ensure validity and exclusion with qwriter(9), streams_put(9), with appropriate synchronization boundaries (STR_PERQUEUE or D_MTPERQ), or with module private locks. Because freezing the Stream is not the only way to provide the necessary assurances, Linux Fast-STREAMS[1] does not require that the Stream be frozen by the caller, although it is recommended.

Similar synchronization is necessary for the use of appq(), insq(9), and rmvq(9).

appq() protects its dereferencing of the emp->b_next pointer with the queue write lock, making it safe to be called concurrent with putq(9), putbq(9), insq(9), getq(9), flushq(9), flushband(9), rmvq(9) or a concurrent call to appq().

Validity and Exclusion for nmp

Validity of the nmp pointer and exclusive access to the message pointed to by nmp is normally assured in the usual ways: If nmp was just allocated using allocb(9) or esballoc(9), or, if nmp was just removed from a message queue with getq(9) or rmvq(9), then exclusion and validity is assured.

IMPLEMENTATION

appq() is implemented under Linux Fast-STREAMS using insq(9). Essentially, appq(q,emp,nmp) is the same as insq(q,emp?emp->b_next,nmp) except that the emp dereference is protected by the queue write lock.

NOTICES

appq() is a LiS-specific function: _LIS_SOURCE must be defined before including DDI/DKI include files to expose this symbol. Linux Fast-STREAMS must also have been compiled with CONFIG_STREAMS_COMPAT_LIS or CONFIG_STREAMS_COMPAT_LIS_MODULE defined.

appq() called with an existing message pointer, emp, argument that is not on the queue, q, will panic or destabilize the kernel.

EXAMPLES

None.

SEE ALSO

flushband(9), flushq(9), freezestr(9), getq(9), insq(9), noenable(9), putbq(9), putq(9), putq(9), qwriter(9), rmvq(9), streams_put(9), strqset(9).

BUGS

appq() has no known bugs.

COMPATIBILITY

appq() is compatible with LiS with the following portability considerations:

---
When a banded message (a normal priority message, with a non-zero b_band) is placed on a queue with putq(9), putbq(9), insq(9), or appq(), and a qband(9) structure does not exist for the band corresponding to b_band, appq() tries to allocate qband(9) structures for all non-existent bands up to and including the band of the message and places the resulting qband(9) structures into a reverse sorted q_bandp list on the queue(9). q_nband is adjusted accordingly and always reflects the highest allocated band.
This is consistent with the description in the SVR 4 STREAMS Programmer's Guide, which states: "If a mesages is passed to appq() with a b_band value that is greater than the number of qband(9) structures associated with the queue [member q_nband in the queue(9) structure], appq() tries to allocate a new qband(9) structure for each band up to and including the band of the message."[2]
Solaris® allocates qband(9) structures up to an including b_band, and maintains the q_nband member of the queue(9) structure. It is safe to assume that other UNIX® implementations based on SVR 4 follow SVR 4 as does Solaris®.
LiS allocates qband(9) structures on demand, links them in a sparse array, and will also reuse qband(9) structures that were previously allocated for bands that are currently empty. This is not a good approach because user established band high- and low-water marks will be reset to those of the queue(9) structure when a subsequent message is place on the reused band. Also, it is difficult to predict when appq(), insq(9), putq(9), putbq(9), will fail as a result of failure to allocate a qband(9) structure. This LiS bug is not perpetuated in Linux Fast-STREAMS[1].
Portable STREAMS drivers and modules can rely on intermediate band strutures being allocated when a normal priority message is placed on a queue using appq(), and may examine the q_nband member of the queue(9) structure to determine whether a qband(9) exists for a given band number.
Portable STREAMS drivers and modules will use Linux Fast-STREAMS[1] instead of LiS[3].
---
appq() orders the qband(9) structures in the list pointed to by the q_bandp member of the queue(9) structure from highest band number to lowest band number. This ensures that higher priority qband(9) structures can be accessed faster than lower priority qband(9) structures. Solaris®[4] lists qband(9) structures from lowest to highest priority, without gaps (see consideration of allocation above). LiS[3] lists qband(9) structures from most recently allocated/reused to least recently allocated/reused. Neither the Solaris® nor the LiS approach is very efficient.
Portable STREAMS drivers and modules will not depend on the ordering of qband(9) structures within the q_bandp list on the queue(9) structure, and, will not access qband(9) or queue(9) members directly, but will use the portable strqget(9) and strqset(9) utilities instead.
---
appq() is an LiS-specific function that is also provided by Linux Fast-STREAMS.
Portable STREAMS drivers and modules should not call this function.
---
appq() called with a NULL q or nmp argument will panic or destabilize the kernel. appq() called with a NULL emp argument will have the same effect as putq(q, nmp). Under LiS, appq() called with a NULL q, emp or nmp argument, will fail silently (losing a reference to nmp).
Portable STREAMS drivers and modules should not pass invalid arguments.
---
appq() called with a non-NULL q pointer that does not point to a valid queue structure will result in destabilization of the kernel. Under LiS, appq() called with a non-NULL q pointer that does not point to a valid queue structure will result in the silent freeing of the emp message block.
Portable STREAMS drivers and modules should not pass invalid arguments.
---
appq() called with the the QNOENB flag set (see noenable(9)) will schedule the queue qi_srvp(9) procedure if a high priority message is appended. LiS does not schedule the queue qi_srvp(9) procedure when a high priority message is appended to the queue.
Portable STREAMS drivers and modules should not rely upon the queue qi_srvp(9) procedure not being scheduled when a high priority message is appended.
---
appq() protects dereferencing of the emp->b_next pointer with the queue write lock, making it safe to be called concurrent with putq(9). Under LiS, appq() does not protect dereferencing of the emp->b_next pointer with the queue spin lock making it unsafe to be called concurrent with putq(9).
Portable STREAMS drivers and modules will use Linux Fast-STREAMS instead of LiS.
---
All versions of LiS contain the bug that they keep track of message queue counts, q_count, qb_count, in terms of the sum of the absolute sizes of the data buffers referenced by message blocks, (db_lim - db_base), and not the sizes of the message blocks themselves, (b_wptr - b_rptr), which does not conform to SVR 4.2 STREAMS[5]. See msgsize(9). No other implementation has this bug.
Portable STREAMS applications programs, drivers and modules will use Linux Fast-STREAMS instead of LiS.
---
Binary compatibility is not guaranteed.

See STREAMS(9) for additional compatibility information.

CONFORMANCE

LfS[1] and LiS[3] source code.

HISTORY

appq() first appeared in LiS.

Before OpenSS7 release LIS-2.16.18-17, appq() returned void. As of OpenSS7 release LIS-2.16.18-17, appq() returns int.

REFERENCES

[1]
streams-0.9.2, Linux Fast-STREAMS (LfS) 0.9.2 Source Code, Brian Bidulock, ed., OpenSS7 Corporation. <http://www.openss7.org/>
[2]
SVR 4, UNIX® System V Release 4 STREAMS Programmer's Guide, 1990, (Englewood Cliffs, New Jersey), AT&T UNIX System Laboratories, Inc., Prentice Hall.
[3]
LIS 2.18, Linux STREAMS (LiS) 2.18.6 Source Code, Brian Bidulock, ed., OpenSS7 Corporation. <http://www.openss7.org/>
[4]
Solaris® 8, Solaris 8 Docmentation, 2001, (Santa Clara, California), Sun Microsystems, Inc., Sun. <http://docs.sun.com/>
[5]
SVR 4.2, STREAMS Programmer's Guide, 1992, (Englewood Cliffs, New Jersey), AT&T UNIX System Laboratories, Inc., Prentice Hall.

TRADEMARKS

OpenSS7tm
is a trademark of OpenSS7 Corporation.
Linux®
is a registered trademark of Linus Torvalds.
UNIX®
is a registered trademark of The Open Group.
Solaris®
is a registered trademark of Sun Microsystems.

Other trademarks are the property of their respective owners.

IDENTIFICATION


Linux Fast-STREAMS: Package streams version 0.9.2.4 released 2008-10-31.

Copyright©1997-2008OpenSS7 Corp. All Rights Reserved.
(See roff source for permission notice.)



Index

NAME
SYNOPSIS
ARGUMENTS
INTERFACE
DESCRIPTION
Message Queueing Priority
Flow Control
USAGE
RETURN
ERRORS
CONTEXT
MP-STREAMS
Validity of q
Validity and Exclusion for emp
Validity and Exclusion for nmp
IMPLEMENTATION
NOTICES
EXAMPLES
SEE ALSO
BUGS
COMPATIBILITY
CONFORMANCE
HISTORY
REFERENCES
TRADEMARKS
IDENTIFICATION

This document was created by man2html, using the manual pages.
Time: 05:12:05 GMT, June 18, 2013
OpenSS7
SS7 for the
Common Man
Home TopIndex FirstPrev Next LastMore Download Info FAQ Mail  Home -> Documentation -> Man Pages -> Manpage of APPQ
Last modified: Sat, 01 Nov 2008 10:41:53 GMT
© Copyright 1997-2007 OpenSS7 Corporation All Rights Reserved.