#REFACTORING by cg
authorClaus Gittinger <cg@exept.de>
Tue, 25 Jun 2019 09:03:59 +0200
changeset 5031 0cfe45b14c1a
parent 5030 8f13987273e8
child 5032 fe353b8a8223
#REFACTORING by cg class: Future added: #signalSemaphoreAfterForked: #signalSemaphoreAfterForked:atPriority: comment/format in: #block: #block:value: #block:value:value: #block:value:value:value: #block:valueWithArguments: #priority:block: #priority:block:value: #priority:block:value:value: #priority:block:value:value:value: #priority:block:valueWithArguments: changed: #doesNotUnderstand: #perform:withArguments: #value class: Future class comment/format in: #examples
Future.st
--- a/Future.st	Tue Jun 25 07:58:37 2019 +0200
+++ b/Future.st	Tue Jun 25 09:03:59 2019 +0200
@@ -102,8 +102,8 @@
                                                                     [exBegin]
     | fac1 fac2 |
 
-    fac1 := [Transcript showCR: 'Starting fac1.. '. 9000 factorial. Transcript showCR: 'Finished fac1'] futureValue.
-    fac2 := [Transcript showCR: 'Starting fac2.. '. 5000 factorial. Transcript showCR: 'Finished fac2'] futureValue.
+    fac1 := [Transcript showCR: 'Starting fac1.. '. 90000 factorial. Transcript showCR: 'Finished fac1'] futureValue.
+    fac2 := [Transcript showCR: 'Starting fac2.. '. 50000 factorial. Transcript showCR: 'Finished fac2'] futureValue.
     fac2 value.
     fac1 value.
     Transcript showCR: 'both completed.'.
@@ -127,13 +127,22 @@
     Without futures, the inputfile is read before opening the view;
     the readTime and view creation times sum up:
                                                                     [exBegin]
-        |p text v|
+        |p text v t1 t2 tAll|
 
-        p := PipeStream readingFrom:'ls -l /bin /usr/bin /usr/lib'.
-        text := p contents.
-        p close.
-        v := TextView new openAndWait.
-        v contents:text
+        tAll := TimeDuration toRun:[
+            t1 := TimeDuration toRun:[
+                p := PipeStream readingFrom:'ls -l /bin /usr/bin /usr/lib /etc'.
+                text := p contents.
+                p close.
+            ].
+            t2 := TimeDuration toRun:[
+                v := TextView new openAndWait.
+            ].    
+            v contents:text
+        ].
+        Transcript showCR:'Time to read: %1' with:t1.
+        Transcript showCR:'Time to open: %1' with:t2.
+        Transcript showCR:'Time overall: %1' with:tAll.
                                                                     [exEnd]
 
     The same here:
@@ -141,7 +150,7 @@
         |p text v|
 
         v := TextView new openAndWait.
-        p := PipeStream readingFrom:'ls -l /bin /usr/bin /usr/lib'.
+        p := PipeStream readingFrom:'ls -l /bin /usr/bin /usr/lib /etc'.
         text := p contents.
         p close.
         v contents:text
@@ -153,17 +162,27 @@
      be already available - especially on X window systems, where the user
      has to provide the window position with the mouse)
                                                                     [exBegin]
-        |p text v|
+        |p text v t1 t2 tAll|
 
-        text := [   |p t|
+        tAll := TimeDuration toRun:[
+            text := [   
+                        |p t|
 
-                    p := PipeStream readingFrom:'ls -l /bin /usr/bin /usr/lib'.
-                    t := p contents.
-                    p close.
-                    t
-                ] futureValue.
-        v := TextView new openAndWait.
-        v contents:text
+                        t1 := TimeDuration toRun:[
+                            p := PipeStream readingFrom:'ls -l /bin /usr/bin /usr/lib /etc'.
+                            t := p contents.
+                            p close.
+                        ].     
+                        t
+                    ] futureValue.
+            t2 := TimeDuration toRun:[
+                v := TextView new openAndWait.
+            ].    
+            v contents:text
+        ].
+        Transcript showCR:'Time to read: %1' with:t1.
+        Transcript showCR:'Time to open: %1' with:t2.
+        Transcript showCR:'Time overall: %1' with:tAll.
                                                                     [exEnd]
 "
 ! !
