Illegal execution with a 'Close' Notifier

All except GUI problems
Post Reply
User avatar
Robert
Posts: 177
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Illegal execution with a 'Close' Notifier

Post 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?
User avatar
Ivan Denisov
Posts: 362
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: Illegal execution with a 'Close' Notifier

Post 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.
User avatar
Ivan Denisov
Posts: 362
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: Illegal execution with a 'Close' Notifier

Post 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
cfbsoftware
Posts: 55
Joined: Wed Sep 18, 2013 10:06 pm
Contact:

Re: Illegal execution with a 'Close' Notifier

Post 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?
User avatar
Ivan Denisov
Posts: 362
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: Illegal execution with a 'Close' Notifier

Post 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?
Attachments
notify.png
User avatar
Ivan Denisov
Posts: 362
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: Illegal execution with a 'Close' Notifier

Post 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.
User avatar
Robert
Posts: 177
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Illegal execution with a 'Close' Notifier

Post 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.
User avatar
Robert
Posts: 177
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Illegal execution with a 'Close' Notifier

Post 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.
Post Reply