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

Reply via email to