home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
vxtech04.zip
/
VXTECH04.TXT
Wrap
Text File
|
1994-05-03
|
9KB
|
230 lines
============================================================================
VX-REXX Tech Note #4:
Introduction to REXX Queues
March 09, 1994
Applies to all versions of VX-REXX
----------------------------------------------------------------------------
Paul Prescod
WATCOM International
============================================================================
Abstract
--------
REXX queues are the standard interprocess communication mechanism between
REXX programs. REXX queues can also be used to pipe the output of
external programs into a REXX program. This technical note explains when
to use queues, as well as how to create and destroy them. There is
more advanced information on the queue interface in the "REXX Information"
reference in the VX-REXX folder. This document is intended to be used as
an introduction and companion to that reference.
When To Use A REXX Queue
------------------------
Use a REXX queue any time you want to communicate between processes.
Examples of this would be communication between REXX programs running at
the same time, passing the output of the OS/2 "set" command to a REXX
program, or sending information from a C program to a REXX program. Queues
are system-wide so any REXX application, whether it is Presentation
Manager based or text mode, foreground, background or detached, can
access them.
Creating a Queue
----------------
Queue maintanence is done using the RXQueue function. Queues have names,
just like VX-REXX objects or OS/2 files. Usually, you will let
REXX choose the queue name:
Qname = RXQueue( "Create" )
Now the variable Qname contains the string that represents the queue, the
queue's name. This name is usually something along the lines of
"S20Q0363406248." There is nothing special about this string. It is just
a quasi-random string of letters chosen by REXX used to identify this
queue. REXX is will always choose a name that is unique system-wide, so you
can be sure that no one else is using that queue. You can pass that
queue name to any other REXX program, and the two programs can use the
queue for communications. You might pass it via a command line
argument, an already existing queue, or a file on disk.
On the other hand, it might be difficult to communicate the queue name
to another program (e.g. one which is already running). In this case, you
would want to choose the name of the queue yourself, so you can hard code it
into both programs when you write them.
Creating Named Queues
------------------
To create a new queue named "Fred", you would say:
Qname = RXQueue( "Create", "Fred" )
If "Fred" did not already exist, REXX will create it, and return the word
"Fred" (so the variable Qname now contains the word "Fred").
What if Fred Already Exists?
----------------------------
If "Fred" did already exist, REXX will create a new queue, choose its
name, and return it. Since you have already made the decision to use the
Fred queue, you should immediately delete the new queue.
Be careful, though, since Fred was already created, there may be another
program using that queue. Since it is unlikely that two different
developers would choose the same queue name (unless you actually use a
queue named "Fred", which is now world famous!), it is likely that the
queue was created by another copy of your program. Either an earlier
instance of your program did not destroy the queue, or two instances of
your program are running concurrently. Be careful! It is very easy to
cross messages.
Using REXX Queues
-----------------
A system can have as many queues as it has memory for, and any particular
REXX program can access as many of them as it wants. All it has to know
are the names of the queues that it is going to access. At any one time,
however, there is only one queue that is considered "current". The current
queue is the only one that you can work with. To use multiple queues, you
change the current queue to each of them in turn. You can change
the current queue to any queue whose name you know using the following
command:
oq = RXQueue( "Set", "Fred" )
Now the current queue is set to the queue "Fred." The queue name could also
be stored in a variable:
qname = "Fred"
oq = RXQueue( "Set", qname )
Often, instead of setting the variable to a constant, you will use the
variable returned by the "Create" command (above).
qname = RXQueue( "Create" )
oq = RXQueue( "Set", qname )
Sending Data To Queues
----------------------
From REXX
---------
REXX programs use the "Push" and "Queue" commands to put data on the
current queue. See the "REXX Information" reference for more information
on these functions.
From the Command Line
---------------------
There is a program in the \OS2 directory called RXQUEUE that allows you to
send the output of a program to a REXX queue. Though this command has the
same name as the RXQueue function, they are in fact different. RXQUEUE
is a filter, so you must send data through an OS/2 pipe. For more
information on pipes, see the section called "pipe, using a" in the
Master Help Index. RXQUEUE has the following syntax:
RXQUEUE [Queuename] [/FIFO|/LIFO|/CLEAR],
Queuename is the name of a REXX queue that exists.
The /CLEAR parameter removes all text from the queue.
The /LIFO flag stacks items Last In First Out (like push() )
the /FIFO flag queue items First In First Out (like queue() )
If the queue name is omitted, RXQUEUE uses the contents of the
environment variable "RXQUEUE". When the queue name is omitted and
the "RXQUEUE" environment variable does not have a value, the RXQUEUE
program uses the "SESSION" queue. For more information on the "SESSION"
queue, read the "REXX Information" reference.
Since commands that can be executed from the command line can also be
executed from REXX, you can use this technique to pipe the output of an
external program into your REXX program. For instance, here is a small
function which collects the data from the "set" command and sends it to
a ListBox.
/* Set2LB_1: Collects output of set and then puts it in a ListBox
called LB_1 (if LB_1 does not exist you will get an error message)
*/
Set2LB_1:
'set | rxqueue'
do while queued()>0
call VRMethod "LB_1", "AddString", linein("QUEUE:")
end
return
This example does not specify a queue because it uses the default queue,
the "SESSION" queue. For more information on the queued() function used
above, see the "REXX Information Reference." For more information on
the RXQueue function, see the "Procedures Language 2/REXX Reference" in
the OS/2 2.0 Technical Library.
From C
------
There is an undocumented API for accessing a REXX queue from a C program.
These functions are prototyped in the REXXSAA.H header file. This API is
not likely to change, but just in case it does, there is also a
documented way to write to a REXX queue. All you have to do is write a
small REXX program that uses the PUSH command to a buffer in memory, and
use the RexxStart function to execute it. There is more information on
the RexxStart function in the RexxApi.inf reference.
Getting Data From a Queue
---------------------------
Data is retrieved from the queue using the Pull and Linein("QUEUE:")
functions. These are well documented in the "REXX Information" reference
in the VX-REXX folder.
Destroying REXX Queues
----------------------
You should destroy any REXX Queue you create. Once the name of the queue is
lost, there is no way to destroy it. To destroy a queue named "Fred", you
would say:
rc = RXQueue( "Delete", "Fred" )
To destroy a queue whose name is in a variable, qname, you would say:
rc = RXQueue( "Delete", qname )
There is more information about destroying queues and analysing the return
codes in the "REXX Information" reference.
Example Program
----------------
/* Parent.cmd : Simple program showing how to use a REXX Queue */
/* ----------
Calls a VX-REXX program with a queue name as a parameter
and then "executes" any commands the VX-REXX program queues.
Good for modifying the environment of the parent session of
a VX-REXX program.
*/
qname = rxqueue("Create")
oldqname = rxqueue("Set",qname)
/* Call a VX-REXX program with the queue name as the first parameter
*/
'project.exe' qname
do while queued()>0
/* Get data out of the queue and execute it as a command
*/
data = linein("QUEUE:")
data
end