Tried to come up with a text for the documentation for the EventSemaphore class.
Please check the raildiagrams and descriptions for the methods. Also please note that the example got simplified in the formatting somewhat (e.g. the date portion is not used anymore, making the output better legible and also will not "age" because in five years the dates look "outdated"). Any errors and/or bad English are mine only! ;) Please let me know whether this is helpful or not. If so, I will try to come up with the text for the MutexSemaphore class in the next days. Here it goes: =============================================================================== 5.4.x EventSemaphore Class Semaphores get used in multithreaded scenarios. An "event semaphore" allows one thread "A" to synchronize multiple threads (like "B", "C", ...) with whom the event semaphore gets shared. Thread "A" creates the event semaphore and sends it the "reset" message. Then thread "A" supplies the event semaphore to the threads "B", "C", ..., which each send the received event semaphore a "wait" message. This will block the threads "B", "C", ..., until thread "A" sends the "post" message to the event semaphore. At this time all threads waiting on the event semaphore get released and can run in parallel on their threads. 5.4.x.1 close >>--- close --->< Closes the event semaphore. 5.4.x.2 isPosted >>--- isPosted --->< Returns .true if the event semaphore is in the "posted" state, such that sending the "wait" message to this event semaphore would return immediately. A return value of .false indicates that the event semaphore is not in the "posted" state, such that a "wait" message will block. 5.4.x.2 post >>--- post --->< Sets the event semaphore to the "posted" state, signalling that the event that other threads are waiting on has occurred, such that all threads waiting on this event semaphore will be released and start to run again. 5.4.x.3 reset >>--- reset --->< Resets (clears) the event semaphore to the non-"posted" state, such that "wait" messages to this event semaphore will block. 5.4.x.4 uninit >>--- uninit --->< This method cleans up the object when it is garbage collected. It should not be invoked directly except via an uninit method of a subclass of the EventSemaphore class. 5.4.x.5 wait >>--- wait(--+-------------+--)--->< | | +-- timeout --+ Waits (blocks) on the event semaphore until it gets "posted". If "timeout" was supplied it must be a whole number that represents the milliseconds to wait on the event semaphore before returning. If no "timeout" value was supplied or its value is negative, the wait will be forever, ie. until the event semaphore gets posted. If the "timeout" value is zero the method returns immediately with the same value that the method "isPosted" would return if sent to the event semaphore instead. The method returns .true if the event semaphore got "posted", .false if the method returns prematurely because the given timeout has occurred. Example 5.xxx The following example will fetch the routine object "WORKER" and in a loop will send the routine object the message "start" (defined in the ooRexx root class "Object") supplying the message name ("call") to be sent on a new (asynchroneous) thread, and as arguments the event semaphore to wait on and the number of the loop for the respective asynchroneous message. The main program creates an event semaphore and sends the message "reset" to it. Then it sends the "start" message three times to the routine object in the loop, causing the routine "worker" to run on three different threads, where in each thread the executed routine then waits on the event semaphore ("wait" message to the event semaphore). The main program then sleeps for five seconds, before sending the "post" message to the event semaphore, which will awake the routines on the three threads, ie. they return from the wait message and execute on their threads in parallel, causing each to sleep for two seconds before returning from the routine invocation. <code> eventSem=.eventSemaphore~new -- create an event semaphore, will be in posted state dt=.dateTime~new -- a .DateTime object to allow measuring elapsed time say "/main\ " pp(dt~elapsed) "currently 'eventSem~isPosted':" pp(eventSem~isPosted) eventSem~reset -- reset event semaphore, such that "wait" will block say "/main\ " pp(dt~elapsed) "after 'eventSem~reset', 'eventSem~isPosted':" pp(eventSem~isPosted) w=.routines~waiter -- get routine 'WAITER' as a routine object do i=1 to 3 say "/main\ " pp(dt~elapsed) "running routine 'WAITER' #" pp(i) "asynchroneously" w~start("call", eventSem, i) -- call (run) the routine object on a separate thread end say sleepTime=5 say "/main\ " pp(dt~elapsed) "sleeping" pp(sleepTime) "seconds ..." call sysSleep sleepTime -- sleep five seconds say "/main\ " pp(dt~elapsed) "awoke, about doing an 'eventSem~post' ..." say eventSem~post -- wake up all threads waiting on this event semaphore say "\main/ " pp(dt~elapsed) "--> leaving main, other threads may still be active!" ::routine waiter -- this routine will be called on a separate thread use arg eventSem, nr s=.dateTime~new -- we use our own .DateTime object to measure elapsed time on this thread say .context~name" #" nr":" pp(s~elapsed) "arrived, eventSem~isPosted="pp(eventSem~isPosted)", waiting..." eventSem~wait -- wait until main program posts this event semaphore sleepTime=2 say .context~name" #" nr":" pp(s~elapsed) "wait over, 'eventSem~isPosted':" pp(eventSem~isPosted) say .context~name" #" nr":" pp(s~elapsed) "now sleeping" pp(sleepTime) "second(s)" call syssleep sleeptime -- sleep a second o=.dateTime~new say .context~name" #" nr":" pp(s~elapsed) "sleep over" ::routine pp -- "pretty print" ;) (encloses argument in square brackets) return "["arg(1)"]" </code> Running this program may yield the following output: <code> /main\ [00:00:00.000000] currently 'eventSem~isPosted': [1] /main\ [00:00:00.015000] after 'eventSem~reset', 'eventSem~isPosted': [0] /main\ [00:00:00.015000] running routine 'WAITER' # [1] asynchroneously /main\ [00:00:00.015000] running routine 'WAITER' # [2] asynchroneously WAITER # 1: [00:00:00.000000] arrived, eventSem~isPosted=[0], waiting... /main\ [00:00:00.015000] running routine 'WAITER' # [3] asynchroneously WAITER # 2: [00:00:00.016000] arrived, eventSem~isPosted=[0], waiting... WAITER # 3: [00:00:00.000000] arrived, eventSem~isPosted=[0], waiting... /main\ [00:00:00.047000] sleeping [5] seconds ... /main\ [00:00:05.054000] awoke, about doing an 'eventSem~post' ... \main/ [00:00:05.054000] --> leaving main, other threads may still be active! WAITER # 2: [00:00:05.039000] wait over, 'eventSem~isPosted': [1] WAITER # 1: [00:00:05.039000] wait over, 'eventSem~isPosted': [1] WAITER # 3: [00:00:05.023000] wait over, 'eventSem~isPosted': [1] WAITER # 2: [00:00:05.055000] now sleeping [2] second(s) WAITER # 1: [00:00:05.055000] now sleeping [2] second(s) WAITER # 3: [00:00:05.039000] now sleeping [2] second(s) WAITER # 3: [00:00:07.067000] sleep over WAITER # 1: [00:00:07.083000] sleep over WAITER # 2: [00:00:07.083000] sleep over </code> ---rony
_______________________________________________ Oorexx-devel mailing list Oorexx-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/oorexx-devel