Page 1 of 1
Illegal execution with a 'Close' Notifier
Posted: Fri Apr 05, 2019 10:49 am
by Robert
I wish to be informed when a particulat Text Window is closed, and use the following code fragments...
Code: Select all
TYPE
CloseNotifier = POINTER TO RECORD (Sequencers.Notifier)
text: TextModels.Model
END;
VAR
cNotif: CloseNotifier;
myText: TextModels.Model;
PROCEDURE (c: CloseNotifier) Notify (VAR msg: Sequencers.Message);
BEGIN
IF c.text = myText THEN myText := NIL END
END Notify;
...
v := TextViews.dir.New (myText);
Views.OpenAux (v, 'My document name');
NEW (cNotif); cNotif.text := myText;
v.Domain ().GetSequencer ()(Sequencers.Sequencer).InstallNotifier (cNotif)
If/when the Window is closed the variable
myText is set to NIL.
This works fine, but the
problem is if I unload the Module, then close the Window, I get an "illegal execution (adr = 688E98C9H)" TRAP.
This chain of events only happens during development, so is not much of a problem. However is any "illegal execution" of this type a violation of BlackBox's claim to be a
safe programming environment?
Re: Illegal execution with a 'Close' Notifier
Posted: Fri Apr 05, 2019 6:53 pm
by Ivan Denisov
Dear Robert, can you please make some draft with documentation for Sequencers module?
I need to understand it's work better. For example, can it be used to be notified if window becomes "Dirty" the same way as closed?
According your problem. I agree, that this is not OK. I think that you can prevent this by removing the notifier in CLOSE section of your module.
There are also some difficulties, that I am finding annoying. For example, repeated TRAP windows in some cases. They make impossible to save draft of module correctly sometimes.
Re: Illegal execution with a 'Close' Notifier
Posted: Sat Apr 06, 2019 4:30 am
by Ivan Denisov
Why CloseNotifier called twice?
Code: Select all
MODULE DemoSequencers;
IMPORT Log, TextModels, Sequencers, Views, TextViews;
TYPE
CloseNotifier = POINTER TO RECORD (Sequencers.Notifier) END;
VAR cNotif: CloseNotifier;
PROCEDURE (c: CloseNotifier) Notify (VAR msg: Sequencers.Message);
BEGIN
Log.String('view closed'); Log.Ln;
END Notify;
PROCEDURE Do*;
VAR v: TextViews.View;
BEGIN
v := TextViews.dir.New(TextModels.dir.New());
Views.OpenAux (v, 'My document name');
NEW (cNotif);
v.Domain().GetSequencer()(Sequencers.Sequencer).InstallNotifier(cNotif)
END Do;
CLOSE
END DemoSequencers.
^Q DemoSequencers.Do
Re: Illegal execution with a 'Close' Notifier
Posted: Sat Apr 06, 2019 5:23 am
by cfbsoftware
The call sequence for the first call to CloseNotifier is:
...
HostCmds.Close
HostCmds.CloseWindow
Sequencers.Sequencer.Notify
DemoSequencers.CloseNotifier.Notify
The call sequence for the second call to CloseNotifier is:
...
HostCmds.Close
HostCmds.CloseWindow
HostWindows.Directory.Close
HostWindows.Window.Close
Windows.Window.Close
Sequencers.Sequencer.Notify
DemoSequencers.CloseNotifier.Notify
Does that help answer your question?
Re: Illegal execution with a 'Close' Notifier
Posted: Sat Apr 06, 2019 5:57 am
by Ivan Denisov
Thank you, Chris. I see, that Notify called in two places.
Also I mentioned, that there is no way to remove notifiers... I think, that in case of problem, which Robert had mention, this is no good. Maybe we should add procedure UninstallNorifier?
Re: Illegal execution with a 'Close' Notifier
Posted: Sat Apr 06, 2019 6:36 am
by Ivan Denisov
It works. I have checked it.
Code: Select all
...
PROCEDURE (s: Sequencer) UnistallNotifier* (n: Notifier), NEW;
VAR tmp: Notifier;
BEGIN
IF s.notifiers = n THEN
s.notifiers := s.notifiers.next
ELSE
tmp := s.notifiers;
WHILE (tmp.next # NIL) & (tmp.next # n) DO
tmp := tmp.next
END;
IF tmp.next # NIL THEN
tmp.next := tmp.next.next
END
END
END UnistallNotifier;
END Sequencers.
That is safe module. It can be unloaded without such troubles.
Code: Select all
MODULE DemoSequencers;
IMPORT Log, TextModels, Sequencers, Views, TextViews;
TYPE
CloseNotifier = POINTER TO RECORD (Sequencers.Notifier) END;
VAR
cNotif: CloseNotifier;
v: TextViews.View;
PROCEDURE (c: CloseNotifier) Notify (VAR msg: Sequencers.Message);
BEGIN
Log.String('view closed'); Log.Ln;
END Notify;
PROCEDURE Do*;
BEGIN
v := TextViews.dir.New(TextModels.dir.New());
Views.OpenView(v);
NEW (cNotif);
v.Domain().GetSequencer()(Sequencers.Sequencer).InstallNotifier(cNotif)
END Do;
PROCEDURE Unload*;
BEGIN
IF v # NIL THEN
v.Domain().GetSequencer()(Sequencers.Sequencer).UnistallNotifier(cNotif)
END
END Unload;
CLOSE
Unload
END DemoSequencers.
Re: Illegal execution with a 'Close' Notifier
Posted: Sat Apr 06, 2019 10:14 am
by Robert
Ivan Denisov wrote:According your problem. I agree, that this is not OK. I think that you can prevent this by removing the notifier in CLOSE section of your module.
I decided that this was a real problem for me; I couldn't close the Window without closing BlackBox. To avoid it I now close the Window in the CLOSE section of my module. I already had a routine to do that (in LibMisc):
Code: Select all
PROCEDURE CloseModelWindows* (model : Models.Model; askIfDirty : BOOLEAN) : INTEGER;
VAR
w, w2 : Windows.Window;
wTitle : Views.Title;
res, cnt : INTEGER;
ask : BOOLEAN;
BEGIN
cnt := 0;
IF model # NIL THEN
w := Windows.dir.First (); ask := TRUE;
WHILE w # NIL DO
w2 := w; w := Windows.dir.Next (w);
IF w2.doc.ThisView ().ThisModel () = model THEN
IF w2.seq.Dirty () THEN
IF askIfDirty THEN
IF ask THEN
w2.GetTitle (wTitle); ask := FALSE;
Dialog.GetOK ('Close Dirty model in window ^0 ?', wTitle, '', '',
{Dialog.yes, Dialog.no, Dialog.cancel}, res)
END
ELSE
res := Dialog.yes
END;
IF res = Dialog.yes THEN w2.Close; INC (cnt)
ELSIF res = Dialog.cancel THEN w := NIL END
ELSE
w2.Close
END
END
END
END;
RETURN cnt
END CloseModelWindows
I agree that a new procedure
UninstallNotifier would be a useful addition.
But my point is not about how to deliberately avoid this trap, but if avoiding it should be automatic (somehow) so that it is impossible to get this Illegal execution.
There is some documentation about Notifiers in
https://wiki.blackboxframework.org/inde ... Sequencers.
Re: Illegal execution with a 'Close' Notifier
Posted: Sat Apr 06, 2019 10:37 am
by Robert
Ivan Denisov wrote:Dear Robert, can you please make some draft with documentation for Sequencers module?
I need to understand it's work better. For example, can it be used to be notified if window becomes "Dirty" the same way as closed?
I don't know how to be notified when a window becomes
Dirty, but agree that it could be a useful feature.