#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
--- 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'!