@@ -171,162 +190,128 @@
 !Future methodsFor:'evaluating'!
 
 block:aBlock
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [aBlock value] ensure:[semaphore signal. semaphore := nil.]
-    ] fork
+    self signalSemaphoreAfterForked:aBlock
 
     "Modified: / 09-08-2017 / 11:54:19 / cg"
     "Modified: / 12-02-2019 / 20:26:39 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:50:12 / Claus Gittinger"
 !
 
 block:aBlock value:aValue
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [aBlock value:aValue] ensure:[semaphore signal. semaphore := nil.]
-    ] fork
+    self signalSemaphoreAfterForked:[aBlock value:aValue]
 
     "Modified: / 09-08-2017 / 11:54:23 / cg"
     "Modified: / 12-02-2019 / 20:27:03 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:50:09 / Claus Gittinger"
 !
 
 block:aBlock value:value1 value:value2
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [
-            aBlock value:value1 value:value2
-        ] ensure:[semaphore signal. semaphore := nil.]
-    ] fork
+    self signalSemaphoreAfterForked:[aBlock value:value1 value:value2]
 
     "Modified: / 09-08-2017 / 11:54:27 / cg"
     "Modified: / 12-02-2019 / 20:27:20 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:50:06 / Claus Gittinger"
 !
 
 block:aBlock value:value1 value:value2 value:value3
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [
-            aBlock value:value1 value:value2 value:value3
-        ] ensure:[semaphore signal. semaphore := nil.]
-    ] fork
+    self signalSemaphoreAfterForked:[aBlock value:value1 value:value2 value:value3]
 
     "Modified: / 09-08-2017 / 11:54:31 / cg"
     "Modified: / 12-02-2019 / 20:27:31 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:50:03 / Claus Gittinger"
 !
 
 block:aBlock valueWithArguments:anArray
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [
-            aBlock valueWithArguments:anArray
-        ] ensure:[semaphore signal. semaphore := nil.]
-    ] fork
+    self signalSemaphoreAfterForked:[aBlock valueWithArguments:anArray]
 
     "Modified: / 09-08-2017 / 11:54:34 / cg"
     "Modified: / 12-02-2019 / 20:27:40 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:49:52 / Claus Gittinger"
 !
 
-priority:prio block: aBlock
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+priority:prio block:aBlock
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [aBlock value] ensure:[semaphore signal. semaphore := nil.]
-    ] forkAt:prio
+    self signalSemaphoreAfterForked:[aBlock value] atPriority:prio
 
     "Created: / 04-10-2011 / 14:53:21 / cg"
     "Modified: / 09-08-2017 / 11:54:38 / cg"
     "Modified: / 12-02-2019 / 20:27:52 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:50:20 / Claus Gittinger"
 !
 
 priority:prio block: aBlock value: aValue
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [
-            aBlock value:aValue
-        ] ensure:[semaphore signal. semaphore := nil.]
-    ] forkAt:prio
+    self signalSemaphoreAfterForked:[aBlock value:aValue] atPriority:prio
 
     "Created: / 04-10-2011 / 14:53:35 / cg"
     "Modified: / 09-08-2017 / 11:54:41 / cg"
     "Modified: / 12-02-2019 / 20:28:02 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:50:23 / Claus Gittinger"
 !
 
 priority:prio block:aBlock value:value1 value:value2
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [
-            aBlock value:value1 value:value2
-        ] ensure:[semaphore signal. semaphore := nil.]
-    ] forkAt:prio
+    self signalSemaphoreAfterForked:[aBlock value:value1 value:value2] atPriority:prio
 
     "Created: / 04-10-2011 / 14:54:03 / cg"
     "Modified: / 09-08-2017 / 11:54:44 / cg"
     "Modified: / 12-02-2019 / 20:28:10 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:50:26 / Claus Gittinger"
 !
 
 priority:prio block:aBlock value:value1 value:value2 value:value3
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [
-            aBlock value:value1 value:value2 value:value3
-        ] ensure:[semaphore signal. semaphore := nil.]
-    ] forkAt:prio
+    self signalSemaphoreAfterForked:[aBlock value:value1 value:value2 value:value3] atPriority:prio
 
     "Created: / 04-10-2011 / 14:54:51 / cg"
     "Modified: / 09-08-2017 / 11:54:47 / cg"
     "Modified: / 12-02-2019 / 20:28:21 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:50:29 / Claus Gittinger"
 !
 
 priority:prio block:aBlock valueWithArguments:anArray
