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 &quot;I&quot; (Indivdual) that 
> the arguments
> *                     are listed individually, &quot;A&quot; (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 &quot;I&quot; (Indivdual) that 
> the arguments
> *                     are listed individually, &quot;A&quot; (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

Reply via email to