2014-06-23 22:38 GMT+02:00 Norbert Hartl <[email protected]>: > 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? >
But what happens when you immediately fork, are you sure the forked process immediately pre-empts the activeProcess? What if you introduce Processor activeProcess yield after the fork? > > 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 >> <http://trunk4.6effectiveprocessmethods.st/>> >> >> >> > > > -- > best, > Eliot > > >
