Hi Guys, This is awkward, I think this change was made in response to my expressing surprise that the guard made a difference to methods which have no variables exposed - something that I still don't understand, but have no need to understand. However, if you think it should go, then I'm content for it to go.
BTW, and just for correctness sake, I think the default guard state was changed before, sometime in version 3.x I think. I remember that I had to change all my oodialog message handling methods to be explicitly unguarded. Jon On Sat, 7 Aug 2021, 18:36 Jean Louis Faucher, <jfaucher...@gmail.com> wrote: > +1 > > If you run the example 12.4 of rexxref, you will see that it breaks the > rule written just above. > > > Regards > > On 7 Aug 2021, at 18:28, Rony G. Flatscher <rony.flatsc...@wu.ac.at> > wrote: > > Sleeping and thinking more over it I would suggest to remove this feature > altogether! The major reasing being that the Rexx philosophy (and ooRexx by > extension) should make coding as easy as possible for programmers. > > The default for methods (and related) has always been "guarded" such that > one would not have to write "guarded" to the method directive. With that > default only in very rare cases (in multithreaded scenarios) would one have > to write "unguarded" to a method directive. And if doing so one must have > an understanding of multithreading and the ramifications if someone would > want a method to run unguarded. > > Compare this to the current situation with this new feature on: in order > to fix BSF.CLS all of a sudden I had to add the keyword "guarded" to every > method to gain the default behaviour for ooRexx < 5.0 and thereby > re-enabling correct execution of GUI nutshell examples. > > Ad feature: originally it was thought to be helpful to programmers by > saving the programmers to write "unguarded" to a method directive for a > method that is known to be safe in unguarded mode thinking that methods > that have no direct access to the attribute pool (i.e. the method routine > would not start with "expose" or "use local") qualify for unguarded > execution not thinking about scenarios where this is not enough. > > To make it easy for the programmer (i.e. not having to know additional, > sometimes quite subtle, concepts that play a role in this context) I would > be in a strong favor to leave the default "guarded" in place. Then either > remove this new feature altogether or make it an explicit option a > programmer has to state ("::OPTIONS" with a new pair "guarded|unguarded"). > > What opinions have others? Do you concur? > > ---rony > > > On 06.08.2021 15:09, Rony G. Flatscher wrote: > > Background: In order for ooRexx programmers getting acquainted with > BSF4ooRexx/Java quickly there are numerous nutshell examples in > "bsf4rexx/samples". Most of these nutshell examples stem from observations > of students over time who should get help by demonstrating them how to > achieve something of interest with these (mostly brief) nutshell examples. > > One interesting problem has been the interaction from ooRexx with GUI > objects which must be carried out on the GUI threads in Java (the "awt > thread" or the "JavaFX Application thread"). Although they got the > necessary information about the architecture and what to do in ordert to > become able to send messages on GUI threads, they kept running into > problems, losing a lot of time (even months because they could not get it > working in more complex programs). > > To make a long story short, I came up with a message based solution, that > was very easy to understand and to employ for them. None of the students > ran into the GUI thread problems since then. > > The solution is an ooRexx class for awt (the Java "abstract windows > toolkit") named .AwtGuiThread and for JavaFX (a powerful GUI system) > .FxGuiThread, both subclassing a common superclass .AbstractGuiThread. > These classes allow one to send the ooRexx message > runLater[Latest](GUIreceiver, messageName, arguments) which get queued and > dispatched on the GUI thread later. > > The nutshell examples > "bsf4rexx/samples/3-090_update_awtSwing_GUI-from-non-GUI-thread.rxj" and > "bsf4rexx/samples/JavaFX/javafx_update_GUI-from-non-GUI-thread.rxj" > demonstrate how to employ this infrastructure. They have been working for > years without a problem. > > While working on BSF4ooRexx I stumbled over an error (not having run those > two examples for quite some time) which seems to indicate that ooRexx now > creates an error when being used from different threads: > > F:\work\svn\bsf4oorexx\trunk\bsf4oorexx\samples>3-090_update_awtSwing_GUI-from-non-GUI-thread.rxj > screenSize: [java.awt.Dimension[width=1920,height=1080]] > winSize : [java.awt.Dimension[width=800,height=200]] > xPos=[560] yPos=[440] > a REXXEVENTHANDLER::actionPerformed - starting Rexx thread > The SOME_REXX_CLASS class::updateGuiFromRexxThread - just arrived, GUI > thread: 23808 > The SOME_REXX_CLASS class::updateGuiFromRexxThread - now running on thread: > 7428 > *-* Compiled method "DELETE" with scope "Queue". > 5727 *-* msgQueue~delete(idx) -- delete the guiMsg object > 5637 *-* forward message "REMOVEMESSAGE" continue -- remove all GUI > messages of the same name targeted to the same object > 207 *-* .AwtGuiThread~runLaterLatest(label, "setText", "i", str) > Error 93 running > F:\work\svn\bsf4oorexx\trunk\bsf4oorexx\samples\3-090_update_awtSwing_GUI-from-non-GUI-thread.rxj > line 207: Incorrect > call to method. > Error 93.966: Incorrect queue index "1". > a REXXEVENTHANDLER::windowClosing - release lock ('closeApp=.true') which > will allow a blocked 'waitForExit' method to resume and return > > F:\work\svn\bsf4oorexx\trunk\bsf4oorexx\samples> > > and > > F:\work\svn\bsf4oorexx\trunk\bsf4oorexx\samples\JavaFX>javafx_update_GUI-from-non-GUI-thread.rxj > a REXXBUTTONHANDLER::handle - starting Rexx thread > The SOME_REXX_CLASS class::updateGuiFromRexxThread - just arrived, GUI > thread: 24244 > The SOME_REXX_CLASS class::updateGuiFromRexxThread - now running on thread: > 14124 > *-* Compiled method "DELETE" with scope "Queue". > 5727 *-* msgQueue~delete(idx) -- delete the guiMsg object > 5637 *-* forward message "REMOVEMESSAGE" continue -- remove all GUI > messages of the same name targeted to the same object > 194 *-* .FxGuiThread~runLaterLatest(label, "setText", "i", str) > Error 93 running > F:\work\svn\bsf4oorexx\trunk\bsf4oorexx\samples\JavaFX\javafx_update_GUI-from-non-GUI-thread.rxj > line 194: Incorrect call to method. > Error 93.966: Incorrect queue index "1". > > The ooRexx code where the error occurs looks like, lines # 5637 and # 5727 > are highlighted in green and bold: > > /* > ------------------------------------------------------------------------------------------------- > */ > -- method replaces existing target: this way only the latest sent message > will get executed! > /** This class method allows to define a Rexx message with its arguments that > should > * be processed on the GUI thread. Each invocation will create a new > <code>GUIMessage</code> > * from the supplied arguments and returns it for further inspection in > addition to queueing > * it for later execution on the GUI thread. Unlike <code>runLater</code> > this method will > * first remove any queued messages with the same target and the same > message name, before > * queueing this message. > * > * @param target the target object to receive a message on the GUI thread > * @param messageName the message name to send to the target on the GUI > thread > * @param indicator optional; indicates with "I" (Indivdual) that > the arguments > * are listed individually, "A" (Array) > indicates that the fourth > * argument is an array containing the arguments to supply > with the > * message on the GUI thread > * > * @return GUIMessage a GUI message object (modelled after ooRexx' > <code>Message</code> class > * that allows one to inspect the state of the message > (process completed, > * fetching a possible result, determining whether an > error occurred and > * inspecting it) > */ > ::method runLaterLatest class > use strict arg target, messageName, ... > > signal on syntax > if self~JavaGuiUtilityClz=.nil then self~setup -- make sure attributes are > initialized > > *forward message "REMOVEMESSAGE" continue -- remove all GUI messages of > the same name targeted to the same object* > guiMsg=result -- fetch returned GUIMessage object > msgQueue=self~msgQueue -- get message queue > msgQueue~queue(guiMsg) -- now enqueue current (latest) guiMsg > > if self~waitingToRun=.false then -- "runLater" not invoked yet? > do > self~waitingToRun=.true > self~invokeOnGuiThread -- make sure Java will dispatch Rexx message on > GUI thread > end > return guiMsg -- allows caller to get a hold of a possible > return value > > syntax: > raise propagate > > ... cut ... > > /* > ------------------------------------------------------------------------------------------------- > */ > -- method removes all GUI message objects > /** This private class method removes all GUIMessage objects from the message > queue that will be processed > * later when Java call backs on the GUI thread, that have the supplied > target and the supplied > * message name. > * > * @param target the target object to receive a message on the GUI thread > * @param messageName the message name to send to the target on the GUI > thread > * @param indicator optional; indicates with "I" (Indivdual) that > the arguments > * are listed individually, "A" (Array) > indicates that the fourth > * argument is an array containing the arguments to supply > with the > * message on the GUI thread > * > * @return GUIMessage a GUI message object (modelled after ooRexx' > <code>Message</code> class > * that allows one to inspect the state of the message > (process completed, > * fetching a possible result, determining whether an > error occurred and > * inspecting it) > */ > ::method removeMessage class private > use strict arg target, messageName, ... > > signal on syntax > if self~JavaGuiUtilityClz=.nil then self~setup -- make sure attributes are > initialized > > -- remove all occurrences of messages with the same messagename and the > same target > msgQueue=self~msgQueue -- get message queue > idx=msgQueue~first -- get index of the first item in the queue, if > any > do while idx<>.nil -- a valid index in hand ? > tmpItem=msgQueue~at(idx) -- fetch item, a GuiMessage > -- same target, same messagename? > if tmpItem~target=target, > tmpItem~messageName~caselessEquals(messagename) then > * msgQueue~delete(idx) -- delete the guiMsg object* > idx=msgQueue~next(idx) -- get index of next item in the queue > end > > guiMsg=self~createGuiMessage(arg(1,"array")) -- create and return GUI > message object > return guiMsg -- allows caller to get a hold of a possible > return value > > syntax: > raise propagate > > None of the methods of these three classes are marked as unguarded such > that in the past if one method executes no other can do so in parallel, > inhibiting concurrent access of the queue. > > However, I recall that there was a change in ooRexx 5.0 that if methods do > not have an expose keyword statement than unlike earlier versions of ooRexx > such expose-less methods will be made unguarded. > > Yet, as in this real use case this change may bring incompatibilities for > existing programs (BSF4ooRexx has been around for more than 10 years). The > problem lies in getting and using the queue in different threads because of > this (at the time of devising the solution unforeseen) as no default > blocking of methods takes place. > > To double-check I added manually "guarded" to all methods of the classes > that play together here and doing so, made the nutshell programs work again. > > --- > > The reason I bring this forward is twofold: > > - the change may break existing programs and programmers may be > clueless as to why that happens and therefore not know how to solve it, > - it should be discussed whether keeping this change, but if so it > needs to be prominently communicated as the cause may be too subtle for > many, especially if using ooRexx code for which they do not have the > source: > - one solution may be to have a new OPTION unguared|guarded > determining how expose-less methods should be treated; this way this > default to unguarded behavior needs to be activated explicitly making > the > programmer aware of it, yet older programs still would function with the > default to guarded behavior that was in place in erarlier versions of > ooRexx, > - another solution would be to not only analyze whether the expose > statement exists, but in the case where it does not exist also analyze > whether messages to self occur and if so leave the method guarded; > however > this bears the problem that one could use an object that refers to self > such that the problem might surface nevertheless. > > Any thoughts, ideas, suggestions, conclusions? > > ---rony > > > _______________________________________________ > Oorexx-devel mailing list > Oorexx-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/oorexx-devel > > > _______________________________________________ > Oorexx-devel mailing list > Oorexx-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/oorexx-devel >
_______________________________________________ Oorexx-devel mailing list Oorexx-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/oorexx-devel