Tools

29. ユーザー待ち行列へデータを送信する SNDUSRQ

ユーザー待ち行列( *USRQ ) はプロセス間でデータを共有するのに最も高速で
処理することができる有効な手段であるが、データを送信するためには
enq」という MI (マシン・インターフェース) を使用しなければならない。
enq を使用するには一般的には C 言語からしか呼び出すことはできないが
使用方法に精通しているユーザーも多くはないと思われるので
弊社で製品 EnterpriseServer で実際に使用されている SNDUSRQ という
名前の ANS-C によるプログラム・ソースを公開しよう。

【 SNDUSRQ ソース 】
------------------------------------------------------------------------
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 ソースである。

【 STRMYLOGCL 】
------------------------------------------------------------------------------------
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                                             
------------------------------------------------------------------------------------