ユーザー待ち行列( *USRQ
) はプロセス間でデータを共有するのに最も高速で
処理することができる有効な手段であるが、データを送信するためには
「enq
」という MI (マシン・インターフェース) を使用しなければならない。
enq を使用するには一般的には C 言語からしか呼び出すことはできないが
使用方法に精通しているユーザーも多くはないと思われるので
弊社で製品 EnterpriseServer で実際に使用されている SNDUSRQ
という
名前の ANS-C
によるプログラム・ソースを公開しよう。
------------------------------------------------------------------------ 0001.00 #include <stdio.h> 0002.00 #include <stdlib.h> 0003.00 #include <string.h> 0004.00 #include <miqueue.h> 0005.00 #include <qusec.h> 0006.00 #include <miptrnam.h> 0007.00 #include <signal.h> 0008.00 0009.00 #define TRUE 0 0010.00 #define FALSE -1 0011.00 0012.00 void SNDUSR(char* usrq, char* usrqlib, char* snddta); 0013.00 int main(int argc, char *argv[]){ 0014.00 SNDUSR(argv[1], argv[2], argv[3]); 0015.00 } 0016.00 void SNDUSR(char* usrq, char* usrqlib, char* snddta) 0017.00 { 0018.00 _ENQ_Msg_Prefix_T e_msg_prefix; 0019.00 _SYSPTR queue; 0020.00 volatile _INTRPT_Hndlr_Parms_T ca; 0021.00 int err; 0022.00 0023.00 err=1; 0024.00 #pragma exception_handler(MONMSG, ca, 0, _C2_MH_ESCAPE, \ 0025.00 _CTLA_HANDLE) 0026.00 queue = rslvsp(_Usrq, usrq, usrqlib, _AUTH_ALL); 0027.00 e_msg_prefix.Msg_Len = strlen(snddta); 0028.00 enq(queue,&e_msg_prefix, snddta);/* SNDUSRQ*/ 0029.00 return; 0030.00 MONMSG: 0031.00 memset(snddta, 0, sizeof(snddta)); 0032.00 memcpy(snddta, "*ERROR", 6); 0033.00 return; 0034.00 } ------------------------------------------------------------------------
CRTCMOD MODULE(QTEMP/SNDUSRQ) SRCFILE(MYSRCLIB/QCSRC) AUT(*ALL)
CRTSRVPGM SRVPGM(MYLIB/SNDUSRQ) MODULE(QTEMP/SNDUSRQ) EXPORT(*ALL) ACTGRP(*CALLER) AUT(*ALL)
または
CRTPGM PGM(MYLIB/SNDUSRQ) MODULE(QTEMP/SNDUSRQ) ACTGRP(*NEW) AUT(*ALL)
としてサービス・プログラムとしてもプログラムとしても利用することができる。
プログラムとして作成した場合は実行は簡単であり、
CALL MYLIB/SNDUSRQ('USRQ名', 'ライブラリー名', '投入するデータ')
である。ただし「投入するデータ」は char*
として定義されているので、長さは任意である。
次は この SNDUSRQ を呼び出しているサンプルCLP ソースである。
------------------------------------------------------------------------------------ 0001.00 PGM PARM(&IPADR) 0002.00 /*---------------------------------------------------------*/ 0003.00 /* STRMYLOGCL : アクセス・ログの個別出力 */ 0004.00 /*---------------------------------------------------------*/ 0005.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(80) 0006.00 DCL VAR(&IPADR) TYPE(*CHAR) LEN(15) 0007.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1) 0008.00 DCL VAR(&INSTANSE) TYPE(*CHAR) LEN(10) 0009.00 DCL VAR(&QNAME) TYPE(*CHAR) LEN(11) 0010.00 DCL VAR(&QLIB) TYPE(*CHAR) LEN(11) 0011.00 DCL VAR(&SNDDTA) TYPE(*CHAR) LEN(256) 0012.00 DCL VAR(&NULL) TYPE(*CHAR) LEN(1) VALUE(X'00') 0013.00 DCL VAR(&STRPOS) TYPE(*DEC) LEN(3 0) VALUE(1) 0014.00 DCL VAR(&STRLEN) TYPE(*DEC) LEN(3 0) VALUE(10) 0015.00 DCL VAR(&PATLEN) TYPE(*DEC) LEN(3 0) VALUE(1) 0016.00 DCL VAR(&RESULT) TYPE(*DEC) LEN(3 0) 0017.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR)) 0018.00 0019.00 RTVJOBA TYPE(&TYPE) 0020.00 IF COND(%SST(&IPADR 1 5) *EQ '*CALC') THEN(DO) 0021.00 ASNET.COM/RTVDEVIP DEV(*CURRENT) IPADDR(&IPADR) 0022.00 ENDDO 0023.00 RTVDTAARA DTAARA(ASNET.USR/HTTPSVR (20 10)) + 0024.00 RTNVAR(&INSTANSE) 0025.00 CALL PGM(QCLSCAN) PARM(&INSTANSE &STRLEN &STRPOS + 0026.00 &NULL &PATLEN ' ' ' ' ' ' &RESULT) 0027.00 IF COND(&RESULT *NE 0) THEN(DO) /* + 0028.00 NULL を除去する */ 0029.00 CHGVAR VAR(%SST(&INSTANSE &RESULT 1)) VALUE(' ') 0030.00 ENDDO /* NULL を除去する */ 0031.00 CHGVAR VAR(&QNAME) VALUE(&INSTANSE *TCAT '_SIG' + 0032.00 *CAT &NULL) 0033.00 CHGVAR VAR(&QLIB) VALUE('QUSRTEMP ' *CAT &NULL) 0034.00 CHGVAR VAR(&SNDDTA) VALUE('STRMYLOG=' *CAT + 0035.00 &IPADR *TCAT &NULL) 0036.00 CALL PGM(ASNET.COM/SNDUSRQ) PARM(&QNAME &QLIB + 0037.00 &SNDDTA) 0038.00 CHGVAR VAR(&MSG) VALUE(&IPADR *TCAT + 0039.00 ' のアクセス・ログ出力を開始しました。 ') 0040.00 GOTO SNDMSG 0041.00 0042.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) 0043.00 SNDMSG: 0044.00 IF COND(&TYPE *EQ '0') THEN(DO) 0045.00 SNDPGMMSG MSG(&MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP) 0046.00 ENDDO 0047.00 ELSE CMD(DO) 0048.00 SNDPGMMSG MSG(&MSG) TOMSGQ(*TOPGMQ) MSGTYPE(*DIAG) 0049.00 ENDDO 0050.00 ENDPGM ------------------------------------------------------------------------------------