In order to create trace information for multithreaded ooRexx programs I will come up with a few
simple/small programs, each on a separate e-mail.
First the program will get displayed, its trace output, trace output formatted according to the idea
to include the thread number in the trace prefix and the trace output with multithreaded trace. The
trace output without thread information and with the thread information included in the trace prefix
got created off the multithreaded trace. The reason being that running the samples repeatedly may
yield different sequences which would make comparison and look-ups a little bit difficult.
The motivation being to demonstrate that adding the thread number is helpful, but also that the
multithreaded trace supplies valuable additional information that is helpful for humans to quickly
grasp what is happening where, what belongs together, getting insights quickly and ease debugging.
Maybe a little bit exaggerated: although if one is aquainted one could read a hex dump to search and
find the information that is relevant and important it may be better to get the data presented in a
manner that contains already all relevant information in a human legible manner; the former would be
machine centric, the latter human-centric. As one can hopefully see in this small series, the
different categories of information supplied when multithreaded tracing is turned on will
improve/help "mortal" ooRexx programmers to get quicker to the relevant information in the context
of their concurrently executing ooRexx programs.
---
Maybe a brief overview of multithreading in ooRexx: multithreading in ooRexx is bound to messages
that one sends to objects. The receiving object will then search a method routine by the same name
as the received message and activates/runs it. These are basically the three possibilities for
ooRexx programmers to create additional threads of execution:
* In the method routine one can use the REPLY keyword instruction: this will
return control back
to the object and also create a new thread on which the remaining code of
the activity gets
executed concurrently,
* One can use an instance of the .Message class and set the receiving object
("receiver"), the
message name and the arguments going with it. Then, if the message should
get sent
asynchroneously, that message object should get the "start" message sent to
it. This will create
a new thread on which the message gets sent to the receiving object and the
control returns
immediately to the sender.
* One can forgo creating a .Message object and use the method 'start' of the
ooRexx root class
.Object. So sending directly the 'start' message to any object becomes
possible if one supplies
the message name and any arguments that go with it. The result is that the
'start' method in the
root class will create a .Message object as above, supply the message name
and arguments, if
any, and sends it the 'start' message. The result of the 'start' method in
the root class is
that very message object that gets returned to the sender and enables him to
learn about the
state of the asynchroneously executing method.
There is an additional possibility that multithreading gets triggered for an ooRexx program: an
application hosting ooRexx programs may dispatch/run those programs on different operating system
threads. In principle this should not be noticeable.
However, there are situations where the hosting application may interact with ooRexx objects on
threads the hosting application created. An example for this are Windows or Java GUIs: in such a
scenario a GUI thread gets usually created in which the (Windows/Java) GUI managers observe the
interaction with GUI components in order to create events for event listeners, i.e. objects that are
known to handle GUI events for certain components. This is in essence the situation with Windows
ooDialog, Java awt/swing and JavaFX applications. One typical problem with Windows/Java GUIs (on all
systems for all programming languages) is a restricted communication with the GUI components: such a
communication (API calls) must be carried out on the GUI thread and not on a different thread on
which an ooRexx method may execute and try to update GUI components. The result of such a
misbehaviour may be e.g. a frozen GUI and the like.
There are other use cases in which multithreading may be employed by the hosting application such
that on different threads there may be different ooRexx method routines executing concurrently like
in the case of Java based webservers where one can use ooRexx for coding the web server logic (CGI
and/or JSPs).
In the case of Java applications using ooRexx programs (as macros, scripts, utility programs) via
BSF4ooRexx(850) each script manager gets an Rexx interpreter instance (RII) assigned to. It is
possible that such a Java hosting app uses multiple different RIIs and is free to choose which Rexx
code gets run on which RII, it is also possible to run the same Rexx code on different RIIs (which
makes sense in the case of a web server).
So there are many places where Rexx code gets executed concurrently. Concurrency being employed
either by the hosting application, or by an ooRexx program or a combination of the two.
---
Here a brief description of the few test programs:
* mt01.rex: a "simple" ooRexx program that demonstrates the use of the REPLY
keyword statement in
two method routines (named "M1" and "M2"). The attribute named "counter"
gets increased by 1
upon entry of "M1" and decreased by "1" right before leaving "M2". Method
'BLOCK' is used to
synchronize the main program with potentially concurrently running method
routines by using the
attribute "counter" as a control variable in the "GUARD ON WHEN counter=0".
The messages M1, M2
and BLOCK are sent synchroneously (one after the other).
* mt02.rex: this extends "mt01.rex" with random syssleep() calls before and
after the REPLY
keyword statement such that the concurrent execution of each becomes random
to a certain extent;
each run may therefore yield a slightly different execution sequence. The
messages M1, M2 and
BLOCK are sent synchroneously (one after the other).
* mt03.rex: same as "mt02.rex" with the exception that the messages M1 and M2
get sent
asynchroneously.
* mt90.rex: same as "mt02.rex" adding using 'send' with M1 and M2,
blocking/synchronizing,
followed by 'start' with M1 and M2, blocking/synchronizing as well
* mt91.rex: same as "mt90.rex", but without blocking/synchronizing and
replacing 'send' with
'start' such that even more concurrency takes place; running mt91.rex on two
RIIs at the same time
Please note, these are relative simple examples. There are many other combinations possible, but the
excercise has just the purpose of demonstrating the different trace outputs in a little bit more and
more complex contexts.
---rony
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel