Illegal execution with a 'Close' Notifier

All except GUI problems

Illegal execution with a 'Close' Notifier

Postby Robert » Fri Apr 05, 2019 10:49 am

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
Robert
 
Posts: 128
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Illegal execution with a 'Close' Notifier

Postby Ivan Denisov » Fri Apr 05, 2019 6:53 pm

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: 255
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: Illegal execution with a 'Close' Notifier

Postby Ivan Denisov » Sat Apr 06, 2019 4:30 am

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

Re: Illegal execution with a 'Close' Notifier

Postby cfbsoftware » Sat Apr 06, 2019 5:23 am

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

Re: Illegal execution with a 'Close' Notifier

Postby Ivan Denisov » Sat Apr 06, 2019 5:57 am

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: 255
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: Illegal execution with a 'Close' Notifier

Postby Ivan Denisov » Sat Apr 06, 2019 6:36 am

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

Re: Illegal execution with a 'Close' Notifier

Postby Robert » Sat Apr 06, 2019 10:14 am

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: 128
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Illegal execution with a 'Close' Notifier

Postby Robert » Sat Apr 06, 2019 10:37 am

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


Return to BlackBox Framework

Who is online

Users browsing this forum: No registered users and 1 guest

cron