Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
September 2014
- 1227 messages
Re: [Pharo-dev] [Issue Tracker] Call for CleanUp of the issue tracker
by Marcus Denker
On 22 Sep 2014, at 15:00, Sean P. DeNigris <sean(a)clipperadams.com> wrote:
> Marcus Denker-4 wrote
>> But for me it is important that they are âclosed*
>
> I understand. It seems Closed + special status serves both needs. I had
> proposed "stale" before, but it seemed that existing "postponed" was close
> enough last time we discussed.
>
I will add a "Closed (stale)â status (sometimes when I find time later the week)
Marcus
Sept. 22, 2014
Re: [Pharo-dev] Fixed case 11996 -- exception handler search bug
by Marcus Denker
On 22 Sep 2014, at 17:05, Martin McClure <martin(a)hand2mouse.com> wrote:
> This fix required multiple slices since loading things in the wrong order broke exceptions badly enough to hang the system. I packaged things in five slices. (It's possible that if Monticello was smart enough I could have done it in less than five, but it did need more than one).
>
> The automatic test runner seems to only load the first of the five slices. Therefore two exception tests fail, which is expected. All exception tests should pass after all five slices are loaded in order.
>
> Is there a way to tell the automatic test runner to load all five, or does this one require manual testing? (I did test it manually before dropping the slices in the inbox, but that was a month ago.)
Maybe for a complex change like that we should sync off list⦠the normal machinery is good for normal stuff, everything else needs exceptional work.
(e.g. we could load changesets, could be simpler than using monticello)
Marcus
Sept. 22, 2014
Re: [Pharo-dev] Exceptions chapter of Deep Into Pharo
by Damien Cassou
On Mon, Sep 22, 2014 at 4:44 PM, Martin McClure <martin(a)hand2mouse.com> wrote:
> OK, send me the SVN info and I'll work on the edits.
please create an account on https://gforge.inria.fr and ask to join
the project pharobooks.
--
Damien Cassou
http://damiencassou.seasidehosting.st
"Success is the ability to go from one failure to another without
losing enthusiasm."
Winston Churchill
Sept. 22, 2014
Re: [Pharo-dev] I'm confused about Process>>isTerminated
by Eliot Miranda
Hi Max,
phhh, that editor truncated my reply (that's my excuse and I'm sticking
to it), so...
On Mon, Sep 22, 2014 at 4:57 AM, Max Leske <maxleske(a)gmail.com> wrote:
> Hi Eliot,
>
> Thanks a lot for those explanations.
>
> On 18.09.2014, at 20:53, Eliot Miranda <eliot.miranda(a)gmail.com> wrote:
>
> Hi Max,
>
> phhh, time zone differences suck ;-)
>
> On Thu, Sep 18, 2014 at 3:50 AM, Max Leske <maxleske(a)gmail.com> wrote:
>
>> Hi Eliot,
>>
>> On 18.09.2014, at 01:18, Eliot Miranda <eliot.miranda(a)gmail.com> wrote:
>>
>> Hi Max,
>>
>> On Wed, Sep 17, 2014 at 1:59 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>
>>> Hi Eliot
>>>
>>>
>>> On 16.09.2014, at 20:18, Eliot Miranda <eliot.miranda(a)gmail.com> wrote:
>>>
>>> Hi Max,
>>>
>>> On Tue, Sep 16, 2014 at 11:05 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>>
>>>> Hi
>>>>
>>>> As always when I want to check if a process has died I get very
>>>> confused by #isTerminated and Iâm wondering if I just donât get how itâs
>>>> supposed to work or if there are others that share my confusion.
>>>>
>>>> Old implementation:
>>>>
>>>> isTerminated
>>>>
>>>> self isActiveProcess ifTrue: [^ false].
>>>> ^suspendedContext isNil
>>>> or: ["If the suspendedContext is the bottomContext it is the
>>>> block in Process>>newProcess.
>>>> If so, and the pc is greater than the startpc, the
>>>> bock has alrteady sent and returned
>>>> from value and there is nothing more to do."
>>>> suspendedContext isBottomContext
>>>> and: [ suspendedContext pc > suspendedContext startpc
>>>> ] ]
>>>>
>>>>
>>>> Pharo 4 implementation:
>>>>
>>>> isTerminated
>>>> self isActiveProcess ifTrue: [^ false].
>>>> ^suspendedContext isNil
>>>> or: ["If the suspendedContext is the bottomContext it is the
>>>> block in Process>>newProcess.
>>>> If so, and the pc is greater than the startpc, the
>>>> bock has alrteady sent and returned
>>>> from value and there is nothing more to do.â
>>>> suspendedContext isBottomContext
>>>> and: [ suspendedContext isDead not
>>>> â<âââââââââââââââââââââââââ new"
>>>> and: [ suspendedContext pc > suspendedContext startpc
>>>> ] ] ]
>>>>
>>>>
>>>> The old implementation would break if the suspended context was dead
>>>> (i.e. the pc was nil) because the send of #> would produce an MNU.
>>>> The new implementation doesnât fix that, even though it looks like it
>>>> at first glance: if the pc is nil, the #> send will still happen -> MNU.
>>>>
>>>
>>> Off the top of my head it would seem that it should be isDead or: [] not
>>> isDead not and:
>>>
>>> isTerminated
>>> self isActiveProcess ifTrue: [^ false].
>>> ^suspendedContext isNil
>>> or: ["If the suspendedContext is the bottomContext it is the
>>> block in Process>>newProcess.
>>> If so, and the pc is greater than the startpc, the
>>> bock has alrteady sent and returned
>>> from value and there is nothing more to do.â
>>> suspendedContext isBottomContext
>>> and: [ suspendedContext isDead
>>> or: [ suspendedContext pc > suspendedContext
>>> startpc ] ] ]
>>>
>>>
>>> Phew. Glad you see that the same way.
>>>
>>> isDead
>>>> ^ pc isNil
>>>>
>>>
>>> and maybe (suspendedContext pc ifNil: [true] ifNotNil: [:pc| pc >
>>> suspendedContext startpc]) is more obvious.
>>>
>>> Anyway, neither implementation will reliably tell me if the process has
>>>> been terminated:
>>>> - an inactive process will be suspended when #terminate is sent and
>>>> report that it has not been terminated (#isSuspended -> true, #isTerminated
>>>> -> false)
>>>>
>>>
>>> except that it *hasn't* been terminated, it is merely in the process of
>>> termination. It isn't terminated until all unwind blocks have run, right?
>>>
>>>
>>> True. Easy to forget when you can just kill -9 on the console⦠:)
>>>
>>>
>>>
>>>> - a properly terminated process will raise an MNU (although apparently
>>>> not always�)
>>>>
>>>
>>> but that's a bug the change I suggested will fix.
>>>
>>>
>>>> - all the states in between: no clue
>>>>
>>>> I would like to know two things:
>>>> 1. how can I check if a process has already *received* a #terminate? (I
>>>> would then assume that the process will die eventually)
>>>>
>>>
>>> I don't think you can without putting a critical section around
>>> terminate and adding some process-specific variable that is set when you
>>> send terminate. termination is not instantaneous (unwind blocks have to be
>>> run), so it is potentially interruptible.
>>>
>>>
>>> Iâve thought about this a bit. I wouldnât really care if I donât get a
>>> correct answer about the termination status immediately but I want to have
>>> it before the process terminates. In case of something like the following:
>>>
>>> ([ 10 seconds asDelay wait ] forkAt: 11) terminate
>>>
>>> it can (potentially) take a very long time for the process to terminate.
>>> So if I have to poll 3 or 4 times thatâs ok but I donât want to wait for
>>> minutes.
>>> One solution would be to take your idea of the variable, but without the
>>> critical block:
>>>
>>> terminate
>>> "Stop the process that the receiver represents forever. Unwind to
>>> execute pending ensure:/ifCurtailed: blocks before terminating."
>>>
>>> | ctxt unwindBlock oldList |
>>> terminating := true. â<âââââââââââââââââââââââââââââââââââ changed"
>>> self isActiveProcess
>>> ifTrue: [
>>> ctxt := thisContext.
>>> [ ctxt := ctxt findNextUnwindContextUpTo: nil.
>>> ctxt isNil ] whileFalse:
>>> [ (ctxt tempAt: 2) ifNil:
>>> [ ctxt tempAt: 2 put: nil.
>>> unwindBlock := ctxt tempAt: 1.
>>> thisContext terminateTo: ctxt.
>>> unwindBlock value ]].
>>> thisContext terminateTo: nil.
>>> self suspend ]
>>> ifFalse: [
>>> "Always suspend the process first so it doesn't accidentally get woken
>>> up"
>>> oldList := self suspend.
>>> suspendedContext ifNotNil:[
>>> "Figure out if we are terminating the process while waiting in
>>> Semaphore>>critical:
>>> In this case, pop the suspendedContext so that we leave the ensure:
>>> block inside
>>> Semaphore>>critical: without signaling the semaphore."
>>> (oldList class == Semaphore and:[
>>> suspendedContext method == (Semaphore compiledMethodAt: #critical:)])
>>> ifTrue:[
>>> suspendedContext := suspendedContext home.].
>>> "If we are terminating a process halfways through an unwind, try to
>>> complete that unwind block first."
>>> (suspendedContext findNextUnwindContextUpTo: nil) ifNotNil: [ :outer |
>>> (suspendedContext findContextSuchThat: [ :c | c closure == (outer
>>> tempAt: 1)])
>>> ifNotNil: [ :inner |
>>> "This is an unwind block currently under evaluation"
>>> suspendedContext runUntilErrorOrReturnFrom: inner ]].
>>> ctxt := self popTo: suspendedContext bottomContext.
>>> ctxt == suspendedContext bottomContext ifFalse: [
>>> self debug: ctxt title: 'Unwind error during termination']] ].
>>>
>>>
>>>
>>> isTerminating
>>> ^ terminating ifNil: [ ^ false ]
>>>
>>>
>>> With this small modification I can run the example from above and
>>> immediately see that it will die eventually.
>>>
>>> Iâm aware that one process might not see the change to the variable
>>> immediately but as I said, I wouldnât really care.
>>>
>>>
>>> What do you think?
>>>
>>
>> Yes that looks good. But given that branches are atomic (ifTrue: is not
>> a send) why not do
>>
>> Process>>initialize
>> terminating := false.
>>
>> terminate
>> "Stop the process that the receiver represents forever. Unwind to
>> execute pending ensure:/ifCurtailed: blocks before terminating."
>>
>> | ctxt unwindBlock oldList |
>> terminating
>> ifTrue: [self error: 'Process is already terminated, or being terminated']
>> ifFalse: [terminating := true].
>> self isActiveProcess
>> ifTrue:
>> ...
>>
>> ?
>>
>> I would suggest a status inst var, as in
>>
>> Process>>initialize
>> status := nil
>>
>> terminate
>> "Stop the process that the receiver represents forever. Unwind to
>> execute pending ensure:/ifCurtailed: blocks before terminating."
>>
>> | ctxt unwindBlock oldList |
>> status == #terminating
>> ifTrue: [self error: 'Process is already terminated, or being terminated']
>> ifFalse: [status := terminating].
>> self isActiveProcess
>> ifTrue:
>> ...
>>
>> but the temptation then is to have lots of different status values and
>> I'm leery of introducing that kind of complication without a strong
>> justification.
>>
>>
>>
>> Iâve worked a bit on an implementation along your suggestions. I wrote a
>> test which looks like this:
>>
>> testIsTerminated
>> | proc |
>> proc := [ Semaphore new wait ] forkAt: 30.
>> self deny: proc isSuspended.
>> self deny: proc isTerminating.
>> self deny: proc isTerminated.
>> proc terminate.
>> self deny: proc isTerminated.
>> self assert: proc isSuspended.
>> self assert: proc isTerminating.
>> [ proc isTerminated ] whileFalse: [ 1 second asDelay wait ].
>> â<âââââââââââ ???"
>>
>> self assert: proc isTerminated.
>> self assert: proc isTerminating
>>
>> The test works AFAICT (apart from the loopâ¦) but I want to also have a
>> check after the process has terminated. Is there some reliable way to wait
>> for a process to die? I tried something like this for example:
>>
>> proc run.
>> self assert: proc isTerminated.
>>
>> But that locks up the active process (obviously) until I interrupt it
>> manually. If there is such a way, I could also add a method that lets a
>> process x wait for the completion of a process y for example (or not,
>> depending on how difficult it is :) )
>>
>
> I can't see anything to do other than waiting. One thing is to run the
> process at as close to user priority as possible, so I would say
>
> proc := [ Semaphore new wait ] forkAt: Processor activePriority - 1.
>
> Another important thing is that you're not giving your process a chance to
> run before you test for it not terminating. So adding a yield after the
> first set of asserts and then repeating them is good:
>
> started := false. proc := [ started := true. Semaphore new wait ] forkAt:
> 30.
> self deny: proc isSuspended.
> self deny: proc isTerminating.
> self deny: proc isTerminated.
> (Delay forMilliseconds: 10) wait. self assert: started.
> self deny: proc isSuspended.
> self deny: proc isTerminating.
> self deny: proc isTerminated.
>
> Another thing might be to boost its priority to make sure it finishes
> (except that that'll probably have no effect because IIRC right now the
> terminator runs the termination). So you could say
>
> proc terminate.
> self deny: proc isTerminated.
> self assert: proc isSuspended.
> self assert: proc isTerminating.
>
> process priority: Processor activePriority + 1.
> [ proc isTerminated ] whileFalse: [ 1 second asDelay wait ].
>
> Further I'd want to test that unwind blocks have been run so I'd say
>
> testIsTerminated
> | proc started unwound terminator |
> unwound := false. proc := [ started := true. [Semaphore new wait]
> ensure: [terminator := Processor activeProcess.
> unwound := true] ]
> forkAt: Processor activePriority - 1.
> self deny: proc isSuspended.
> self deny: proc isTerminating.
> self deny: proc isTerminated.
> (Delay forMilliseconds: 10) wait. "Alloc proc to run; there shouldnt be
> too much else going on so this delay should suffice"
>
> self assert: started.
> self deny: proc isSuspended.
> self deny: proc isTerminating.
> self deny: proc isTerminated.
> proc terminate.
> proc priority: Processor activePriority + 1. "This may have no effect;
> termination may be executed by the terminator rather than the terminatee;
> ys, this is a bug"
> self deny: proc isTerminated.
> self assert: proc isSuspended.
> self assert: proc isTerminating.
> (Delay forMilliseconds: 10) wait. "Allow proc to terminate; there
> shouldnt be too much else going on so this delay should suffice"
>
> self assert: proc isTerminated.
> self assert: proc isTerminating.
> self assert: unwound.
> self assert: terminator == proc. "But this should be made an expected
> failure; I don't know how to do that in SUnitâ¦"
>
>
> From your comments I expected this last statement to fail but actually it
> doesnât. I guess thatâs a good sign (?).
>
>
> and google's mail text editor *SUCKS*!!!!
>
>
> lol :p
>
> I noticed something else regarding terminated processes that have never
> run and Iâm not sure if thatâs not a bug:
> When I suspend a process (that has never run) that is not the active
> process, I can reliably reproduce that the entire #terminate method is
> being executed. The processâ suspendedContext is the bottom context (as it
> should be). However, the pc is equal to the startpc, since that process
> never had a chance to to anything. The result is that #isTerminated will
> answer false, even though the process is technically terminated.
> One side effect of this is that itâs impossible to do something like â[
> proc isTerminated ] whileFalse: [ 1 second asDelay wait ].â because that
> will not terminate for all processes. Luckily those processes can be
> garbage collected regardless of what #isTerminated says.
>
> One obvious fix would be to set the pc of the suspendedContext to nil but
> Iâm not sure thatâs a good idea.
>
> What do you think?
>
I think that's fine.
Cheers,
> Max
>
> Cheers,
>> Max
>>
>> Cheers,
>>> Max
>>>
>>> 2. how can I check if a process is *actually* dead? (in case a âhalf
>>>> deadâ process will still unwind or whatever)
>>>>
>>>
>>> see above.
>>>
>>> What would be necessary to make those tests (or better ones) possible
>>>> (rewrite the whole process implementation?)?
>>>>
>>>> Cheers,
>>>> Max
>>>
>>> --
>>> best,
>>> Eliot
>>>
>>> --
>> best,
>> Eliot
>>
>> --
> best,
> Eliot
>
> --
best,
Eliot
Sept. 22, 2014
Re: [Pharo-dev] GToolkit in Pharo 4?
by Tudor Girba
Thanks Andrei!
For the rest of the tools, we kindly ask you to be patient until we release
Moose 5 and switch development to Pharo 4.
Cheers,
Doru
On Mon, Sep 22, 2014 at 5:43 PM, Andrei Chis <chisvasileandrei(a)gmail.com>
wrote:
> Not all GT-Tools work in Pharo 4 (e.g. the debugger does not work).
> You can load the Playground + a subset of the inspector (without roassal)
> using the code below.
> (You still need to manually enable them from the setting browser -> GT)
>
> Gofer new smalltalkhubUser: 'Moose'
> project: 'GToolkit';
> package: 'ConfigurationOfGTPlayground';
> load.
>
> (((Smalltalk at: #ConfigurationOfGTPlayground) project version:
> '0.1-baseline') load).
>
>
> On Mon, Sep 22, 2014 at 5:36 PM, Yuriy Tymchuk <yuriy.tymchuk(a)me.com>
> wrote:
>
>> So is it working for you? Because when I load it, I get emergency
>> evaluator when debugger should openâ¦
>>
>> Uko
>>
>> > On 29 Jul 2014, at 09:17, Max Leske <maxleske(a)gmail.com> wrote:
>> >
>> > Ok, thanks.
>> >
>> >
>> > On 28.07.2014, at 22:37, Stephan Eggermont <stephan(a)stack.nl> wrote:
>> >
>> >> Just fix the configuration. Nothing there for pharo 4.x
>> >> And as baseline012 refers to #development everywhere,
>> >> you'll need to check all dependencies too
>> >>
>> >> Stephan
>> >>
>> >
>> >
>>
>>
>>
>
--
www.tudorgirba.com
"Every thing has its own flow"
Sept. 22, 2014
Re: [Pharo-dev] I'm confused about Process>>isTerminated
by Eliot Miranda
On Mon, Sep 22, 2014 at 4:57 AM, Max Leske <maxleske(a)gmail.com> wrote:
> Hi Eliot,
>
> Thanks a lot for those explanations.
>
> On 18.09.2014, at 20:53, Eliot Miranda <eliot.miranda(a)gmail.com> wrote:
>
> Hi Max,
>
> phhh, time zone differences suck ;-)
>
> On Thu, Sep 18, 2014 at 3:50 AM, Max Leske <maxleske(a)gmail.com> wrote:
>
>> Hi Eliot,
>>
>> On 18.09.2014, at 01:18, Eliot Miranda <eliot.miranda(a)gmail.com> wrote:
>>
>> Hi Max,
>>
>> On Wed, Sep 17, 2014 at 1:59 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>
>>> Hi Eliot
>>>
>>>
>>> On 16.09.2014, at 20:18, Eliot Miranda <eliot.miranda(a)gmail.com> wrote:
>>>
>>> Hi Max,
>>>
>>> On Tue, Sep 16, 2014 at 11:05 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>>
>>>> Hi
>>>>
>>>> As always when I want to check if a process has died I get very
>>>> confused by #isTerminated and Iâm wondering if I just donât get how itâs
>>>> supposed to work or if there are others that share my confusion.
>>>>
>>>> Old implementation:
>>>>
>>>> isTerminated
>>>>
>>>> self isActiveProcess ifTrue: [^ false].
>>>> ^suspendedContext isNil
>>>> or: ["If the suspendedContext is the bottomContext it is the
>>>> block in Process>>newProcess.
>>>> If so, and the pc is greater than the startpc, the
>>>> bock has alrteady sent and returned
>>>> from value and there is nothing more to do."
>>>> suspendedContext isBottomContext
>>>> and: [ suspendedContext pc > suspendedContext startpc
>>>> ] ]
>>>>
>>>>
>>>> Pharo 4 implementation:
>>>>
>>>> isTerminated
>>>> self isActiveProcess ifTrue: [^ false].
>>>> ^suspendedContext isNil
>>>> or: ["If the suspendedContext is the bottomContext it is the
>>>> block in Process>>newProcess.
>>>> If so, and the pc is greater than the startpc, the
>>>> bock has alrteady sent and returned
>>>> from value and there is nothing more to do.â
>>>> suspendedContext isBottomContext
>>>> and: [ suspendedContext isDead not
>>>> â<âââââââââââââââââââââââââ new"
>>>> and: [ suspendedContext pc > suspendedContext startpc
>>>> ] ] ]
>>>>
>>>>
>>>> The old implementation would break if the suspended context was dead
>>>> (i.e. the pc was nil) because the send of #> would produce an MNU.
>>>> The new implementation doesnât fix that, even though it looks like it
>>>> at first glance: if the pc is nil, the #> send will still happen -> MNU.
>>>>
>>>
>>> Off the top of my head it would seem that it should be isDead or: [] not
>>> isDead not and:
>>>
>>> isTerminated
>>> self isActiveProcess ifTrue: [^ false].
>>> ^suspendedContext isNil
>>> or: ["If the suspendedContext is the bottomContext it is the
>>> block in Process>>newProcess.
>>> If so, and the pc is greater than the startpc, the
>>> bock has alrteady sent and returned
>>> from value and there is nothing more to do.â
>>> suspendedContext isBottomContext
>>> and: [ suspendedContext isDead
>>> or: [ suspendedContext pc > suspendedContext
>>> startpc ] ] ]
>>>
>>>
>>> Phew. Glad you see that the same way.
>>>
>>> isDead
>>>> ^ pc isNil
>>>>
>>>
>>> and maybe (suspendedContext pc ifNil: [true] ifNotNil: [:pc| pc >
>>> suspendedContext startpc]) is more obvious.
>>>
>>> Anyway, neither implementation will reliably tell me if the process has
>>>> been terminated:
>>>> - an inactive process will be suspended when #terminate is sent and
>>>> report that it has not been terminated (#isSuspended -> true, #isTerminated
>>>> -> false)
>>>>
>>>
>>> except that it *hasn't* been terminated, it is merely in the process of
>>> termination. It isn't terminated until all unwind blocks have run, right?
>>>
>>>
>>> True. Easy to forget when you can just kill -9 on the console⦠:)
>>>
>>>
>>>
>>>> - a properly terminated process will raise an MNU (although apparently
>>>> not always�)
>>>>
>>>
>>> but that's a bug the change I suggested will fix.
>>>
>>>
>>>> - all the states in between: no clue
>>>>
>>>> I would like to know two things:
>>>> 1. how can I check if a process has already *received* a #terminate? (I
>>>> would then assume that the process will die eventually)
>>>>
>>>
>>> I don't think you can without putting a critical section around
>>> terminate and adding some process-specific variable that is set when you
>>> send terminate. termination is not instantaneous (unwind blocks have to be
>>> run), so it is potentially interruptible.
>>>
>>>
>>> Iâve thought about this a bit. I wouldnât really care if I donât get a
>>> correct answer about the termination status immediately but I want to have
>>> it before the process terminates. In case of something like the following:
>>>
>>> ([ 10 seconds asDelay wait ] forkAt: 11) terminate
>>>
>>> it can (potentially) take a very long time for the process to terminate.
>>> So if I have to poll 3 or 4 times thatâs ok but I donât want to wait for
>>> minutes.
>>> One solution would be to take your idea of the variable, but without the
>>> critical block:
>>>
>>> terminate
>>> "Stop the process that the receiver represents forever. Unwind to
>>> execute pending ensure:/ifCurtailed: blocks before terminating."
>>>
>>> | ctxt unwindBlock oldList |
>>> terminating := true. â<âââââââââââââââââââââââââââââââââââ changed"
>>> self isActiveProcess
>>> ifTrue: [
>>> ctxt := thisContext.
>>> [ ctxt := ctxt findNextUnwindContextUpTo: nil.
>>> ctxt isNil ] whileFalse:
>>> [ (ctxt tempAt: 2) ifNil:
>>> [ ctxt tempAt: 2 put: nil.
>>> unwindBlock := ctxt tempAt: 1.
>>> thisContext terminateTo: ctxt.
>>> unwindBlock value ]].
>>> thisContext terminateTo: nil.
>>> self suspend ]
>>> ifFalse: [
>>> "Always suspend the process first so it doesn't accidentally get woken
>>> up"
>>> oldList := self suspend.
>>> suspendedContext ifNotNil:[
>>> "Figure out if we are terminating the process while waiting in
>>> Semaphore>>critical:
>>> In this case, pop the suspendedContext so that we leave the ensure:
>>> block inside
>>> Semaphore>>critical: without signaling the semaphore."
>>> (oldList class == Semaphore and:[
>>> suspendedContext method == (Semaphore compiledMethodAt: #critical:)])
>>> ifTrue:[
>>> suspendedContext := suspendedContext home.].
>>> "If we are terminating a process halfways through an unwind, try to
>>> complete that unwind block first."
>>> (suspendedContext findNextUnwindContextUpTo: nil) ifNotNil: [ :outer |
>>> (suspendedContext findContextSuchThat: [ :c | c closure == (outer
>>> tempAt: 1)])
>>> ifNotNil: [ :inner |
>>> "This is an unwind block currently under evaluation"
>>> suspendedContext runUntilErrorOrReturnFrom: inner ]].
>>> ctxt := self popTo: suspendedContext bottomContext.
>>> ctxt == suspendedContext bottomContext ifFalse: [
>>> self debug: ctxt title: 'Unwind error during termination']] ].
>>>
>>>
>>>
>>> isTerminating
>>> ^ terminating ifNil: [ ^ false ]
>>>
>>>
>>> With this small modification I can run the example from above and
>>> immediately see that it will die eventually.
>>>
>>> Iâm aware that one process might not see the change to the variable
>>> immediately but as I said, I wouldnât really care.
>>>
>>>
>>> What do you think?
>>>
>>
>> Yes that looks good. But given that branches are atomic (ifTrue: is not
>> a send) why not do
>>
>> Process>>initialize
>> terminating := false.
>>
>> terminate
>> "Stop the process that the receiver represents forever. Unwind to
>> execute pending ensure:/ifCurtailed: blocks before terminating."
>>
>> | ctxt unwindBlock oldList |
>> terminating
>> ifTrue: [self error: 'Process is already terminated, or being terminated']
>> ifFalse: [terminating := true].
>> self isActiveProcess
>> ifTrue:
>> ...
>>
>> ?
>>
>> I would suggest a status inst var, as in
>>
>> Process>>initialize
>> status := nil
>>
>> terminate
>> "Stop the process that the receiver represents forever. Unwind to
>> execute pending ensure:/ifCurtailed: blocks before terminating."
>>
>> | ctxt unwindBlock oldList |
>> status == #terminating
>> ifTrue: [self error: 'Process is already terminated, or being terminated']
>> ifFalse: [status := terminating].
>> self isActiveProcess
>> ifTrue:
>> ...
>>
>> but the temptation then is to have lots of different status values and
>> I'm leery of introducing that kind of complication without a strong
>> justification.
>>
>>
>>
>> Iâve worked a bit on an implementation along your suggestions. I wrote a
>> test which looks like this:
>>
>> testIsTerminated
>> | proc |
>> proc := [ Semaphore new wait ] forkAt: 30.
>> self deny: proc isSuspended.
>> self deny: proc isTerminating.
>> self deny: proc isTerminated.
>> proc terminate.
>> self deny: proc isTerminated.
>> self assert: proc isSuspended.
>> self assert: proc isTerminating.
>> [ proc isTerminated ] whileFalse: [ 1 second asDelay wait ].
>> â<âââââââââââ ???"
>>
>> self assert: proc isTerminated.
>> self assert: proc isTerminating
>>
>> The test works AFAICT (apart from the loopâ¦) but I want to also have a
>> check after the process has terminated. Is there some reliable way to wait
>> for a process to die? I tried something like this for example:
>>
>> proc run.
>> self assert: proc isTerminated.
>>
>> But that locks up the active process (obviously) until I interrupt it
>> manually. If there is such a way, I could also add a method that lets a
>> process x wait for the completion of a process y for example (or not,
>> depending on how difficult it is :) )
>>
>
> I can't see anything to do other than waiting. One thing is to run the
> process at as close to user priority as possible, so I would say
>
> proc := [ Semaphore new wait ] forkAt: Processor activePriority - 1.
>
> Another important thing is that you're not giving your process a chance to
> run before you test for it not terminating. So adding a yield after the
> first set of asserts and then repeating them is good:
>
> started := false. proc := [ started := true. Semaphore new wait ] forkAt:
> 30.
> self deny: proc isSuspended.
> self deny: proc isTerminating.
> self deny: proc isTerminated.
> (Delay forMilliseconds: 10) wait. self assert: started.
> self deny: proc isSuspended.
> self deny: proc isTerminating.
> self deny: proc isTerminated.
>
> Another thing might be to boost its priority to make sure it finishes
> (except that that'll probably have no effect because IIRC right now the
> terminator runs the termination). So you could say
>
> proc terminate.
> self deny: proc isTerminated.
> self assert: proc isSuspended.
> self assert: proc isTerminating.
>
> process priority: Processor activePriority + 1.
> [ proc isTerminated ] whileFalse: [ 1 second asDelay wait ].
>
> Further I'd want to test that unwind blocks have been run so I'd say
>
> testIsTerminated
> | proc started unwound terminator |
> unwound := false. proc := [ started := true. [Semaphore new wait]
> ensure: [terminator := Processor activeProcess.
> unwound := true] ]
> forkAt: Processor activePriority - 1.
> self deny: proc isSuspended.
> self deny: proc isTerminating.
> self deny: proc isTerminated.
> (Delay forMilliseconds: 10) wait. "Alloc proc to run; there shouldnt be
> too much else going on so this delay should suffice"
>
> self assert: started.
> self deny: proc isSuspended.
> self deny: proc isTerminating.
> self deny: proc isTerminated.
> proc terminate.
> proc priority: Processor activePriority + 1. "This may have no effect;
> termination may be executed by the terminator rather than the terminatee;
> ys, this is a bug"
> self deny: proc isTerminated.
> self assert: proc isSuspended.
> self assert: proc isTerminating.
> (Delay forMilliseconds: 10) wait. "Allow proc to terminate; there
> shouldnt be too much else going on so this delay should suffice"
>
> self assert: proc isTerminated.
> self assert: proc isTerminating.
> self assert: unwound.
> self assert: terminator == proc. "But this should be made an expected
> failure; I don't know how to do that in SUnitâ¦"
>
>
> From your comments I expected this last statement to fail but actually it
> doesnât. I guess thatâs a good sign (?).
>
Yes, that's great!
>
>
> and google's mail text editor *SUCKS*!!!!
>
>
> lol :p
>
I spent so much time editing the code in the message with the editor doing
weird things like pasting the fragment I was appending to a line to the end
of the previous line, etc. Drove me *mad* :-)
I noticed something else regarding terminated processes that have never run
> and Iâm not sure if thatâs not a bug:
> When I suspend a process (that has never run) that is not the active
> process, I can reliably reproduce that the entire #terminate method is
> being executed. The processâ suspendedContext is the bottom context (as it
> should be). However, the pc is equal to the startpc, since that process
> never had a chance to to anything. The result is that #isTerminated will
> answer false, even though the process is technically terminated.
>
Hmmm. You might want to add code to #terminated to check for that case,
and set the pc to endPC + 1, or nil. Just make sure there's a comment ;-)
> One side effect of this is that itâs impossible to do something like â[
> proc isTerminated ] whileFalse: [ 1 second asDelay wait ].â because that
> will not terminate for all processes. Luckily those processes can be
> garbage collected regardless of what #isTerminated says.
>
Right.
>
> One obvious fix would be to set the pc of the suspendedContext to nil but
> Iâm not sure thatâs a good idea.
>
> What do you think?
>
>
> Cheers,
> Max
>
> Cheers,
>> Max
>>
>> Cheers,
>>> Max
>>>
>>> 2. how can I check if a process is *actually* dead? (in case a âhalf
>>>> deadâ process will still unwind or whatever)
>>>>
>>>
>>> see above.
>>>
>>> What would be necessary to make those tests (or better ones) possible
>>>> (rewrite the whole process implementation?)?
>>>>
>>>> Cheers,
>>>> Max
>>>
>>> --
>>> best,
>>> Eliot
>>>
>>> --
>> best,
>> Eliot
>>
>> --
> best,
> Eliot
>
> --
best,
Eliot
Sept. 22, 2014
Versioneer. nice. mmMmmm...
by Ben Coman
While I had done the Versioneer tutorial some time ago, I had some
inertial problem using it in anger. Now I'm happy to report using it
just now to update the ConfigurationOfPharoLauncher was simple and
smooth - which is great since I've never done a Configuration by hand.
I thought it would be useful for others to see how simple it was...
1. Loaded latest ConfigurationOfPharoLauncher.
2. Loaded and tested newer PharoLauncher packages.
3. Opened World > Tools > Versioneer.
4. Selected PharoLauncher and <Open Project>.
5. Selected "development" list item.
6. Clicked <Release Version> and <Ok> to accept auto increment of
version number.
7. Clicked <Commit the project>
Now there is an updated ConfigurationOfPharoLauncher in its Smalltalkhub
repository.
Easy with Versioneer. mmMmmmm. nice. shiny.....
cheers -ben
Sept. 22, 2014
Re: [Pharo-dev] Penelope Re: Call for CleanUp of the issue tracker
by Damien Cassou
On Sat, Sep 20, 2014 at 12:28 PM, Ben Coman <btc(a)openinworld.com> wrote:
>
> I have two tickets open on Penelope...
> https://pharo.fogbugz.com/default.asp?11550
> https://pharo.fogbugz.com/default.asp?11551
>
> I'd be happy to give them a go myself if I had access to the code and be
> able to test it.
> cheers -ben
can anyone help Ben?
--
Damien Cassou
http://damiencassou.seasidehosting.st
"Success is the ability to go from one failure to another without
losing enthusiasm."
Winston Churchill
Sept. 22, 2014
Re: [Pharo-dev] Fixed case 11996 -- exception handler search bug
by Marcus Denker
On 22 Sep 2014, at 17:35, Ben Coman <btc(a)openInWorld.com> wrote:
> Martin McClure wrote:
>> This fix required multiple slices since loading things in the wrong order broke exceptions badly enough to hang the system. I packaged things in five slices. (It's possible that if Monticello was smart enough I could have done it in less than five, but it did need more than one).
>>
>> The automatic test runner seems to only load the first of the five slices. Therefore two exception tests fail, which is expected. All exception tests should pass after all five slices are loaded in order.
>>
>> Is there a way to tell the automatic test runner to load all five, or does this one require manual testing? (I did test it manually before dropping the slices in the inbox, but that was a month ago.)
>>
>> Regards,
>>
>> -Martin
>>
>>
> There is no built in mechanism for loading multiple slices. Now perhaps your slice can contain only a "Dummy class>>initialize" method that scripts Gopher to load the slices in order. Disclaimer, never tried it - just thinking out loud.
I think the easiest is to make sub-cases: then they will be checked with the leaf first, after it is integrated (and closed), the parent gets tested, and so on.
Marcus
Sept. 22, 2014
Re: [Pharo-dev] GToolkit in Pharo 4?
by Andrei Chis
Not all GT-Tools work in Pharo 4 (e.g. the debugger does not work).
You can load the Playground + a subset of the inspector (without roassal)
using the code below.
(You still need to manually enable them from the setting browser -> GT)
Gofer new smalltalkhubUser: 'Moose'
project: 'GToolkit';
package: 'ConfigurationOfGTPlayground';
load.
(((Smalltalk at: #ConfigurationOfGTPlayground) project version:
'0.1-baseline') load).
On Mon, Sep 22, 2014 at 5:36 PM, Yuriy Tymchuk <yuriy.tymchuk(a)me.com> wrote:
> So is it working for you? Because when I load it, I get emergency
> evaluator when debugger should openâ¦
>
> Uko
>
> > On 29 Jul 2014, at 09:17, Max Leske <maxleske(a)gmail.com> wrote:
> >
> > Ok, thanks.
> >
> >
> > On 28.07.2014, at 22:37, Stephan Eggermont <stephan(a)stack.nl> wrote:
> >
> >> Just fix the configuration. Nothing there for pharo 4.x
> >> And as baseline012 refers to #development everywhere,
> >> you'll need to check all dependencies too
> >>
> >> Stephan
> >>
> >
> >
>
>
>
Sept. 22, 2014