Hmmm,

I'm trying to write a test for it and I wonder why 

testDynamicVariableAccessFromDifferentProcess
        | process  sem1 result    |
        
        sem1 := Semaphore new.
        process := [  
                TestDynamicVariable 
                        value: 123 
                        during: [ sem1 wait ] ] fork.
                
        Processor activeProcess 
                evaluate: [  result := TestDynamicVariable value ] 
                onBehalfOf: process.
        sem1 signal.
        self assert: result = 123

does not work. The variable accessing is in 

DynamicVariable>>#value: anObject during: aBlock
        | p oldValue |
        p := Processor activeProcess.
        oldValue := (p psValueAt: index) ifNil: [ self default ].
        ^ [ 
                p psValueAt: index put: anObject.
                aBlock value ] ensure: [ p psValueAt: index put: oldValue ]

Any ideas?

Norbert

Am 23.06.2014 um 21:29 schrieb Eliot Miranda <[email protected]>:

> 
> 
> 
> On Mon, Jun 23, 2014 at 12:05 PM, Norbert Hartl <[email protected]> wrote:
> Hi Eliot,
> 
> thank you very much. I imported your changes in a pharo 3 image and it works 
> awesome. So I'm preparing a slice for pharo. 
> 
> Thanks again, a very annoying problem seems to be solved,
> 
> glad to hear it, and thanks for your prompting me as it's now in Squeak trunk 
> too.
>  
> 
> Norbert
> 
> Am 23.06.2014 um 19:29 schrieb Eliot Miranda <[email protected]>:
> 
>> and here are the changes I've just committed to Squeak trunk.
>> 
>> 
>> On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda<[email protected]> 
>> wrote:
>> Hi Norbert,
>> 
>>     [ let me try again.  never try and get code out too early in the morning 
>> ;-) ]
>> 
>>     it is the debugger that needs fixing, not your code !! :-).  The 
>> debugger needs to respect process identity.  Andreas and I (mostly Andreas) 
>> came up with the following changes at Qwaq.  Your message is a good reminder 
>> that I need to add this to Squeak asap.
>> 
>> The idea is for Process to have an additional inst var 'effectiveProcess' 
>> that holds the actual process running code.  For the most part this is self, 
>> but in the debugger we substitute the process being debugged:
>> 
>> Process methods for accessing
>> effectiveProcess
>>      "effectiveProcess is a mechanism to allow process-faithful debugging.  
>> The debugger executes code
>>       on behalf of processes, so unless some effort is made the identity of 
>> Processor activeProcess is not
>>       correctly maintained when debugging code.  The debugger uses 
>> evaluate:onBehalfOf: to assign the
>>       debugged process as the effectiveProcess of the process executing the 
>> code, preserving process
>>       identity."
>>      ^effectiveProcess ifNil: [self]
>> 
>> then the relevant methods in Process and processorScheduler defer to 
>> effectiveProcess, e.g.
>> 
>> ProcessorScheduler methods for process state change
>> terminateActive
>>      "Terminate the process that is currently running."
>> 
>>      activeProcess effectiveProcess terminate
>> 
>> and the debugging methods use evaluate:onBehalfOf: to install the process 
>> being debugged:
>> 
>> Process methods for private
>> evaluate: aBlock onBehalfOf: aProcess
>>      "Evaluate aBlock setting effectiveProcess to aProcess.  Used
>>       in the execution simulation machinery to ensure that
>>       Processor activeProcess evaluates correctly when debugging."
>>      | oldEffectiveProcess |
>>      oldEffectiveProcess := effectiveProcess.
>>      effectiveProcess := aProcess.
>>      ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
>> 
>> Process methods for changing suspended state
>> step
>> 
>>      ^Processor activeProcess
>>              evaluate: [suspendedContext := suspendedContext step]
>>              onBehalfOf: self
>> 
>> stepToCallee
>>      "Step until top context changes"
>> 
>>      Processor activeProcess
>>              evaluate:
>>                      [| ctxt |
>>                      ctxt := suspendedContext.
>>                      [ctxt == suspendedContext] whileTrue: [
>>                              suspendedContext := suspendedContext step]]
>>              onBehalfOf: self.
>>      ^suspendedContext
>> 
>> etc.  Changes from a Qwaq image attached.
>> 
>> HTH
>> 
>> 
>> On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <[email protected]>wrote:
>> In my code I'm using a DynamicVariable to request a context object when 
>> needed. Until now I knew the name DynamicVariable only from seaside. There 
>> it is called WADynamicVariable and it is an exception. So I blindly assumed 
>> the pharo DynamicVariable works the same.
>> I thought this might be a good optimization not to travel the stack all the 
>> time but put in the process.
>> Now that I am using it I can see the difference. I find it real hard using 
>> it because I don't know how to debug/step in code. DynamicVariable is a 
>> process specific variable but as soon as a debugger opens it is very likely 
>> to be in another process. This makes stepping in method using the 
>> DynamicVariable impossible. The only way round is to set break points after 
>> the dynamic lookup and step from there. But this feels just wrong.
>> What would be the best way to have DynamicVariable and be able to debug 
>> anything? Or is there a variant that uses the stack instead of the "active" 
>> process?
>> 
>> thanks,
>> 
>> Norbert
>> 
>> 
>> 
>> 
>> 
>> -- 
>> best,
>> Eliot
>> 
>> 
>> 
>> -- 
>> best,
>> Eliot
>> <trunk4.6EffectiveProcessMethods.st>
> 
> 
> 
> 
> -- 
> best,
> Eliot

Reply via email to