[squeak-dev] Freezing UI issue

Jaromir Matas mail at jaromir.net
Sun Jul 3 13:08:42 UTC 2022


Hi Marcel,

>> Could we check if the UI process is waiting on interCycleDelay semaphore to exclude the inter cycle pause case?

> Such an explicit check would be smelly and increase maintenance cost and impair readability and information hiding and... :-)

Yes, yes, I see, a bad idea :)

> This is where I would urge you to stop and *really* think about whether we need to fix this.

Well, *need to fix this* means there's something broken; I don't know whether it's broken; it's just that I expected the example

                s := Semaphore new.
                [1/0. s signal] fork.
                s wait.

just "work" without freezing the UI :) I'm aware of the reason why it's not and starting to understand it may be pretty tricky to "fix" it :)

So in the end it's just a question of consistency of the behavior regardless whether the process is UI or not.

In the special case of #terminate I have an ugly workaround to keep the UI responsive during errors inside unwind blocks but imo #terminate shouldn't really care whether it terminates a UI or non-UI process... I'm talking about this example where you *terminate* instead of abandon the debugger after the halt:
                [self halt] ensure: [self error]

> Besides experimentation in a workspace, what kind of Morphic application would actively wait on a custom semaphore in the UI process?

No idea, frankly, but I haven't written any Morphic app yet ;)

Thanks very much for taking the time to discuss this,
Best,
Jaromir


--

Jaromír Matas

mail at jaromir.net

From: Marcel Taeumel<mailto:marcel.taeumel at hpi.de>
Sent: Sunday, July 3, 2022 13:29
To: squeak-dev<mailto:squeak-dev at lists.squeakfoundation.org>
Subject: Re: [squeak-dev] Freezing UI issue

Hi Jaromir --

> Could we check if the UI process is waiting on interCycleDelay semaphore to exclude the inter cycle pause case?

This is where I would urge you to stop and *really* think about whether we need to fix this. Such an explicit check would be smelly and increase maintenance cost and impair readability and information hiding and... :-)

Besides experimentation in a workspace, what kind of Morphic application would actively wait on a custom semaphore in the UI process? This is bad style. :-)

Yet, if Squot needs it, we might want to think about solving it somehow.

Best,
Marcel

Am 03.07.2022 13:08:16 schrieb Jaromir Matas <mail at jaromir.net>:
Hi Marcel,

thanks for taking a look at the issue :)

> What would be the reason for such a strange "semaphore wait" in the UI process

Here's my original example:

p := [ [Semaphore new wait] ensure: [1/0] ] fork.   "terminatee process -> error during unwind"
Processor yield.
p terminate.   "terminator process = UI Process"

I know you can recover it via Alt+. but it doesn't feel right imo to use such brute force for innocent examples :)

If you apply Morphic-mt.2016 the UI won't freeze but as you pointed out, it won't proceed. In the following example 'done' won't be printed:

s := Semaphore new.
[1/0. s signal] fork.
s wait.
Transcript cr; show: 'done'

I understand juggling with two UIs, one blocked or busy and another one keeping the screen responsive isn't trivial; I remember your discussion with Jakob about what seems to me now a similar situation in Squot (SquotGUI>>#waitFor) where Jakob needs to keep the UI responsive while it's waiting on a resource or something; similar situation is dealt with in InstallerSqueakMap>>#update. I tried to apply the strategy here but failed miserably :D

My question is: is the above example from Squot the same type of problem? Could it be solved similarly? Would such solution remove the need for an ad-hoc solution like in Squot? Sorry if this doesn't make much sense; I'm far from sure what I'm talking about :)

> How can we now that that #isBlocked state will not resolve itself soon? Can we?

Could we check if the UI process is waiting on interCycleDelay semaphore to exclude the inter cycle pause case?

Thanks again,
Jaromir


--

Jaromír Matas

mail at jaromir.net

From: Marcel Taeumel<mailto:marcel.taeumel at hpi.de>
Sent: Sunday, July 3, 2022 11:22
To: squeak-dev<mailto:squeak-dev at lists.squeakfoundation.org>
Subject: Re: [squeak-dev] Freezing UI issue

Hi all --

I did a small spike via Morphic-mt.2016 (Inbox).

Not sure whether this issue is actually relevant in Morphic applications. CMD+Dot will help you anyway. What would be the reason for such a strange "semaphore wait" in the UI process other than what the framework does anyway?

Best,
Marcel

Am 03.07.2022 01:13:27 schrieb Eliot Miranda <eliot.miranda at gmail.com>:




