Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uwm.edu!bionet!agate!color.ced.berkeley.edu!spanki From: spanki@color.ced.berkeley.edu (Frank Goodman) Newsgroups: comp.windows.x Subject: R4 Athena Widget question. Keywords: DestroyCallback, Memeory Leaks, Quit, Athena Widgets Message-ID: <1990Feb24.002324.14813@agate.berkeley.edu> Date: 24 Feb 90 00:23:24 GMT Sender: usenet@agate.berkeley.edu (USENET Administrator;;;;ZU44) Reply-To: spanki@color.ced.berkeley.edu (Frank Goodman) Organization: UC Berkeley Center of Environmental Design Research Lines: 91 I've got a few questions about the quit functions of core clients in the R4 distribution. I'm writing an application that uses one of my own widgets under X11 R4 Athena. For a while, I was following the examples of the source code in $TOP/clients. Most of these clients exit via a function that looks similar to this. Exit(w, call, client) Widget w; caddr_t call, client; { XtDestroyApplicationContext(app_con); exit(0); } Now, from my own trauma with my application I have found that this will NOT call ANY of the widget's destroyCallback procedures. I now understand why (thanks to Paul Asente: asente@decwrl.dec.com). Now, many of the athena widgets do indeed have destroy callbacks, so it would seem that any application that exits in the above fashion is "doing the wrong thing". Would you (Consortium Staff), say this is true? The reason I bring this up, is basically for clarification for myself, and others. The documentation covers XtDestroyWidget, and XtDestroyApplicationContext, but it doesn't address this phenomenom at all. If a widget writer puts a destroycallback into their widget, there is assumed to be a good reason for this. Now, In my eyes an application writer should not have to look through the widget code to see if the destroy callback is "worth calling" or not. In my case, it was imperative that my destroyCallback got called, beacuse it has to remove a 30MB tmp file. The hack I'm using (again, thanks to Paul Asente) is as follows: void Exit() { xtUnmapWidget(top); XtDestroyWidget(top); /* global flag */ exitFlag = True; } MainLoop() { while (1) { /* dpy, and app_con are global */ XEvent event; XtAppNextEvent(app_con, &event); XtDispatchEvent(&event); if (exitFlag) { XFlush(dpy); break; } } XtDestroyApplicationContext(app_con); exit(0); } In this way, by the time the flag is set, all the events (XtCallCallbacks) are already on the que, so XFlush, moves 'm on through, then we exit. I'm wondering what the deal is? Why did the Consortium Staff neglect this aspect of exiting? It is well documented, that XtDestoryWidget is a two pass operation, it's equally well ignored by the applciations in the distribution. What gives? Furthermore, I'm even more curious if this is the cause of the notorious "Memory Leaks". In other words, I'm curious if every application that uses widgets, and exits without waiting for these callbacks are leaving stuff in the server and therefore it would seem to continually grow? Also, Since every application that uses widgets has a toplevelshell, could there perhaps be some sort of event dispatched when that shell is finally detroyed? Maybe you could then pass the toplevelwidget to a new XtAppMainLoop, and it would exit appropriately when the shell is dead? I would be really interested to hear what people think about this. My hope is that someone can give me an explanation for these inconsistencies or, explain to me (nicely please) why I don't know what I'm talking about. Thanks Frank. --------------------------------------------------------------------------- Frank Goodman arpa: spanki@CED.Berkeley.EDU University of California, Berkeley or: spanki%CED@jade.Berkeley.EDU College of Environmental Design uucp: ...hplabs!ucbvax!ced!spanki S.I.S Research Laboratory phone: Novelty item, not necessary ---------------------------------------------------------------------------