On Sun, Aug 18, 2013 at 5:20 PM, Art Heimsoth <artst...@artheimsoth.com>wrote:

>   Thanks Mark,  I think that helps me, at least it gives me
> some more reading and ideas of how to relate the usage
> to my specific situation.  I am assuming that any action
> from a button or from a menu selection, along with the
> items like LostFocus/GotFocus/Update, etc are all events
> and should all be unGuarded.  Methods that are invoked
> from any of these “action generating” methods may not
> need to be guarded unless there is a method that can be
> invoked from multiple of the other events.  Am I close to
> understanding it so far?  Thanks again..
>

No, any methods you call from the event handlers are in the same boat if
they are guarded methods.  If your main thread is a guarded method, then it
has a "lock" on the object.  If you try to invoke a guarded method from
another thread, then it will wait until it can obtain the object lock.  All
you've done is move the problem one level.

Rick


>   Art
>
>  *From:* Mark Miesfeld <miesf...@gmail.com>
> *Sent:* Sunday, August 18, 2013 3:58 PM
> *To:* Open Object Rexx Users <oorexx-users@lists.sourceforge.net>
> *Subject:* Re: [Oorexx-users] unGuarded vs Guarded
>
>  On Sun, Aug 18, 2013 at 10:59 AM, Art Heimsoth 
> <artst...@artheimsoth.com>wrote:
>
>>   Is there an explanation on when unguarded should be used on a method,
>> or when it should not be used?
>>
>
> Hi Art,
>
> First, I'll give you some areas to read in the ooRexx reference manual and
> in ooDialog, then I'll try to add a little explanation.
>
> To understand guarded / unguarded you need to know it is related to
> concurrency.  So, you should read the section Chapter 12 Concurrency to get
> an idea of how ooRexx implements concurrency.
>
> Guarded / UnGuarded is explained in Chapter 3 Directives, section 3.4
> Methods, where guarded/ungurarded is briefly explained in the notes at the
> end of the section.
>
> To understand how concurrency relates to ooDialog you need to understand
> events and event handlers in ooDialog.  You should read 3.6 Event
> Notification Mixin Class, 3.6.1 Connecting Event Handlers, and 3.6.2 Coding
> Event Handlers.
>
> In addtion, in Chapter 1 Brief Overview, some basic concepts are
> explained.  Reading section 1.3.3 Events and section 1.3.14 Window Messages
> should help.
>
>
>
>>   Or alternatively what it does vs what is
>> done without it?  It doesn’t appear to be a blocking protection on the
>> method if not present, but does appear to do some sort of serialization
>> if not present
>>
>
> Basically when a method of an object is guarded no other guarded method of
> that object can run.  When a method is unguarded it can run even if some
> other method in the object is executing.
>
> Nothing is ever as simple as "basically ..."  One exception to the above
> is that a guarded method can invoke another guarded method in the object
> and that method will execute.  I.e.:
>
> ::class 'example'
> ::method a
>
>   -- do stuff
>   self~b()
>   -- do more stuff
>
> ::method b
>   -- do stuff
>   return
>
> So, even though both methods a and b are guarded, when b() is invoked from
> method a() it executes.
>
>
>>   – but I am confused on how to figure out when to and
>> when not to use it on a method.
>>
>
>
> Concurrency is not simple, so there are no simplistic statements that will
> make everything crystal clear.
>
> In general, one use of guarded is to prevent non-deterministic access to
> the object's variables.  In general I make every method guarded until I see
> that a method needs to be unguarded.
>
> In ooDialog, I have a general statement: make every event handler
> unguarded.
>
> To understand this, you need to understand the window processing loop.
> The OS sends a message to a window, the window's message processing loop
> does something in response to the message and returns a value to the OS.
> The message processing loop then processes the next message.
>
> The OS stacks the messages up in a queue, the processing loop pulls them
> out of the queue one by one.
>
> Let's say the user clicks on a button in a dialog, then uses the mouse to
> move the dialog up 1 pixel.
>
> If, in the window processing loop, the application sleeps for 40 seconds
> when it processes the button click and then returns a value to the OS.  For
> 40 seconds, the message to move the dialog up 1 pixel sits in the queue
> unprocessed.  To the user, it appears that she can not move the dialog with
> the mouse.
>
> Back to ooDialog specific.   The ooDialog framework starts a window
> message processing loop, in a separate thread, for every dialog you the
> programmer create.  Within that processing loop, for every message, the
> ooDialog framework returns a value to the OS that essentially means: 'do
> the default for this message', *unless*, you the programmer have connected
> that message to an event handler.
>
> In the message processing loop, when the ooDialog framework sees a message
> that has been "connected", the framework invokes the method in the dialog
> that the programmer connected.
>
> Take this simple dialog:
>
>  /* Simple User Dialog to produce a dialog that will appear hung */
>
>   .application~useGlobalConstDir('O')
>   .constDir[IDC_PB_ONE] = 100
>   .constDir[IDC_PB_TWO] = 110
>
>   dlg = .SimpleDialog~new
>   dlg~execute("SHOWTOP", IDI_DLG_OOREXX)
>
> ::requires "ooDialog.cls"
>
> ::class 'SimpleDialog' subclass UserDialog
>
> ::method init
>   forward class (super) continue
>
>   self~create(30, 30, 257, 123, "Simple Dialog", "CENTER")
>
> ::method defineDialog
>
>   self~createPushButton(IDC_PB_ONE, 10, 10, 50, 14, "", "Push Me Now",
> 'buttonClick1')
>   self~createPushButton(IDC_PB_TWO, 10, 30, 75, 14, "", "Push Me Now
> Also", 'buttonClick2')
>   self~createPushButton(IDOK, 142, 99, 50, 14, "DEFAULT", "Ok")
>   self~createPushButton(IDCANCEL, 197, 99, 50, 14, , "Cancel")
>
>
> ::method buttonClick1
>   say 'in buttonClick1()'
>   j = SysSleep(40)
>   say 'leaving buttonClick1()'
>
>
> ::method buttonClick2
>   say 'in buttonClick2()'
>   j = SysSleep(40)
>   say 'leaving buttonClick2()'
>
>
> ::method ok
>   say 'in ok()'
>   j = SysSleep(40)
>   say 'leaving ok()'
>   self~ok:super
>
> ::method cancel
>   say 'in cancel()'
>   j = SysSleep(40)
>   say 'leaving cancel()'
>   self~cancel:super
>
> Run the dialog and click the 'Push Me Now' button immediately.  Then push
> any other button, nothing will happen.  Typically a user will then start
> pushing other buttons.  Try to close the dialog by pushing ok or cancel,
> you won't be able to.  The more times you push the buttons or try to close
> the dialog, the longer it will be before the program finally ends.
>
> What happens is:  you push the 'Push Me Now' button, the guarded
> buttonClick1() method starts executing.  You push the 'Push Me Now Also'
> button, the guarded buttonClick2() is invoked, but can not run until all
> other guarded methods are not running.
>
> You, the user, get exasperated and push the cancel button.  The guarded
> cancel() method is invoked by the framework - but it can not run until all
> other guarded methods are not running.
>
> At this point, the dialog is not going to end for 120 seconds.  The ooRexx
> interpreter is not going to end until all invoked methods have completed.
> The more you try to close the dialog, the worse your situation gets.
>
> Now make all the event handling methods unguarded.  Each time you click a
> button, you will immediately see the 'in methodName()' message.  This shows
> that all the event handlers are now running concurrently.
>
> You still won't see the program end immediately when you push the ok or
> cancel program because you have started all these 40 second threads.  But,
> if you push 5 buttons pretty quickly you will see the program end in about
> 40 seconds rather than 200 seconds.
>
> Now, in the guarded version, after you push the first button, you will
> still be able to move the dialog around with the mouse.  This seems to
> contradict what I originally said.  The reason for this is that, for button
> clicks, the ooDialog framework actually invokes the event handler using
> start() and so the message processing loop immediately returns a value to
> the OS and continues processing messages.
>
> But try this program:
>
>  /* Simple User Dialog to produce a dialog that will appear hung */
>
>   .application~useGlobalConstDir('O')
>   .constDir[IDC_PB_ONE] = 100
>   .constDir[IDC_PB_TWO] = 110
>   .constDir[IDC_EDIT] = 120
>   .constDir[IDC_UPD] = 130
>
>   dlg = .SimpleDialog~new
>   dlg~execute("SHOWTOP", IDI_DLG_OOREXX)
>
> ::requires "ooDialog.cls"
>
> ::class 'SimpleDialog' subclass UserDialog
>
> ::method init
>   forward class (super) continue
>
>   self~create(30, 30, 257, 123, "Simple Dialog", "CENTER")
>
> ::method defineDialog
>
>   self~createPushButton(IDC_PB_ONE, 10, 10, 50, 14, "", "Push Me Now",
> 'buttonClick1')
>   self~createPushButton(IDC_PB_TWO, 10, 30, 75, 14, "", "Push Me Now
> Also", 'buttonClick2')
>   self~createEdit(IDC_EDIT, 10, 60, 50, 14)
>   self~createUpDown(IDC_UPD, 60, 60, 15, 15, 'WRAP ARROWKEYS AUTOBUDDY
> SETBUDDYINT')
>   self~createPushButton(IDOK, 142, 99, 50, 14, "DEFAULT", "Ok")
>   self~createPushButton(IDCANCEL, 197, 99, 50, 14, , "Cancel")
>
>   self~connectUpDownEvent(IDC_UPD, "DELTAPOS", onUPD)
>
> ::method onUPD
>   say 'in onUPD()'
>   j = SysSleep(40)
>   say 'leaving onUPD()'
>   return .UpDown~deltaPosReply
>
> ::method buttonClick1
>   say 'in buttonClick1()'
>   j = SysSleep(40)
>   say 'leaving buttonClick1()'
>
>
> ::method buttonClick2
>   say 'in buttonClick2()'
>   j = SysSleep(40)
>   say 'leaving buttonClick2()'
>
>
> ::method ok
>   say 'in ok()'
>   j = SysSleep(40)
>   say 'leaving ok()'
>   self~ok:super
>
> ::method cancel
>   say 'in cancel()'
>   j = SysSleep(40)
>   say 'leaving cancel()'
>   self~cancel:super
>
> For the UpDown DELTAPOS envent, the ooDialog framework waits for the reply
> from the event handler.
>
> Run this program - click the 'Push Me Now' button, immediately click an
> arrow in the UpdDown control, and immediately use the mouse to try and move
> the window.  You won't be able to.
>
> In Windows 7, the OS will detect that your dialog is not processing
> messages and start the special "Window is not responding" behavior after
> about 5 seconds.  This allows the user to move the window and close it.
> Without that special behavior things would be truly hung.  But, the way the
> user can close the dialog is through the Window is not responding dialog
> that the OS puts up.  Not real user friendly.
>
> Not sure how much help this has been.  But, at least you should be able to
> see why you usually need make your event handlers unguarded.
>
> --
> Mark Miesfeld
>
>
>
>
>
>
>
>
>>   If it is described somewhere, point me
>> to it as I did not find it when searching.  Thanks,
>>   Art
>>
>> **
>>
>>
>>
>> ------------------------------------------------------------------------------
>> Get 100% visibility into Java/.NET code with AppDynamics Lite!
>> It's a free troubleshooting tool designed for production.
>> Get down to code-level detail for bottlenecks, with <2% overhead.
>> Download for free and get started troubleshooting in minutes.
>>
>> http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk
>> _______________________________________________
>> Oorexx-users mailing list
>> Oorexx-users@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/oorexx-users
>>
>>
>
> ------------------------------
>
> ------------------------------------------------------------------------------
> Get 100% visibility into Java/.NET code with AppDynamics Lite!
> It's a free troubleshooting tool designed for production.
> Get down to code-level detail for bottlenecks, with <2% overhead.
> Download for free and get started troubleshooting in minutes.
> http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk
>
> ------------------------------
> _______________________________________________
> Oorexx-users mailing list
> Oorexx-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/oorexx-users
>
>
>
> ------------------------------------------------------------------------------
> Get 100% visibility into Java/.NET code with AppDynamics Lite!
> It's a free troubleshooting tool designed for production.
> Get down to code-level detail for bottlenecks, with <2% overhead.
> Download for free and get started troubleshooting in minutes.
> http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk
> _______________________________________________
> Oorexx-users mailing list
> Oorexx-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/oorexx-users
>
>
------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite!
It's a free troubleshooting tool designed for production.
Get down to code-level detail for bottlenecks, with <2% overhead. 
Download for free and get started troubleshooting in minutes. 
http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk
_______________________________________________
Oorexx-users mailing list
Oorexx-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-users

Reply via email to