On Jul 2, 2022, at 2:13 PM, Jaromir Matas <mail at jaromir.net> wrote:

Hi Eliot, Marcel, all

> This sounds right to me.  The important things would be
- is the activeProcess (in which the exception occurs) the UI process?  If so don’t create a new UI process.
- is the UI process blocked temporarily or long-term?  I’m guessing there are delays in the UI process’s stepping/rendering so some simple test for blocking might assume the UI process was blocked while in fact it was just pausing.

Yes, I realize the UI may be in a blocked state most of the time because of the intercycle pause which is not the case we need to isolate; so yes, we need some more clever test than simple #isBlocked.

Another thing is that the blocked UI will/may eventually (when signaled) become active again so if we create a new UI to deal with a subsequent error (i.e. a request to open a debugger) then this new UI should really be just “temporary” and should be closed when the original UI becomes active again; and this is at the moment way beyond my skills; I’m not even sure this is the right approach :)

> But I really *don’t* know what I’m talking about here.  I would talk it over with Marcel; he’s much more familiar with the code and co-located.

That would be a great help indeed :))

Can I assume we can agree that it would be nice and reasonable if this motivation example opened the ZeroDivide without freezing the UI ?

s := Semaphore new.
[1/0. s signal] fork.
s wait

Yes, at least I can.  It’s a bad thing when errors in background processes don’t show up (although there is a potential issue with a flood of such events).  It’s far worse when such events cause the UI to lock up.  It would be great if the debugger clearly identified an error in a named background process (such as the finalization process) since simply closing the debugger leaves the image in a bad state.




Thanks!


--

Jaromír Matas

mail at jaromir.net

From: Eliot Miranda<mailto:eliot.miranda at gmail.com>
Sent: Saturday, July 2, 2022 19:23
To: The general-purpose Squeak developers list<mailto:squeak-dev at lists.squeakfoundation.org>
Subject: Re: [squeak-dev] Freezing UI issue

Hi Jaromir,




On Jul 1, 2022, at 2:43 AM, Jaromir Matas <mail at jaromir.net> wrote:

Hi All,

I'd like to ask you to help me understand this: If you run the following example in the Workspace, the UI will freeze (Alt + . recoverable indeed)

s := Semaphore new.
[1/0. s signal] fork.
s wait

The reason is obvious - the example runs inside the UI and hence the UI will start waiting on the semaphore s. At the same time the newly forked process will try to evaluate 1/0 and will request the UI to open a debugger but this won't happen because the UI is waiting on a semaphore.

Now the question: Why the system won't start the debugger in a new UI? There's no 'fundamental' reason why the UI should get stuck on a semaphore instead of taking care of the new error that occurred elsewhere in the meantime. Look at  #spawnNewProcessIfThisIsUI: : the method tries to make sure there's a running UI so that a new debugger can be opened in case the UI is missing or is suspended. It feels like the situation where the UI *is blocked* has been left off - and I can't figure out whether by omission or intentionally.

I've tried to modify it like this:

spawnNewProcessIfThisIsUI: suspendedProcess
                "Initialize a UI process if needed. Answer true if suspendedProcess was interrupted
                from a UI process."
                self uiProcess == suspendedProcess ifTrue: [
                                self spawnNewProcess.
                                ^true
                ].

                "Ensure that the UI process is running."
                self uiProcess
                                ifNil: [self spawnNewProcess]
                                ifNotNil: [:p | (p isSuspended or: [p isBlocked]) ifTrue: [     "<------- here's my change... or: [p isBlocked]"
                                                self restoreDisplay.
                                                self uiProcess resume]].

                ^false                    "no new process was created"

... and the example above no longer blocks the UI !

I'm not saying this is a fix (I don't have any debugger/UI experience to fix it correctly); I'm just trying to demonstrate the functionality I'd like to achieve :) A real fix should maybe open a new UI instead of unblocking the existing one, I don't know…

This sounds right to me.  The important things would be
- is the activeProcess (in which the exception occurs) the UI process?  If so don’t create a new UI process.
- is the UI process blocked temporarily or long-term?  I’m guessing there are delays in the UI process’s stepping/rendering so some simple test for blocking might assume the UI process was blocked while in fact it was just pausing.

But I really *don’t* know what I’m talking about here.  I would talk it over with Marcel; he’s much more familiar with the code and co-located.





Thanks very much for any input on this.
best,
Jaromir


--

Jaromír Matas

mail at jaromir.net






-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20220703/97d4837f/attachment.html>


More information about the Squeak-dev mailing list