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; }