jcarson@MONIZ.BCM.TMC.EDU (Janet L. Carson) (03/03/90)
With regards to the the "cleaning up before exit" problem recently discussed on xpert, I would like to propose the following addition to the Xt Intrinsics: XtAddCleanUpProc(routine, client_data) XtRemoveCleanUpProc(routine, client_data) These would add or remove a routine from a list of routines to be called when the application exits. To exit an application, the programmer would call: XtExit(value) which would call all of the clean up procedures and then call exit(value). --Janet Janet L. Carson internet: jcarson@bcm.tmc.edu Baylor College of Medicine uucp: {rutgers,mailrus}!bcm!jcarson
erik@srava.sra.co.jp (Erik M. van der Poel) (03/04/90)
In article <9003022256.AA07109@moniz.bcm.tmc.edu> Janet L. Carson writes: >With regards to the the "cleaning up before exit" problem >recently discussed on xpert, I would like to propose the >following addition to the Xt Intrinsics: > >XtAddCleanUpProc(routine, client_data) >XtRemoveCleanUpProc(routine, client_data) > >These would add or remove a routine from a list of routines >to be called when the application exits. > >To exit an application, the programmer would call: > >XtExit(value) > >which would call all of the clean up procedures and then >call exit(value). I think these are good ideas, but there is a problem: this scheme would not be backward-compatible. New applications that use XtExit() would break existing widgets that expect their destroy procedures to get called in order to remove temporary files, etc. However, I *do* think that registering clean-up procs is a good idea, and should probably be possible for general purposes, but not for those things that widget destroy procs are used for. I think that the application programmer should explicitly call XtDestroyWidget() for widgets whose documentation clearly states that destruction is necessary. Then the application should call XtExit(), which tells Xt to exit when it is safe to do so, that is, after destroy phase 2. This way the app programmer does not have to set a global flag to break out of the main loop. There should probably also be an XtAppExit(), which would terminate only the given application. This would only be implemented in systems where it is possible to have multiple applications in one address space. Similarly, we need XtAppAddCleanUpProc() and XtAppRemoveCleanUpProc(). The default error handler should not call exit() directly. It should call XtExit(). Also, it would be nice if widgets would be able to express an interest in having themselves destroyed before exiting, just in case the app programmer does call XtExit() but forgets to call XtDestroyWidget(). Of course, if the app programmer calls exit() you're hosed, but the current situation is already like that anyway. Another issue is the distinction between a normal exit and a crash. A widget may want to know whether its destroy proc is being called by Xt or by the app programmer. If it is being called by Xt, it might assume that there was an error, and therefore refrain from unlinking its temporary file. The widget might also like to give the app some control over this, by having a resource like XtNremoveTempFile. As far as XtDestroyApplicationContext() is concerned, I think that it should destroy all widgets associated with the app context. Otherwise, XtWidgetToApplicationContext() would not be meaningful. Similarly, XtCloseDisplay() should destroy all associated widgets. - -- Erik M. van der Poel erik@sra.co.jp (Japan) Software Research Associates, Inc. erik%sra.co.jp@uunet.uu.net (USA) Tokyo, Japan TEL +81-3-234-2692 erik%sra.co.jp@mcsun.uucp (Europe)
jcarson@WILKINS.BCM.TMC.EDU (Janet L. Carson) (03/06/90)
[Me: Scheme for exit: XtAddCleanUpProc, XtExit, etc.] >I think these are good ideas, but there is a problem: this scheme >would not be backward-compatible. New applications that use XtExit() >would break existing widgets that expect their destroy procedures to >get called in order to remove temporary files, etc. It is backward compatible in this sense: if the application and the widget set go on doing the same things they were always doing, the same thing that happened before will continue to happen. I agree that if you only change 1/2 of the system, the other half will not change automatically, and that could present problems in a few cases. The problem that got the whole thing started was that the destroy procedure isn't always called, unless the application programmer is careful about it. If both the widget and the application are changed to clean-up procs, they won't have to be so careful in the future. >I think that the application programmer should explicitly call >XtDestroyWidget() for widgets whose documentation clearly states that >destruction is necessary. Hopefully clean up procs would reduce the number of widgets for which this is necessary. It's too much of a hassle for the programmer, and it limits the widget writer: I can't change my widget to create a temp file because all of the existing applications would have to go back and change their code to make sure it was destroyed explicitly. What I envisioned was that a widget which created a temp file would call XtAddCleanUpProc from it's Initialize routine, and XtRemoveCleanUpProc from it's Destroy routine, passing the widget pointer as the client_data. This creates an "ensured destroy" without changing the core widget structure, or bothering the 99% of widgets that don't absolutely need their destroy procedure called. >Another issue is the distinction between a normal exit and a crash. How about if the callback has the following arguments: CleanUpProc(client_data, exit_value) Where exit_value is the value passed to XtExit(). If this is non-zero, the clean-up proc. knows that the application is not exiting normally. >As far as XtDestroyApplicationContext() is concerned, I think that it >should destroy all widgets associated with the app context. Otherwise, >XtWidgetToApplicationContext() would not be meaningful. Similarly, >XtCloseDisplay() should destroy all associated widgets. Whether or not all these widgets want or need their destroy procedure called? Wouldn't this be a waste of time? The widget destroy proc was envisioned to free up Pixmaps, GCs and things from X which would not have to be freed explicitly if the connection to the X server were closing. (Otherwise, wouldn't they have called all of the destroy procs in the current Intrinsics implementation?) >Erik M. van der Poel erik@sra.co.jp (Japan) >Software Research Associates, Inc. erik%sra.co.jp@uunet.uu.net (USA) >Tokyo, Japan TEL +81-3-234-2692 erik%sra.co.jp@mcsun.uucp (Europe) --Janet Janet L. Carson internet: jcarson@bcm.tmc.edu Baylor College of Medicine uucp: {rutgers,mailrus}!bcm!jcarson
kit@EXPO.LCS.MIT.EDU (Chris D. Peterson) (03/06/90)
> With regards to the the "cleaning up before exit" problem > recently discussed on xpert, I would like to propose the > following addition to the Xt Intrinsics: > XtAddCleanUpProc(routine, client_data) > XtRemoveCleanUpProc(routine, client_data) > These would add or remove a routine from a list of routines > to be called when the application exits. > To exit an application, the programmer would call: > XtExit(value) > which would call all of the clean up procedures and then > call exit(value). This is a good idea. I will bring this before the internal Xt Consortium working group for discussion. Chris D. Peterson MIT X Consortium Net: kit@expo.lcs.mit.edu Phone: (617) 253 - 9608 Address: MIT - Room NE43-213
erik@srava.sra.co.jp (Erik M. van der Poel) (03/06/90)
> >I think that the application programmer should explicitly call > >XtDestroyWidget() for widgets whose documentation clearly states that > >destruction is necessary. > > Hopefully clean up procs would reduce the number of widgets for which > this is necessary. Even if you have clean-up procs or some other way for widgets to tell Xt that they crave destruction, the author of such a widget should probably warn app programmers that they should call XtExit() and not exit(). But, yes, I agree that it would be better for us to migrate to a situation where calling XtDestroyWidget() is unnecessary. Of course, all this wouldn't be necessary if everyone had the ANSI C atexit() (to register clean-up procs), but even then you can't protect yourself against a programmer that suddenly and gleefully calls execl(). (Well, not easily, anyway.) Or does ANSI C support that now too? Perhaps it should. > >As far as XtDestroyApplicationContext() is concerned, I think that it > >should destroy all widgets associated with the app context. Otherwise, > >XtWidgetToApplicationContext() would not be meaningful. Similarly, > >XtCloseDisplay() should destroy all associated widgets. > > Whether or not all these widgets want or need their destroy procedure > called? Wouldn't this be a waste of time? The widget destroy proc was > envisioned to free up Pixmaps, GCs and things from X which would not > have to be freed explicitly if the connection to the X server were > closing. I said that XtDestroyApplicationContext() should destroy all associated widgets. I did *not* say that apps should call XtDestroyApplicationContext(). Most apps should probably just call exit() oops I mean XtExit(). As Paul said, destroy procs are really meant for applications that wish to continue processing after destroying some widgets. Destroying the app context is analogous to destroying widgets. However, it probably is a waste of time to explicitly ask the X server to free resources when they will be freed automatically and quickly when the connection is closed. So XtCloseDisplay() should probably tell the widgets not to bother freeing server resources. > (Otherwise, wouldn't they have called all of the destroy procs in the > current Intrinsics implementation?) Even the X Consortium occasionally makes mistakes. But I hasten to add that, on the whole, they have done and are doing a great job, and that is why I am interested in the first place. - -- Erik M. van der Poel erik@sra.co.jp (Japan) Software Research Associates, Inc. erik%sra.co.jp@uunet.uu.net (USA) Tokyo, Japan TEL +81-3-234-2692 erik%sra.co.jp@mcsun.uucp (Europe)
hvr@kimba.Sun.COM (Heather Rose) (03/08/90)
In article <9003052005.AA24152@expo.lcs.mit.edu> kit@EXPO.LCS.MIT.EDU (Chris D. Peterson) writes: > >> With regards to the the "cleaning up before exit" problem >> recently discussed on xpert, I would like to propose the >> following addition to the Xt Intrinsics: > >> XtAddCleanUpProc(routine, client_data) >> XtRemoveCleanUpProc(routine, client_data) > >> These would add or remove a routine from a list of routines >> to be called when the application exits. > >> To exit an application, the programmer would call: > >> XtExit(value) > >> which would call all of the clean up procedures and then >> call exit(value). > >This is a good idea. I will bring this before the internal Xt Consortium >working group for discussion. You might want to make this a more general solution. Add the notion of interposition to the Xt intrinsics as XView does. Then you just interpose on the default clean up procedure to do application specific things. The concept of "putting this callback before this other one" in the event stream is a very powerful tool. It makes a slight change of behavior very easy to accomplish. For example, in XView if I want to add to the behavior of the default exiting procedure, I do this: ... frame = (Frame)xv_create(NULL, FRAME, NULL); notify_interpose_destroy_func(frame, my_destroy_func); ... /* This is called before the frame's destroy func (ie. I've interposed in * front of it. */ Notify_func my_destroy_func(frame, status) Frame frame; Destroy_status status; { if (status == DESTROY_PROCESS_DEATH || status == DESTROY_CLEANUP) { /* * do something for the application like save a file */ } /* Now call the frame's default destroy func. */ notify_next_destroy_func(frame, status); } If I want to change the behavior, I omit the last line: "notify_next_destroy_func(frame, status);" which passes on the destroy event to the next callback. The concept of interposition applies to any callback in the XView toolkit. It's a very clean solution...and would not break backwards compatibility since it would be additional functionality. Regards, Heather
jimf%saber@HARVARD.HARVARD.EDU (03/09/90)
|>> XtAddCleanUpProc(routine, client_data) |>> XtRemoveCleanUpProc(routine, client_data) |You might want to make this a more general solution. Add the notion of |interposition to the Xt intrinsics as XView does. He's right, interposition is a much more general solution. I suggest, however, *NOT* having an interposition call for each of the events that you want to interpose on. The SunView/XView method, which has generic event interposers, destroy interposers, and others (five or six in all, I can never remember and the manuals are junk) is overcomplex. It would have been better to have a single interposer and key off event types (which you have to do ANYWAY) instead of five or six of them. Happy hacking, jim frost saber software jimf@saber.com
hvr@kimba.Sun.COM (Heather Rose) (03/11/90)
In article <9003091424.AA26239@armory> jimf%saber@HARVARD.HARVARD.EDU writes: >|>> XtAddCleanUpProc(routine, client_data) >|>> XtRemoveCleanUpProc(routine, client_data) > >|You might want to make this a more general solution. Add the notion of >|interposition to the Xt intrinsics as XView does. > >He's right, interposition is a much more general solution. I suggest, >however, *NOT* having an interposition call for each of the events >that you want to interpose on. The SunView/XView method, which has >generic event interposers, destroy interposers, and others (five or >six in all, I can never remember and the manuals are junk) is >overcomplex. It would have been better to have a single interposer >and key off event types (which you have to do ANYWAY) instead of five >or six of them. Actually, interposition works on Notify Clients not Events. Each notify client has an event mask which specifies when it should be called. The interposer on the notify client will only be called when an event for the interposee matches it's event mask. Each callback supplied is a notify client. I agree that the API for interposition could be simplified. It's one interface leftover from SunView that has not yet been changed for XView. For example, window_create(), panel_create(), etc... have been collapsed into xv_create(). FYI: SunView System Programmer's Guide is pretty good on this subject. Also, there's a good white paper on the SunView notifier from USENIX proceedings about 3 or 4 years ago. Author, Steve Evans. Most of the issues still apply. If the manuals are junk, please let us know what the specific problems are so we can do something about it. __________________________________________________________________ Heather Rose Window Systems Group internet: hrose@sun.com Sun Microsystems, Inc. uucp: ...!sun!hrose
asente@decwrl.dec.com (Paul Asente) (03/13/90)
In article <132650@sun.Eng.Sun.COM> hvr@sun.UUCP (Heather Rose) writes: >You might want to make this a more general solution. Add the notion of >interposition to the Xt intrinsics as XView does. Then you just interpose >on the default clean up procedure to do application specific things. > >The concept of "putting this callback before this other one" in the event >stream is a very powerful tool. It makes a slight change of behavior very >easy to accomplish. It may well be a powerful tool, but it's also a horrible programmer trap. The biggest problem is that it violates all the abstraction boundaries in the system. Think about event handlers, for example. If you interpose an event handler that decides not to continue the event handling, you have to make sure you're not preempting some other event handler that some other, possibly completely independent, code module has installed. There are plenty of cases in widget sets where a widget adds an event handler to its parent, or to its children, or to some seemingly unrelated widget. Doing safe interposition requires an intimate knowledge of the implementations of all the widget implementations and of the Intrinsics. Worse, what is safe today can become disasterous tomorrow as soon as someone modifies the implementation of any component. >It's a very clean solution...and would not break backwards compatibility >since it would be additional functionality. It's a horrible hack, and adding it breaks widget implementations everywhere that count on their functions being called. -paul asente asente@decwrl.dec.com decwrl!asente
maslen@Neon.Stanford.EDU (Thomas Maslen) (03/13/90)
In article <2999@bacchus.dec.com> asente@decwrl.dec.com (Paul Asente) writes: >It may well be a powerful tool, but it's also a horrible programmer trap. Would that be "a horrible trap for programmers" or mayhap "a trap for horrible programmers"? Thomas maslen@neon.stanford.edu
marbru@auto-trol.UUCP (Martin Brunecky) (03/14/90)
In article <2999@bacchus.dec.com> asente@decwrl.dec.com (Paul Asente) writes: > ...(text deleted) ..... There are >plenty of cases in widget sets where a widget adds an event handler to its >parent, or to its children, or to some seemingly unrelated widget. > I am not quite sure, but is THIS a good practice ? XUI and Motif are full of instances where one widget munges another one, assuming intimate knowledge of it's internals, rather than documented widget methods. This, however, makes any extension to such widget set extremely difficult. Yes, it is more difficult to accomplish the required overall toolkit functionality without hacks, but I believe that our widget sets (be it XUI or Motif) must evolve - and any assumptions one widget makes about other widgets today may (and will) prevent any improvements tomorrow. -- =*= Opinions presented here are solely of my own and not those of Auto-trol =*= Martin Brunecky marbru@auto-trol.COM (303) 252-2499 {...}ncar!ico!auto-trol!marbru Auto-trol Technology Corp. 12500 North Washington St., Denver, CO 80241-2404
asente@decwrl.dec.com (Paul Asente) (03/14/90)
In article <774@auto-trol.UUCP> marbru@auto-trol.COM (Martin Brunecky) writes: >In article <2999@bacchus.dec.com> asente@decwrl.dec.com (Paul Asente) writes: >> ...(text deleted) ..... There are >>plenty of cases in widget sets where a widget adds an event handler to its >>parent, or to its children, or to some seemingly unrelated widget. >> > I am not quite sure, but is THIS a good practice ? XUI and Motif > are full of instances where one widget munges another one, assuming > intimate knowledge of it's internals, rather than documented > widget methods. This, however, makes any extension to such widget > set extremely difficult. Two good examples: - A menu widget needs to deal with the implicit server grab on button press and wants to pop down wherever the button release occurs. It does this by installing an event handler on its shell. - A gadget wants to handle events, but it has no window. It installs event handlers on its parent to deal with the events. In neither case does the widget make any assumptions about the internals of other widgets; they just use the Intrinsics event handler semantics. I agree that having a widget implementation grub around in the internals of another widget is lewd, crude, rude, and socially unacceptable, but this is another thing entirely. -paul asente asente@decwrl.dec.com decwrl!asente