Image is Squeak3.10.gamma.7159.
I have a visualization demo. It runs in a separate process to permit mouse and keyboard input while it runs: startChaosAnimation currentState = #CHAOS ifTrue: [^self]. currentState := #CHAOS. processSemaphore wait. BB2ChaosCtx startChaosAnimationOn: data. processSemaphore signal. ] fork. BB2ChaosCtx startChaosAnimationOn: data starts a loop that creates and removes Morphs interspersed with suitable Delays to get the speed right. The process can run for several hours before crashing in various ways. It sometimes crashes with a primitiveError while redisplaying World. A simpler stop was an MNU in MorphicEventDispatcher>>dispatchDefault: anEvent with: aMorph where aMorph = a PasteUpMorph [world], with fullBounds = nil My process is clearly in some unfortunate state when the main process repaints or handles the mouse. Any ideas how I should make my process safe? Thanks in advance --Trygve --
Trygve
Reenskaug mailto: [hidden email] Morgedalsvn. 5A http://heim.ifi.uio.no/~trygver N-0378
Oslo Tel: (+47) 22 49 57 27 Norway |
Trygve Reenskaug wrote:
> I have a visualization demo. It runs in a separate process to permit > mouse and keyboard input while it runs: > startChaosAnimation > currentState = #CHAOS ifTrue: [^self]. > currentState := #CHAOS. > processSemaphore wait. > BB2ChaosCtx startChaosAnimationOn: data. > processSemaphore signal. > ] fork. > > BB2ChaosCtx startChaosAnimationOn: data starts a loop that creates and > removes Morphs interspersed with suitable Delays to get the speed right. > > The process can run for several hours before crashing in various ways. > It sometimes crashes with a primitiveError while redisplaying World. A > simpler stop was an MNU in > MorphicEventDispatcher>>dispatchDefault: anEvent with: aMorph > where aMorph = a PasteUpMorph [world], with fullBounds = nil > > My process is clearly in some unfortunate state when the main process > repaints or handles the mouse. Any ideas how I should make my process safe? Use Morph stepping instead of an unsynchronized process. Cheers, - Andreas |
Thanks Andreas, for your very quick answer.
Stepping was the first mechanism I tried, but the program got very complex keeping track of what to do at each step. My goal is to have a simple, readable program and the stepping alternative was neither simple nor readable. So I'm trying other solutions. Cheers --Trygve On 06.05.2009 18:09, Andreas Raab wrote: Trygve Reenskaug wrote: --
Trygve
Reenskaug mailto: [hidden email] Morgedalsvn. 5A http://heim.ifi.uio.no/~trygver N-0378
Oslo Tel: (+47) 22 49 57 27 Norway |
Trygve Reenskaug wrote:
> Thanks Andreas, for your very quick answer. > Stepping was the first mechanism I tried, but the program got very > complex keeping track of what to do at each step. My goal is to have a > simple, readable program and the stepping alternative was neither simple > nor readable. So I'm trying other solutions. In that case you need to define what a "stable" state for your simulation is. Once you have that you can implement something where you pass a semaphore into the simulation that is being signaled when the simulation should make progress, and that the simulation waits on when it's in a stable state. Along the lines of: sema := Semaphore new. [ sema wait. "wait for the simulation to begin" simulator syncSema: sema. simulator simulate. ] forkAt: Processor userInterruptPriority. MyMorph>>step "Allow our simulation to run until it has reached stable state" sema signal. Then anywhere in the simulation where it's safe to do so, just throw in a sema wait. Cheers, - Andreas |
In reply to this post by Trygve
On Wed, May 06, 2009 at 05:50:09PM +0200, Trygve Reenskaug wrote:
> Image is Squeak3.10.gamma.7159. > > I have a visualization demo. It runs in a separate process to permit > mouse and keyboard input while it runs: > startChaosAnimation > currentState = #CHAOS ifTrue: [^self]. > currentState := #CHAOS. > processSemaphore wait. > BB2ChaosCtx startChaosAnimationOn: data. > processSemaphore signal. > ] fork. > > BB2ChaosCtx startChaosAnimationOn: data starts a loop that creates and > removes Morphs interspersed with suitable Delays to get the speed right. > > The process can run for several hours before crashing in various ways. > It sometimes crashes with a primitiveError while redisplaying World. A > simpler stop was an MNU in > MorphicEventDispatcher>>dispatchDefault: anEvent with: aMorph > where aMorph = a PasteUpMorph [world], with fullBounds = nil > > My process is clearly in some unfortunate state when the main process > repaints or handles the mouse. Any ideas how I should make my process safe? Morphic does everything in its own main UI process, but none of the things that happen in that process are necessarily "thread safe". If you want some other process (such as the process in which your animation is running) to do things in the Morphic UI process, then your animation process should schedule things to be executed: WorldState addDeferredUIMessage: [doSomethingInTheMorphicUIProcess] This causes #doSomethingInTheMorphicUIProcess to be evaluated shortly thereafter in the context of the Morphic UI process, hence no crashes. I have not tried this with MorphicEventDispatcher>>dispatchDefault:with:, but I expect that wrapping the call in #addDeferredUIMessage: may take care of your problem. Dave |
In reply to this post by Andreas.Raab
Many thanks for helping me along. Your advice to use stepping was sound, but didn't quite fit my needs. I tried several alternative solutions with running my visualization in a separate process, but they all failed. This led to an important (in retrospect: obvious) discovery: I CANNOT CHANGE THE DISPLAYED MORPHS IN A SEPARATE PROCESS. Reason: Adding, removing, or changing a submorph lead to a call on Morph>>layoutChanged which sets fullBounds := nil recursively up the owner chain. At the same time, the normal process is happily repeating WorldState>>doOneCycleFor: aWorld. This includes redisplaying the World, computing fullBounds if needed. The separate process can have set fullBounds to nil at any point in the redisplay loop. Usually, this has no bad effect, but MNU or primitiveError can happen in rare cases. (I run my animation overnight to make this happen.) Hence the above conclusion. Two unsynchronized processes should not share a common variable. The basic process and my process did share the whole morphic display hierarchy. No apologies for stating the obvious --Trygve On 06.05.2009 18:09, Andreas Raab wrote: Trygve Reenskaug wrote: --
Trygve
Reenskaug mailto: [hidden email] Morgedalsvn. 5A http://heim.ifi.uio.no/~trygver N-0378
Oslo Tel: (+47) 22 49 57 27 Norway |
Free forum by Nabble | Edit this page |