spass
モジュールは,プットされたすべてのメッセージを
putnext()
プロシージャに引き渡す,簡単な STREAMS モジュールです。
spass
モジュールは,サービス・プロシージャが処理するために,putnext()
に対する呼び出しを遅延させます。
このモジュールには,フロー制御コードが組み込まれており,読み取り側および書き込み側の両方が,1 つのサービス・プロシージャを共用しています。
spass
モジュールのコードは,次のとおりです。
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/sysconfig.h>
static int spass_close();
static int spass_open();
static int spass_rput();
static int spass_srv();
static int spass_wput();
static struct module_info minfo = {
0, "spass", 0, INFPSZ, 2048, 128
};
static struct qinit rinit = {
spass_rput, spass_srv, spass_open, spass_close, NULL, &minfo
};
static struct qinit winit = {
spass_wput, spass_srv, NULL, NULL, NULL, &minfo
};
struct streamtab spassinfo = { &rinit, &winit };
cfg_subsys_attr_t bufcall_attributes[] = {
{, 0, 0, 0, 0, 0, 0} /* must be the last element */
};
int
spass_configure(op, indata, indata_size, outdata, outdata_size)
cfg_op_t op;
caddr_t indata;
ulong indata_size;
caddr_t outdata;
ulong outdata_size;
{
struct streamadm sa;
dev_t devno = NODEV;
if (op != CFG_OP_CONFIGURE)
return EINVAL;
sa.sa_version = OSF_STREAMS_10;
sa.sa_flags = STR_IS_MODULE | STR_SYSV4_OPEN;
sa.sa_ttys = 0;
sa.sa_sync_level = SQLVL_QUEUE;
sa.sa_sync_info = 0;
strcpy(sa.sa_name, "spass");
if ( (devno = strmod_add(devno, &spassinfo, &sa)) == NODEV ) {
return ENODEV;
}
return 0;
}
/* Called when module is popped or the Stream is closed */
static int
spass_close (q, credp)
queue_t * q;
cred_t * credp;
{
return 0;
}
/* Called when module is pushed */
static int
spass_open (q, devp, flag, sflag, credp)
queue_t * q;
int * devp;
int flag;
int sflag;
cred_t * credp;
{
return 0;
}
/*
* Called to process a message coming upstream. All messages
* but flow control messages are put on the read side service
* queue for later processing.
*/
static int
spass_rput (q, mp)
queue_t * q;
mblk_t * mp;
{
switch (mp->b_datap->db_type) {
case M_FLUSH:
if (*mp->b_rptr & FLUSHR)
flushq(q, 0);
putnext(q, mp);
break;
default:
putq(q, mp);
break;
}
return 0;
}
/*
* Shared by both read and write sides to process messages put
* on the read or write service queues. When called from the
* write side, sends all messages on the write side queue
* downstream until flow control kicks in or all messages are
* processed. When called from the read side sends all messages
* on its read side service queue upstreams until flow control
* kicks in or all messages are processed.
*/
static int
spass_srv (q)
queue_t * q;
{
mblk_t * mp;
while (mp = getq(q)) {
if (!canput(q->q_next))
return putbq(q, mp);
putnext(q, mp);
}
return 0;
}
/*
* Called to process a message coming downstream. All messages but
* flow control messages are put on the write side service queue for
* later processing.
*/
static int
spass_wput (q, mp)
queue_t * q;
mblk_t * mp;
{
switch (mp->b_datap->db_type) {
case M_FLUSH:
if (*mp->b_rptr & FLUSHW)
flushq(q, 0);
putnext(q, mp);
break;
default:
putq(q, mp);
break;
}
return 0;
}