Saving and resuming an exception context?

Andreas Raab andreas.raab at gmx.de
Thu Mar 25 00:54:17 UTC 2004


> Is there an easy way to do this?

Sure. What you are describing is a process ;-)

MyClass>>runBlock: aBlock frozenContext: aProcess
    | frozenState |
    (aProcess notNil and:[aProcess isTerminated not])
        ifTrue:[^aProcess resume].
    frozenState := Process forContext:[
        [aBlock value] on: FreezeMe do:[:ex|
            "Suspend on FreezeMe"
            Processor activeProcess suspend.
            "But resume ex after resuming the process"
            ex resume.
        ].
    ] priority: Processor activeProcess priority + 1.
    ^frozenState resume

About the only situations where this wouldn't work is when the block you are
running waits on a semaphore for some reason (which would continue the
calling process). This problem can be addressed by associating an extra
semaphore with the process which is signaled upon FreezeMe and waited for in
the caller, e.g.,

MyClass>>runBlock: aBlock frozenContext: aProcess
    | frozenState |
    (aProcess notNil and:[aProcess isTerminated not])ifTrue:[
        aProcess resume.
        aProcess freezeSemaphore wait.
    ].
    frozenState := Process forContext:[
        [aBlock value] on: FreezeMe do:[:ex|
            "Tell client that we're done"
            Processor activeProcess freezeSemaphore signal.
            "Suspend on FreezeMe"
            Processor activeProcess suspend.
            "But resume ex after resuming the process"
            ex resume.
        ].
    ] priority: Processor activeProcess priority + 1.
    frozenState freezeSemaphore: Semaphore new.
    frozenState resume.
    frozenState freezeSemaphore wait.
    ^frozenState

Note the subtlety of priority + 1, it makes sure that we're really done with
the block one way or another before giving control back to the caller (this
avoids some potential problems with being interrupted in a bad place).

Cheers,
  - Andreas

----- Original Message ----- 
From: "Ned Konz" <ned at squeakland.org>
To: <squeak-dev at lists.squeakfoundation.org>
Sent: Thursday, March 25, 2004 1:34 AM
Subject: Saving and resuming an exception context?


> Perhaps someone (Anthony?) can tell me how to do this (preferably with a
stock
> VM):
>
> I'd like to be able to evaluate a block, and upon an exception freeze the
> execution state so that it can be resumed later (not necessarily from the
> same context). Kind of like a continuation, but without replacing the
current
> stack context.
>
> That is:
>
> Notification subclass: FreezeMe ...
>
> MyClass>>runBlock: aBlock frozenContext: oldFrozenState
> | frozenState |
> frozenState := nil.
> [ oldFrozenState
> ifNotNil: [ oldFrozenState resumeSomehow ]
> ifNil: [ aBlock value ] ]
> on: FreezeMe
> do: [ :ex | frozenState := ex freezeForLater ].
> ^frozenState
>
> Then I could do this:
>
> frozen := self runBlock: someBlock frozenContext: frozen.
>
> and go off and do something else and come back later and repeat it at
will.
> The block would run until it signaled a FreezeMe.
>
> Of course, what I need here is a definition for
>
> Exception>>freezeForLater
>
> and one for
>
> (frozen)>>resumeSomehow
>
> Is there an easy way to do this?
>
> Thanks,
> -- 
> Ned Konz
> http://bike-nomad.com/squeak/
>




More information about the Squeak-dev mailing list