[squeak-dev] The Inbox: Kernel-jar.1475.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Jun 4 20:31:49 UTC 2022


A new version of Kernel was added to project The Inbox:
http://source.squeak.org/inbox/Kernel-jar.1475.mcz

==================== Summary ====================

Name: Kernel-jar.1475
Author: jar
Time: 4 June 2022, 10:31:44.661893 pm
UUID: 923d5402-9a8d-0a48-87d7-44c56400dd0c
Ancestors: Kernel-jar.1474

Fix a scenario when a delay or yield inside unwind blocks may cause control be handed over to the original process which may be assuming the termination has completed. (A higher priority for termination is indeed not a solution)

A process that invokes termination of another process is assumed to wait until the terminating process finishes unwinding itself. This may be useful during cleanup operations requiring e.g. waiting for resources etc.

A complementing test 'testTerminateWithDelayInUnwind' is part of the additional collection of tests in KernelTests-jar.428.

=============== Diff against Kernel-jar.1474 ===============

Item was changed:
  ----- Method: Process>>terminate (in category 'changing process state') -----
  terminate 
  	"Stop the process that the receiver represents forever.
  	 Unwind to execute pending #ensure:/#ifCurtailed: blocks before terminating;
+ 	 allow all unwind blocks to run; if they are currently in progress, let them finish."
- 	 allow all unwind blocks to run; if they are currently in progress, let them finish.
- 	 If the process is in the middle of a #critical: critical section, release it properly."
  	
+ 	 "This is the kind of behavior we expect when terminating a healthy process.
- 	"This is the kind of behavior we expect when terminating a healthy process.
  	 See further comments in #terminateAggressively and #destroy methods dealing 
+ 	 with process termination when closing the debugger or after a catastrophic failure.
+ 	 
+ 	 If terminating the active process, create a new stack and run unwinds from there.
- 	 with process termination when closing the debugger or after a catastrophic failure."
  	
+ 	 If terminating a suspended process (including runnable and blocked), always
+ 	 suspend the terminating process first so it doesn't accidentally get woken up. 
+ 	 Equally important is the side effect of the suspension: In 2022 a new suspend
+ 	 semantics has been introduced: the revised #suspend backs up a process waiting
+ 	 on a conditional variable to the send that invoked the wait state, while the previous
+ 	 #suspend simply removed the process from the conditional variable's list it was
+ 	 previously waiting on; see #suspend and #suspendAndUnblock comments.
- 	"If terminating the active process, create a parallel stack and run unwinds from there;
- 	 if terminating a suspended process, again, create a parallel stack for the process being
- 	 terminated and resume the suspended process to complete its termination from the new
- 	 parallel stack. Use a priority higher than the active priority to make the process that
- 	 invoked the termination wait for its completion."
  
+ 	 If the process is in the middle of a #critical: critical section, release it properly.
+ 	
+ 	 To allow a suspended process to unwind itself, create a new stack for the process
+ 	 being terminated and resume the suspended process to complete its termination
+ 	 from the new parallel stack. Use a semaphore to make the process that invoked
+ 	 the termination wait for self's completion. Execute the termination in the ensure
+ 	 argument block to ensure it completes even if the terminator process itself gets
+ 	 terminated before it's finished; see testTerminateInTerminate."
+ 	
- 	"If terminating a suspended process (including runnable and blocked), always suspend
- 	 the terminating process first so it doesn't accidentally get woken up. Equally important is
- 	 the side effect of the suspension; In 2022 a new suspend semantics has been introduced:
- 	 the revised #suspend backs up a process waiting on a conditional variable to the send that
- 	 invoked the wait state, while the pre-2022 #suspend simply removed the process from
- 	 the conditional variable's list it was previously waiting on; see Process>>suspend comments.
- 	 Execute the termination in the ensure argument block to ensure it completes even if the 
- 	 terminator process itself gets terminated before it's finished; see testTerminateInTerminate."
- 
  	| context |
  	self isActiveProcess ifTrue: [
  		context := thisContext.
  		^[context unwindTo: nil. self suspend] asContext jump].
  
+ 	[] ensure: [ | terminator |
- 	[] ensure: [ 
  		self suspendAndReleaseCriticalSection.
  		context := suspendedContext ifNil: [^self].
+ 		terminator := Semaphore new.
+ 		suspendedContext := [context unwindTo: nil. terminator signal. self suspend] asContext.
+ 		self priority: Processor activePriority; resume.
+ 		terminator wait]!
- 		suspendedContext := [context unwindTo: nil. self suspend] asContext.
- 		self priority: (Processor activePriority + 1 min: Processor highestPriority); resume]!



More information about the Squeak-dev mailing list