Previous | Contents | Index |
This Pascal agent program signs in to ACMS, gathers transactions from various nodes, and generates a report after all transactions are complete. It shows the use of ACMS$WAIT.
Example 7-5 Pascal Agent Program that Uses ACMS$WAIT |
---|
[INHERIT('SYS$LIBRARY:STARLET','SYS$LIBRARY:ACMSPAS')] PROGRAM campus_transactions(INPUT,OUTPUT); { Program to gather transactions from various nodes. After all transactions are complete, generate a report } CONST pstring_length = 32; TYPE uword = [WORD] 0..65535; { Unsigned word } ubyte = [BYTE] 0..255; { Unsigned byte } pstring = PACKED ARRAY [1..pstring_length] OF CHAR; { descriptor datatype } desc_type = [BYTE(8)] RECORD length : [POS(0)] uword; dtype : [POS(16)] ubyte; class : [POS(24)] ubyte; ptr : [POS(32),UNSAFE] INTEGER; END; quad = PACKED ARRAY [0..1] OF [UNSAFE] INTEGER; nodes = (eku,nku,wku,ul,cmu); arg_list = PACKED ARRAY [0..3] OF [UNSAFE] INTEGER; VAR submitter_id : ACMS$SUBMITTER_ID; exchange_io_id: ACMS$EXCHANGE_IO_ID; status : [unsafe] INTEGER; status_block : ARRAY[eku..cmu] OF quad; selection_string : ARRAY[eku..cmu] of desc_type; padded_application_name : pstring; padded_task_name : pstring; status_string : ARRAY[eku..cmu] of desc_type; argument_list: ARRAY[eku..cmu] OF arg_list; i : nodes; { Run-time library output routine } [external] FUNCTION lib$put_output(%REF desc :desc_type):integer;extern; { Run-time library routine to signal errors } [ASYNCHRONOUS,EXTERNAL(LIB$SIGNAL)] PROCEDURE signal(%IMMED condition : INTEGER; %IMMED fao_parms : [UNSAFE,LIST] INTEGER);EXTERN; FUNCTION init_dyndesc:desc_type; { Function to initialize dynamic string desciptors } VAR temp : desc_type; BEGIN WITH temp DO BEGIN length := 0; class := dsc$k_class_d; dtype := dsc$k_dtype_t; ptr := 0; END; init_dyndesc := temp; END ; { function init_dyndesc} PROCEDURE call_task( SUBMITTER_ID :ACMS$SUBMITTER_ID; APPLICATION_NAME : pstring; TASK_NAME : pstring; VAR argument_list: arg_list; VAR STATUS_BLOCK : quad); { Procedure to perform an $acms$_call_a for the requested task } TYPE uword = [WORD] 0..65535; item_type = [BYTE (12)] RECORD buffer_length : [POS (0)] uword; item_code : [POS (16)] uword; buffer_address: [POS (32),UNSAFE] INTEGER; ret_length_adr: [POS (64),UNSAFE] INTEGER; END ; {item_type} list_type = [BYTE (16)] RECORD list : [POS (0) ] item_type; term : [POS (96)] INTEGER; END; {list_type} VAR status : [UNSAFE] INTEGER; proc_list : list_type; procedure_id : ACMS$PROCEDURE_ID; ACMS$EFN : [EXTERNAL] ubyte; BEGIN { call_task} { Build get procedure info list } WITH proc_list.list DO BEGIN buffer_length := acms$s_procedure_id; item_code := acms$k_proc_procedure_id; buffer_address := iaddress(procedure_id); ret_length_adr := 0; END ; {with proc_list} proc_list.term := 0; { Get procedure_id via acms$get_procedure_info } status := $ACMS$GET_PROCEDURE_INFO(SUBMITTER_ID := submitter_id, PACKAGE := application_name, procedure_ := task_name, item_list := proc_list); IF not odd(status) THEN SIGNAL(status); status := $ACMS$CALL_A(SUBMITTER_ID := submitter_id, PROCEDURE_ID := procedure_id, ARGUMENTS := argument_list, EFN := ACMS$EFN, COMP_STATUS := status_block); IF not odd(status) THEN SIGNAL(status); END ; { procedure call_task } BEGIN { main } { Init argument list for calls } FOR i := eku TO cmu DO BEGIN status_string[i] := init_dyndesc; selection_string[i] := init_dyndesc; argument_list[i][0] := 3; {Number of argument in list} argument_list[i][1] := IADDRESS(selection_string[i]); argument_list[i][2] := IADDRESS(status_string[i]); argument_list[i][3] := IADDRESS(exchange_io_id); END;{for} { sign into acms } status := $ACMS$SIGN_IN(SUBMITTER_ID := submitter_id); IF not odd(status) THEN SIGNAL(status); status := $ACMS$INIT_EXCHANGE_IO(SUBMITTER_ID := submitter_id, EXCHANGE_IO_ID := exchange_io_id ); IF not odd(status) THEN SIGNAL(status); padded_task_name := PAD ( 'ENROLLMENT_TRANSACTIONS', ' ', pstring_length ); padded_application_name := PAD ( 'EKU::TRANSACTIONS', ' ', pstring_length ); call_task(SUBMITTER_ID := submitter_id, application_name := padded_application_name, task_name := padded_task_name, argument_list := argument_list[eku], status_block := status_block[eku]); padded_application_name := PAD ( 'NKU::TRANSACTIONS', ' ', pstring_length ); call_task(SUBMITTER_ID := submitter_id, application_name := padded_application_name, task_name := padded_task_name, argument_list := argument_list[nku], status_block := status_block[nku]); padded_application_name := PAD ( 'WKU::TRANSACTIONS', ' ', pstring_length ); call_task(SUBMITTER_ID := submitter_id, application_name := padded_application_name, task_name := padded_task_name, argument_list := argument_list[wku], status_block := status_block[wku]); padded_application_name := PAD ( 'UL::TRANSACTIONS', ' ', pstring_length ); call_task(SUBMITTER_ID := submitter_id, application_name := padded_application_name, task_name := padded_task_name, argument_list := argument_list[ul], status_block := status_block[ul]); { Now wait for all the procedures to complete } FOR i := eku to ul DO BEGIN status := $ACMS$WAIT(COMP_STATUS := status_block[i]); { Wait for routine to complete} IF not odd(status) THEN SIGNAL(status); IF not odd (status_block[i][0]) THEN signal(status_block[i][0]) ELSE { Tell user status result of his request } LIB$PUT_OUTPUT(status_string[i]); END; { Call report generating routine } padded_task_name := PAD ( 'GENERATE_REPORTS',' ', pstring_length ); padded_application_name := PAD ( 'CMU::REPORTS', ' ', pstring_length ); call_task(submitter_id := submitter_id, application_name := padded_application_name, task_name := padded_task_name, argument_list :=argument_list[cmu], status_block := status_block[cmu]); status := $ACMS$WAIT(COMP_STATUS := status_block[cmu]); IF not odd(status) THEN SIGNAL(status); IF not odd (status_block[cmu][0]) THEN signal(status_block[cmu][0]) ELSE { Tell user status result of his request } LIB$PUT_OUTPUT( status_string[cmu]); status := $ACMS$TERM_EXCHANGE_IO(EXCHANGE_IO_ID := exchange_io_id); IF not odd(status) THEN SIGNAL(status); status := $ACMS$SIGN_OUT(SUBMITTER_ID := submitter_id); IF not odd(status) THEN SIGNAL(status); END. {main} |
The first part of this appendix describes six services used in earlier versions of ACMS and provides reference material for calling these services in agent programs. These six services have been replaced by ACMS$INIT_EXCHANGE_IO and ACMS$TERM_EXCHANGE_IO. You need to use the new services and arguments for all agent programs that call tasks that perform DECforms I/O.
The new services simplify systems interface programming and simplify program maintenance. Use them with TDMS, RI, and stream services as well as with DECforms. For information regarding the new services, see Chapter 4.
ACMS supports the superseded services for agent programs that are already implemented. It also supports the superseded task I/O arguments. In new agent programs, however, use the ACMS$INIT_EXCHANGE_IO and ACMS$TERM_EXCHANGE_IO services. Whenever practical, change the superseded services to ACMS$INIT_EXCHANGE_IO and ACMS_TERM_EXCHANGE_IO in existing agent programs.
Do not mix the new services and the superseded services indiscriminately. Any attempt to use a superseded service to close a call opened with the new service results in an invalid status message. Any attempt to use the new service to close a call opened with a superseded service results in a status message of invalid.
The second part of the appendix describes parameters that were passed into the task I/O argument of the ACMS$CALL and ACMS$START_CALL services in versions of ACMS earlier than Version 3.2. Beginning with ACMS Version 3.1, instead of passing a device name or stream ID to the task I/O argument, use the exchange I/O ID for tasks that perform request I/O, stream I/O, or terminal I/O.
Table A-1 lists the superseded services and gives a brief description of each.
Service Name | Description |
---|---|
ACMS$OPEN_RR | Opens a TDMS channel to a terminal and associates it with a submitter ID. Subsequent task selections for that submitter use the channel. |
ACMS$CLOSE_RR | Closes a TDMS channel to a terminal and disassociates it from a submitter ID. |
ACMS$CREATE_STREAM | Creates a stream and returns a stream ID. |
ACMS$CONNECT_STREAM | Establishes a stream connection on which the agent program and the EXC can exchange messages. This service returns a connect ID. |
ACMS$DISCONNECT_STREAM | Breaks a connection to a stream and invalidates the connect ID. |
ACMS$DELETE_STREAM | Deletes the stream. This service is normally used after ACMS$DISCONNECT_STREAM. |
The rest of this appendix contains reference material for using the superseded services. The services appear in alphabetical order.
A.1 ACMS$CLOSE_RR
The ACMS$CLOSE_RR service closes a TDMS channel to a terminal and
disassociates it from a submitter ID. Any active TDMS call on the
channel is canceled. If the agent program uses ACMS$INIT_EXCHANGE_IO to
open a channel, it must also use ACMS$TERM_EXCHANGE_IO to close the
channel. If the agent program attempts to use a superseded service to
close a channel opened by a new service, this results in status returns
of invalid.
This service has been superseded. ACMS supports this service for existing applications using TDMS. Use the ACMS$TERM_EXCHANGE_IO service in new applications. |
ACMS$CLOSE_RR ([channel.rlu.r],
[nullarg])ACMS$CLOSE_RR_A ([channel.rlu.r],
[nullarg],
[comp_status.wq.r],
[efn.rbu.r],
[astadr.szem.r],
[astprm.rz.v])
channel
The TDMS channel returned from a previous ACMS$OPEN_RR call. The agent program must supply this parameter.nullarg
Place-holding argument. This argument is reserved for Compaq's use.
The parameters comp_status.wq.r, efn.rbu.r, astadr.szem.r, and astprm.rz.v are asynchronous service arguments. See Chapter 2 for a discussion of these parameters.
This list summarizes each error returned by this service. Attempts to use ACMS$CLOSE_RR to close a channel opened with ACMS$INIT_EXCHANGE_IO result in a status message of invalid. Also, invalid status returns from TSS$CLOSE might be returned to the agent program. See the reference section of the VAX TDMS Reference Manual for more information on TSS$CLOSE.The return status codes indicating success or failure of the call follow:
Status Severity Level Description ACMS$_NORMAL Success Normal successful completion. ACMS$_PENDING Informational Successful operation pending asynchronous completion. The final status is in the completion status block. ACMS$_TDMSNOTINST Informational TDMS is not installed on the system. ACMS$_INSUFPRM Error Not enough arguments were passed to this service. ACMS$_INTERNAL Error Internal error. ACMS$_INVCHAN Error Invalid channel---channel not known. ACMS$_INVEFN Error The event flag was invalid. ACMS$_SYNASTLVL Error Synchronous services may not be called from AST level.
A.2 ACMS$CONNECT_STREAM
ACMS$CONNECT_STREAM establishes a connection to a stream and returns a
connect ID. Before using this service, it is necessary to create a
stream with ACMS$CREATE_STREAM.
If an agent program creates and connects a stream, the agent program must call ACMS$WAIT_FOR_STREAM_IO for all tasks (except tasks that do no terminal I/O), whether or not the task performs stream I/O.
This service has been superseded. ACMS supports this service for applications that have already been implemented. To simplify the writing of agent programs, and to simplify program maintenance, use the ACMS$INIT_EXCHANGE_IO service in new applications. |
ACMS$CONNECT_STREAM (stream_id.rq.r,
mode.rl.r,
connect_id.wq.r,
[submitter_id.rq.r])ACMS$CONNECT_STREAM_A (stream_id.rq.r,
mode.rl.r,
connect _id.wq.r,
[comp_status.wq.r],
[efn.rbu.r],
[astadr.szem.r],
[astprm.rz.v],
[submitter_id.rq.r])
stream_id
The identification of the stream to which you want to connect. This ID is returned by ACMS$CREATE_STREAM.mode
The mode of this stream connection must always be set to ACMS$K_STRM_PASSIVE.connect_id
The identification that is returned by this service to identify this stream connection. This ID is used later by ACMS$DISCONNECT_STREAM, ACMS$WAIT_FOR_STREAM_IO, and ACMS$REPLY_TO_STREAM_IO.submitter_id
This ID is used to associate the stream ID with the submitter. The submitter_id argument is optional. You must use this parameter if the agent program calls an ACMS task that performs DECforms, TDMS, or terminal I/O, and that task calls another task that performs stream I/O.
The parameters comp_status.wq.r, efn.rbu.r, astadr.szem.r, and astprm.rz.v are asynchronous service arguments. See Chapter 2 for a discussion of these parameters.
The return status codes indicating success or failure of the call follow:
Status Severity Level Description ACMS$_NORMAL Success Normal successful completion. ACMS$_PENDING Informational Successful operation pending asynchronous completion. The final status is in the completion status block. ACMS$_SENDER_DISCONN Warning The sender has disconnected from the stream. ACMS$_BADMODE Error The mode value specified was invalid. ACMS$_BADSTRMID Error The stream ID is not correct; either the stream was not created, it was deleted, or the stream ID was corrupt. ACMS$_CANOTCON Error The state of the stream does not allow for connects. The agent program must be connected before the EXC. ACMS$_INSUFPRM Error Not enough arguments were passed to this service. ACMS$_INVASTADR Error The AST address was invalid. ACMS$_INVASTPRM Error The AST routine parameter was invalid. ACMS$_INVCMPSTS Error The completion status block was invalid. ACMS$_INVCONID Error The connect ID was invalid. ACMS$_INVEFN Error The event flag was invalid. ACMS$_INVMODE Error The mode of the stream was invalid. ACMS$_INVSTRMID Error The stream ID was invalid. ACMS$_MAXCNSCONN Error The maximum number of agent programs have already connected to the stream. ACMS$_SYNASTLVL Error Synchronous services may not be called from AST level. ACMS$_UNKMODE Error The mode specified was not understood by the stream arbitrator. ACMS$_BADCONNCTLMSG Fatal Invalid function code on control message received by connection.
A.3 ACMS$CREATE_STREAM
The ACMS$CREATE_STREAM service creates a stream and returns the stream
identification. It is used in conjunction with ACMS$CONNECT_STREAM. If
an agent program creates and connects a stream, the agent program must
call ACMS$WAIT_FOR_STREAM_IO for all tasks (except tasks that do no
terminal I/O), whether or not the task performs stream I/O.
ACMS$CREATE_STREAM has been superseded. ACMS supports this service for applications that have already been implemented. To simplify the writing of agent programs and to simplify program maintenance, use the ACMS$INIT_EXCHANGE_IO service in new applications. |
ACMS$CREATE_STREAM (mode.rl.r,
stream_id.wq.r)ACMS$CREATE_STREAM_A (mode.rl.r,
stream _id.wq.r,
[comp_status.wq.r],
[efn.rbu.r],
[astadr.szem.r],
[astprm.rz.v])
mode
The mode of the stream must always be set to ACMS$K_STRM_BIDIRECTIONAL.stream_id
The stream identification that is returned by this service. The ID is passed to any task that connects to this stream.
The parameters comp_status.wq.r, efn.rbu.r, astadr.szem.r, and astprm.rz.v are asynchronous service arguments. See Chapter 2 for a discussion of these parameters.
The return status codes indicating success or failure of the call follow:
Status Severity Level Description ACMS$_NORMAL Success Normal successful completion. ACMS$_PENDING Informational Successful operation pending asynchronous completion. The final status is in the completion status block. ACMS$_BADMODE Error The mode value specified was invalid. ACMS$_INSUFPRM Error Not enough arguments were passed to this service. ACMS$_INVASTADR Error The AST address was invalid. ACMS$_INVASTPRM Error The AST routine parameter was invalid. ACMS$_INVCMPSTS Error The completion status block was invalid. ACMS$_INVEFN Error The event flag was invalid. ACMS$_INVMODE Error The mode of the stream was invalid. ACMS$_INVSTRMID Error The stream ID was invalid. ACMS$_SYNASTLVL Error Synchronous services may not be called from AST level.
Previous | Next | Contents | Index |