Manpage of QI_QCLOSE
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
QI_QCLOSE
Section: Linux Fast-STREAMS DDI/DKI (9)
Updated: 2008-10-31
Index
Return to Main Contents
NAME
close, qi_qclose, qi_close_t
-
STREAMS driver or module close routine
SYNOPSIS
-
#include <sys/stream.h>
-
typedef int (*qi_qclose_t) (queue_t *q, dev_t *devp, int oflag);
ARGUMENTS
- q
pointer to the driver or module instance queue pair;
- devp
- pointer to the driver device number; and,
- oflag
- caller file flags.
INTERFACE
STREAMS.
DESCRIPTION
qi_qclose()
is one of 5 principal synchronous entry points into a
STREAMS
driver or module that form part of the definition of the driver or module. The principal entry
points are:
qi_qopen(9),
qi_qclose(),
qi_qadmin(9),
qi_putp(9),
and
qi_srvp(9).
The
qi_qclose()
routine is specified in the read queue
qinit(9)
structure that is associated with 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_qclose()
routine is called by
STREAMS
before a queue pair forming an instance of the driver or module is removed from the Stream and
deallocated. This routine permits the driver or module to perform whatever driver or module private
cleanup or deallocation is necessary before the queue pair is deactivated and removed from the
Stream. Error numbers returned by this function are generally discarded.
(GNU/Linux
cannot return an error number to
close(2s)
after the release operation has begun.)
Alldriversandmodulesrequirea
qi_qclose()
routine to be defined. See
qinit(9).
Following are the arguments to the driver or module
qi_qclose()
routine:
- q
- is a pointer to the read queue of an active queue pair forming an instance of the driver or module.
- devp
- is a pointer to the
dev_t(9)
formatted device number.
devp
points to the device number of the driver in the Stream.
- oflag
- contains the current file flags (of the last closer) and will contain a bitwise OR of one or more of
the following flags:
-
- FREAD
- the
STREAMS
special file was opened for read.
- FWRITE
- the
STREAMS
special file was opened for write.
- FEXCL
- the
STREAMS
special file was opened for exclusive access.
- FNDELAY
- the
STREAMS
special file was opened for non-blocking operation.
STREAMS
invokes a driver or module
qi_qclose()
routine when the last
close(2s),
I_UNLINK(7),
I_PUNLINK(7),
or
fdetach(3),
operation causes the Stream to be dismantled.
STREAMS
also invokes the
qi_qclose()
routine of a module when popped from a Stream's module stack with the
I_POP(7)
ioctl(2s)
system call.
The
qi_qclose()
routine is called in the following circumstances:
- (1)
- The
qi_qclose()
routine of a module is invoked by a user executing a
I_POP(7)
ioctl(2s)
operation.
- (2)
- The
qi_qclose()
routine of a module is invoked when the Stream is being dismantled and the module is on the Stream's
module stack.
- (3)
- The
qi_qclose()
routine of a driver is invoked when the Stream is being dismantled.
Note that Streams are dismantled when a
close(2s),
I_UNLINK(7),
I_PUNLINK(7),
or
fdetach(3),
operation results in the release of the last reference to the Stream.
When the
qi_qclose()
routine is invoked by
STREAMS
for a queue pair, the following conditions prevail:
- (1)
- If the
qi_qclose()
routine is invoked as the last close of (release of the last reference to) a driver, the
STRCLOSE
bit will be set in the Stream head
stdata(9)
structure, preventing all subsequent opens of the Stream, and the Stream will be removed from the
file pointer prior to the call to
qi_qclose().
- (2)
- If the
qi_qclose()
routine is for a module
I_POP(7)
operation, the
STRWOPEN
bit will be held in the Stream head
stdata(9)
structure, preventing all other plumbing operations for the same Stream.
- (3)
- The
q_ptr
members of each queue in the queue pair still point to module private data, or are preserved as
whatever the driver or module
qi_qopen(9)
routine set for these private pointers.
- (4)
- The queue pair will still be fully inserted into the Stream and queue procedures,
qi_putp(9)
and
qi_srvp(9),
will still be active.
It takes a call to
qprocsoff(9)
from the
qi_qclose()
routine to disable
qi_putp(9)
and
qi_srvp(9)
procedures and half-delete the queue pair from the Stream. The queue pair will be half-deleted by
qprocsoff(9)
in the sense that the
q_next
pointers in the queue pair will still point to the Stream head and the top of the module stack or
driver, however, the
q_next
pointers of the Stream head and top of the module stack or driver will bypass the half-deleted queue
pair.
- (5)
- The
qi_qclose()
procedure is called with a blockable, no locks held, user context: the user context being the user
that caused the routine to be invoked. That is, the same user whose credentials are pointed to by
crp.
The file flags for the user file descriptor associated with the call are contained in the
oflag
argument. It is possible, in a non-portable way, to obtain a reference to the file pointer and
inode associated with the system call that invoked the routine. This is always available in the
sd_file
and
sd_inode
members of the Stream head
stdata(9)
structure. The Stream head
stdata(9)
structure can be located using the
qstream(9)
macro.
- (6)
- If an
mp-streams(9)
synchronization specification has been made for the driver or module that include an inner
synchronization barrier,
STREAMS
enters the inner barrier shared or exclusive (according to the specification) before the
qi_qclose()
routine is called, and leaves the inner barrier after the call returns.
USAGE
The following sections provide some guidelines for the design of
qi_qclose()
routines for a driver or module:
Modules and Drivers
Following are some design guidelines for both driver and module
qi_qclose()
routines:
- *
- Before detaching or deallocating resources required by a driver or module
qi_putp(9),
qi_srvp(9),
procedure or callback function, the
qi_qclose()
routine must call
qprocsoff(9).
- *
- Before returning, the
qi_qclose()
routine must cancel all outstanding
timeout(9)
and
bufcall(9)
callbacks associated with the queue pair.
- *
- The driver or module is allowed to sleep in the
qi_close()
procedure, but must not sleep indefinitely. When the routine sleeps awaiting arrival of a message
on a message queue, it should use
qwait_sig(9)
or
qwait(9).
qwait_sig(9)
and
qwait(9)
must be used before
qprocsoff(9)
is called.
- *
- The
qi_qclose()
routine should deallocate any resources that were allocated as part of the
qi_qopen(9)
routine, as well as any resources that where allocated while the driver or module was in operation.
- *
- q->q_ptr
and
WR(q)->q_ptr
should be
NULL
before returning from the routine.
- *
- All deallocations and cancellations must occur, regardless of the return value from the routine.
(The return value from the routine will be ignored by
Linux Fast-STREAMS.)
Modules
Following are some design guidelines for module
qi_qclose()
routines:
- *
- Modules must follow the general guidelines listed above under
``Modules and Drivers''.
- *
- The
devp
argument points to the device number of the driver instance in the Stream from which the module is
being removed.
Altering this device number will have no effect.
- *
- The
oflag
argument contains the file flags for the file descriptor that is being used as an argument to the
ioctl(2s)
system call invoked to
I_POP(7)
the module, or was an argument to the call to the
close(2s),
I_UNLINK(7),
I_PUNLINK(7),
or
fdetach(3),
operation that resulted in dismantling of the Stream containing the module.
.
Drivers
Following are some design guidelines for driver
qi_qclose()
routines:
- *
- Drivers must follow the general guidelines listed above under
``Modules and Drivers''.
- *
- The
devp
argument points to the device number of the driver instance which is being removed.
Altering this device number will have no effect.
- *
- The
oflag
argument contains the file flags for the file descriptor that is being used as an argument to the
close(2s),
I_UNLINK(7),
I_PUNLINK(7),
or
fdetach(3),
operation that resulted in dismantling of the Stream containing the driver.
RETURN
A driver or module
qi_qclose()
routines returns zero (0) for success, or a non-zero, positive (or negative), error number.
ERRORS
When a driver or module
qi_qclose()
routine fails, it returns a non-zero, positive (or negative), error number.
This error number is ignored by
Linux Fast-STREAMS.
CONTEXT
qi_qclose()
is only called by
STREAMS
in a blockable, no locks held, user context, with the
STRWOPEN
or
STRCLOSE
bit held in the Stream head private structure
stdata(9),
(to prevent other simultaneous opens and closes of the same Stream).
MP-STREAMS
Synchronized Modules and Drivers
If
mp-streams(9)
synchronization has been specified for the driver or module, the inner synchronization barrier, if
any, is entered shared or exclusive per the synchronization specification for the driver or module,
across the call to the driver or module
qi_qclose()
routine. If synchronization has not been specified for the driver or module (that is, the module or
driver is specified as MP-safe), the
qi_qclose()
routine is invoked without synchronization.
MP-Safe Modules and Drivers
The discussion that follows applies to the MP-safe driver or module under
Linux Fast-STREAMS:
qi_qclose()
is only called by
STREAMS
in a blockable, no locks held, user context, with the
STRWOPEN
or
STRCLOSE
bit held in the Stream head private structure
stdata(9),
(to prevent other simultaneous opens and closes of the same Stream).
Driver an module
qi_qclose()
routines are always invoked single-threaded and exclusive within a Stream (and with respect to
itself, and the
qi_qopen(9)
routine) in accordance with description for
SVR 4[1],
as described in
``The Magic Garden Explained''[2].
This is also consistent with exclusive open/close access under
Solaris®[3].
Only one
plumbing
[qopen(9),
qclose(9),
I_LINK(7),
I_PLINK(7),
I_UNLINK(7),
I_PUNLINK(7),
fattach(3),
fdetach(3)]
operation at a time can be executing for a given Stream. So, for example, data structures accessed
only by a
plumbing
operation, and which are private to a queue pair or Stream, do no need protective locks.
On the other hand, each
qi_qclose()
routine must be reentrant as it can run concurrent with any
plumbing
operation on a different Stream, for a different queue pair instance,
q,
of the same driver or module.
Unless
mp-streams(9)
synchronization is used, a
qi_qclose()
routine can run concurrent with any
qi_putp(9),
qi_srvp(9),
or
synchronous or asynchronous callback functions for a separate instance of the driver or module.
Before
qprocsoff(9)
has been called,
qi_putp(9),
qi_srvp(9),
or
synchronous or asynchronous callback functions for the same instance of the driver or module may run
concurrent with the
qi_qclose()
routine.
Protective locks should be used on any data structures that a shared between the
qi_qclose()
routine and a different instance of a
plumbing
operation, or a different instance of a
qi_putp(9),
qi_srvp(9),
or callback procedure, or the same instance of a
qi_putp(9),
qi_srvp(9),
or callback procedure, before
qprocsoff(9)
has been called.
See
EXAMPLES ,
below for an example use of locking within the
qi_qclose()
routine.
See
mp-streams(9),
for more information on driver and module synchronization.
NOTICES
A driver or module
qi_qclose()
routine 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
close(2s)
and
I_POP(2s)
for indirect methods of invoking this routine.
STYLE
It is common practise to name
qi_qclose()
routines
"prefixclose(),"
(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).
EXAMPLES
Example #1 - Module qi_qclose()
The following example of a module
qi_qclose()
routine comes directly from the
pipemod(4)
module located in the
src/modules/pipemod.c
source file in the
streams-0.9.2.4
distribution:
1 static int
2 pipemod_close(queue_t *q, int oflag, cred_t *crp)
3 {
4 (void) oflag;
5 (void) crp;
6 if (!q->q_ptr)
7 return (ENXIO);
8 qprocsoff(q);
9 q->q_ptr = WR(q)->q_ptr = NULL;
10 return (0);
11 }
- Line 6-7:
- The module checks the existence of a
q_ptr
value or returns an error. This is for compatibility with
LiS,
which call
qi_qclose()
procedures with the wrong conditions in some circumstances (particularly for pipes).
This check is not necessary for
Linux Fast-STREAMS.
- Line 8:
- qprocsoff(9)
is called to disable procedures before removing the module private pointers.
- Line 9-10:
- The module private pointers are nulled and the routine returns.
-
- Note that, since no variables global another Stream are referenced, no locks are taken.
See the
src/modules
directory in the
streams-0.9.2.4
distribution for more working examples of module close routines.
Example #2 - Driver qi_qclose()
The following example of a driver
qi_qclose()
routine comes directly from the
sad(4)
driver located in the
src/drivers/sad.c
source file in the
streams-0.9.2.4
distribution:
1 static int
2 sad_close(queue_t *q, int oflag, cred_t *crp)
3 {
4 struct sad *sad = q->q_ptr;
5
6 qprocsoff(q);
7 q->q_ptr = WR(q)->q_ptr = NULL;
8 sad->assigned = 0;
9 sad->iocstate = 0;
10 return (0);
11 }
- Line 4:
- The driver obtains a reference to the module private data from the
q_ptr
field.
- Line 6:
- qprocsoff(9)
is called to disable procedures before removing the driver private pointers.
- Line 7-10:
- The driver private pointers are nulled and the driver state information reset,
and the routine returns.
-
- Note that, since no variables global another Stream are referenced, no locks are taken.
See the
src/drivers
directory in the
streams-0.9.2.4
distribution for more working examples of driver close routines.
SEE ALSO
qi_qopen(9),
qi_qadmin(9),
qi_putp(9),
qi_srvp(9),
qinit(9),
streamtab(9),
dev_t(9),
errno(3),
open(2s),
close(2s),
qopen(9),
qclose(9),
I_LINK(7),
I_PLINK(7),
I_UNLINK(7),
I_PUNLINK(7),
fattach(3),
fdetach(3),
I_POP(7),
ioctl(2s),
stdata(9),
qprocsoff(9),
qstream(9),
timeout(9),
bufcall(9),
qwait(9),
qwait_sig(9),
pipemod(4),
sad(4),
mp-streams(9),
STREAMS(9).
BUGS
Linux Fast-STREAMS
invocation of the
qi_qclose()
entry point has no known bugs.
(Note that it is possible that the inode reference to the Stream should not be removed before
calling the
qi_qclose()
routine for the driver. A concurrent
open(2s)
of the same device number could result in the creation of a new Stream and the invocation of
qi_qopen(9)
with the same device number as is being closed. This could confuse some
qi_qopen(9)
routines.)
COMPATIBILITY
The
qi_qclose()
routine is compatible with
SVR 4.2[4]
and implementations based on
SVR 4[1],
with the following portability considerations:
- ---
- SVR 4.2[5]
did not define a type for the prototype of a queue
qi_qclose(9)
routine. This was an embellishment that first appeared in
OSF/1® 1.1[6],
and propagated to
AIX®[7]
and
HP-UX®[8].
-
- Portable
STREAMS
drivers and modules will not directly reference the
qi_qclose_t
type.
- ---
- GNU/Linux
cannot return any error number returned from the
qi_qclose()
routine to the user in
errno(3)
upon return from the
close(2s)
call.
This is a
GNU/Linux
limtation.
-
- Portable
STREAMS
drivers and modules will not expect any error number returned to in any way affect the
returned
errno(3)
value nor the behaviour of the
close(2s)
system call.
Portable
STREAMS
drivers and modules should always return zero
(0)
from the
qi_qclose()
routine.
- ---
- Linux Fast-STREAMS
does not (yet) support the older
SVR 3-style
prototype. All
qi_qclose()
routines must be written to the
SVR 4-style
prototype, regardless of the setting of the driver or module
xxxflag,
contrary to the description in the
SVR 4 SPG[1].
-
- Portable
STREAMS
drivers and modules will use only the
SVR 4-style
prototype, and will always define the
xxxflag.
- ---
- Because a number of the primary data structures and types have different definitions on the
GNU/Linux
system, binary compatibility is not guaranteed.
See
STREAMS(9)
for additional compatibility considerations.
CONFORMANCE
SVR 4.2 MP EFT[4].
HISTORY
The
qi_qclose_t
type first appeared in
OSF/1® 1.1[6].
The queue
qi_qclose()
close routine first appeared in
SVR 3[9].
REFERENCES
- [1]
- SVR 4,
UNIX® System V Release 4 STREAMS Programmer's Guide, 1990, (Englewood Cliffs, New Jersey), AT&T UNIX System Laboratories, Inc., Prentice Hall.
- [2]
- Magic Garden,
The Magic Garden Explained: The Internals of UNIX® System V Release 4 / An Open Systems Design, 1994, (Australia), B. Goodheart, J. Cox, Prentice Hall.
[ISBN 0-13-098138-9]
- [3]
- Solaris® 8,
STREAMS Programming Guide, August 1999, (Palo Alto, California), Sun Microsystems, Inc., Sun.
[Part No: 805-7478-05]
<http://docs-pdf.sun.com/>
- [4]
- USL DDI/DKI,
Device Driver Interface/Driver-Kernel Interface (DDI/DKI) Reference Manual for Intel Processors, 1992, (Englewood Cliffs, New Jersey), AT&T UNIX System Laboratories, Inc., Prentice Hall.
- [5]
- SVR 4.2,
STREAMS Programmer's Guide, 1992, (Englewood Cliffs, New Jersey), AT&T UNIX System Laboratories, Inc., Prentice Hall.
- [6]
- Digital® UNIX (OSF/1.2),
Digital UNIX: Network Programmers Guide, 1996, (Palo Alto, California), Digital Equipment Corporation, Hewlett-Packard Company.
<http://www.true64unix.compaq.com/docs/>
- [7]
- AIX® 5L Version 5.1,
AIX STREAMS Programmers Guide, 2001, (Boulder, Colorado), Internatonal Business Machines Corp., IBM.
<http://publibn.boulder.ibm.com/>
- [8]
- HP-UX STREAMS,
STREAMS Programmer's Guide -- HP 9000 and Integrity Server Computer Systems, October 2005, (Palo Alto, California), Hewlett-Packard Development Company L.P., HP.
<http://docs.hp.com/>
- [9]
- SVR 3,
UNIX® System V Release 3 Programmer's Manual, (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
- USAGE
- Modules and Drivers
- Modules
- Drivers
- RETURN
- ERRORS
- CONTEXT
- MP-STREAMS
- Synchronized Modules and Drivers
- MP-Safe Modules and Drivers
- NOTICES
- STYLE
- EXAMPLES
- Example #1 - Module qi_qclose()
- Example #2 - Driver qi_qclose()
- SEE ALSO
- BUGS
- COMPATIBILITY
- CONFORMANCE
- HISTORY
- REFERENCES
- TRADEMARKS
- IDENTIFICATION
This document was created by
man2html,
using the manual pages.
Time: 10:40:57 GMT, May 18, 2013