-    "Execute aBlock in parallel with whatever called me, but
-     ensure that any messages sent to me before execution
+    "Execute aBlock in parallel with whoever called me, 
+     but ensure that any messages sent to me before execution
      of the block has terminated are suspended until it has terminated."
 
-    semaphore := Semaphore name:'Future'.
-    [
-        result := [
-            aBlock valueWithArguments:anArray
-        ] ensure:[semaphore signal. semaphore := nil.]
-    ] forkAt:prio
+    self signalSemaphoreAfterForked:[aBlock valueWithArguments:anArray] atPriority:prio
 
     "Created: / 04-10-2011 / 14:55:14 / cg"
     "Modified: / 09-08-2017 / 11:54:50 / cg"
     "Modified: / 12-02-2019 / 20:28:30 / Stefan Vogel"
+    "Modified (comment): / 25-06-2019 / 07:50:32 / Claus Gittinger"
 ! !
 
 !Future methodsFor:'printing'!
@@ -358,51 +343,88 @@
     ^ s contents
 ! !
 
+!Future methodsFor:'private'!
+
+signalSemaphoreAfterForked:aBlock
+    "common code for all block:* methods.
+     Execute aBlock in parallel with whatever called me, 
+     and ensure that my private semaphore is signalled at the end."
+
+    semaphore := Semaphore name:'Future'.
+    [
+        result := aBlock ensure:[semaphore signal. semaphore := nil.]
+    ] fork
+
+    "Created: / 25-06-2019 / 07:32:28 / Claus Gittinger"
+!
+
+signalSemaphoreAfterForked:aBlock atPriority:prio
+    "common code for all block:* methods.
+     Execute aBlock in parallel with whatever called me, 
+     and ensure that my private semaphore is signalled at the end."
+
+    semaphore := Semaphore name:'Future'.
+    [
+        result := aBlock ensure:[semaphore signal. semaphore := nil.]
+    ] forkAt:prio
+
+    "Created: / 25-06-2019 / 07:33:55 / Claus Gittinger"
+! !
+
 !Future methodsFor:'synchronising'!
 
 doesNotUnderstand:aMessage
     "Any message to a Future will end up here."
 
-    semaphore notNil ifTrue:[
+    |sema|
+    
+    (sema := semaphore) notNil ifTrue:[
         Processor activeProcess isDebuggerProcess ifTrue:[
             "enable debugging / inspecting"
             ^ aMessage sendTo:self usingClass:Object.
         ].
-        self value.
+        sema waitUncounted. "Wait for evaluation to complete"
+                            "(if not already completed)"
     ].
     ^ aMessage sendTo:result
 
     "Modified: / 04-10-2011 / 17:37:18 / cg"
     "Modified: / 01-02-2018 / 10:17:48 / stefan"
+    "Modified: / 25-06-2019 / 07:52:42 / Claus Gittinger"
 !
 
 perform:aSelector withArguments:argArray
     "send the message aSelector with all args taken from argArray
      to the receiver."
 
-    semaphore notNil ifTrue:[
+    |sema|
+
+    (sema := semaphore) notNil ifTrue:[
         Processor activeProcess isDebuggerProcess ifTrue:[
             "enable debugging / inspecting"
             ^ super perform:aSelector withArguments:argArray.
         ].
-        self value.
+        sema waitUncounted.
     ].
     ^ result perform:aSelector withArguments:argArray.
 
     "Modified (format): / 01-02-2018 / 10:17:44 / stefan"
+    "Modified: / 25-06-2019 / 07:53:01 / Claus Gittinger"
 !
 
 value
+    "retrieve the value, possibly waiting for the result to arrive"
+    
     |sema|
 
-    sema := semaphore.
-    sema notNil ifTrue:[
-        semaphore waitUncounted. "Wait for evaluation to complete"
-                                 "(if not already completed)"
+    (sema := semaphore) notNil ifTrue:[
+        sema waitUncounted. "Wait for evaluation to complete"
+                            "(if not already completed)"
     ].
     ^ result
 
     "Created: / 04-10-2011 / 17:36:06 / cg"
+    "Modified (comment): / 25-06-2019 / 07:53:28 / Claus Gittinger"
 ! !
 
 !Future methodsFor:'testing'!