Re: XSetCloseDownMode and server memory leak - Xwindows
This is a discussion on Re: XSetCloseDownMode and server memory leak - Xwindows ; In comp.windows.x, vasant
wrote
on 27 Jun 2003 10:37:15 -0700
:
> Hi,
>
> What is the the use of XSetCloseDownMode() ?.
> Seems that using this call with RetainPermanent can prevent the Xserver
> from releasing memory and ...
-
Re: XSetCloseDownMode and server memory leak
In comp.windows.x, vasant
wrote
on 27 Jun 2003 10:37:15 -0700
<70f7ebb4.0306270937.69156f10@posting.google.com>:
> Hi,
>
> What is the the use of XSetCloseDownMode() ?.
> Seems that using this call with RetainPermanent can prevent the Xserver
> from releasing memory and potentially create memory leaks.
>
> Regards
> Kanchan
The general intent apparently is to protect the application
against transient network faults. For a local connection
the call doesn't make an awful lot of sense, but if box
A is running a client which opens a window on box B, and
the network is sufficiently disrupted, under "normal"
circumstances (DestroyAll) the client on A will get a
notification message that the connection broke, and box B
will lose the window. If A hasn't otherwise set itself up,
it will exit.
This is the default behavior.
I can't speak for other behaviors as I've not used this call
personally, and the manpage is a little weird, referring to
what is probably "section 2.5" or "section 2.6" in either
the O'Reilly manuals or some specification. As far as I can
glean from the manpage, RetainTemporary allows the client
to reconnect[*] to its window, unless XKillClient kills it;
RetainPermanent allows the client to reconnect to its window,
and XKillClient apparently can do nothing about it -- which is
admittedly a little weird but might make sense on a trouble-plagued
network.
There are probably better methods by which to deal with this
sort of thing nowadays. I'll admit I for one am not aware of
any production programs using this call.
The entire error handler system appears to have slight
design problems -- in particular I'm not sure the IO Error
Handler should exit, although it might do so by default.
Of course, after an I/O error the communications socket to
the display is closed or broken anyway, rendering further
usage thereof useless -- but the application could at least
in theory attempt to open another connection. With the
current design the application may have to fork() a child,
which does the actual display connection. (I don't think
highly of this, myself -- although it would work, and
has certain other advantages, allowing attempts for error
recovery (e.g., SEGV) not otherwise available. However,
it feels overly complicated and is rather Unix-specific.)
[*] actually, the client merely has to reestablish the connection
to the server, and use the window ID (which it can either
find by querying the window tree or it might know already
if the client didn't crash but merely noticed a network
disruption).
--
#191, ewill3@earthlink.net
It's still legal to go .sigless.
-
Re: XSetCloseDownMode and server memory leak
The Ghost In The Machine wrote:
>
> In comp.windows.x, vasant wrote:
>>
>> What is the the use of XSetCloseDownMode() ?.
>> Seems that using this call with RetainPermanent can prevent the Xserver
>> from releasing memory and potentially create memory leaks.
>>
>> Regards
>> Kanchan
>
> The general intent apparently is to protect the application
> against transient network faults. For a local connection
> the call doesn't make an awful lot of sense, but if box
> A is running a client which opens a window on box B, and
> the network is sufficiently disrupted, under "normal"
> circumstances (DestroyAll) the client on A will get a
> notification message that the connection broke, and box B
> will lose the window. If A hasn't otherwise set itself up,
> it will exit.
>
> This is the default behavior.
>
> I can't speak for other behaviors as I've not used this call
> personally
The RetainPermanent mode is used mostly by programs that set some
resource, and then exit with the intent that the resource should
remain set. If they didn't set the close down mode to RetainPermanent,
then those resources would be freed.
One of the clearest examples of this is xsetroot(1X), which changes
the root image. It first releases the resources for the previous
root image, then creates a new image, and sets it as the root
background with the close down mode set to RetainPermanent. Then
when xsetroot exits, the new image remains intact.
To free an old client's resources, a later client must explicitly free
them by calling XKillClient() with a resource used by the old client.
In the case of xsetroot (and any compatible program that sets the
root image, such as xv with the -root flag), this is done by using
a window property named _XSETROOT_ID attached to the root window;
the value of the atom identifies the root image.
The following two functions free an old root image, and set a new
root image, respectively.
The RetainTemporary mode is similar to RetainPermanent, except that
to free the resources, XKillClient() is passed the special value
AllTemporary instead of the XID of an actual resource.
----------------------------------------------------------------------------
/* Forget the old background image (left-over from a previous process) */
static void forgetold(void)
{
Atom prop, type;
int format;
unsigned long length;
unsigned long dummy;
XID *valptr;
/* Look for an "_XSETROOT_ID" atom. If it doesn't exist, then there
* is no old image to forget about.
*/
prop = XInternAtom(display, "_XSETROOT_ID", True);
if (prop == None)
return;
/* Get the root window's value of that property */
if (XGetWindowProperty(display, root, prop, 0L, 1L, True,
AnyPropertyType, &type, &format, &length,
&dummy, (unsigned char **)&valptr) == Success)
{
/* If the value is a pixmap, then free its resources */
if (type==XA_PIXMAP && format==32 && length==1 && valptr)
{
XSetWindowBackground(display, root,
BlackPixel(display, screen));
XClearWindow(display, root);
XKillClient(display, *valptr);
XDeleteProperty(display, root, prop);
}
if (valptr) XFree((char *)valptr);
}
}
/* This function arranges for the background pixmap to be retained after
* "fractile" exits. It also sets the "_XSETROOT_ID" property so that some
* other process can come along later and free it.
*/
static void remembernew(Pixmap pixmap)
{
Atom prop;
/* Create an Atom to be used to label the _XSETROOT_ID property */
prop = XInternAtom(display, "_XSETROOT_ID", False);
if (!prop)
FAIL("Couldn't create _XSETROOT_ID atom");
/* Store the pixmap's ID as the property value */
XChangeProperty(display, root, prop, XA_PIXMAP, 32, PropModeReplace,
(unsigned char *)&pixmap, 1);
/* arrange for the pixmap to be retained upon exit */
XSetCloseDownMode(display, RetainPermanent);
}
-
Re: XSetCloseDownMode and server memory leak
Steve Kirkendall wrote in message news:<3efe329f@nntp0.pdx.net>...
That is a good example to show the need to preserve X resources across an exit().
However a buggy program could cause server to leak memory.
I notice that openmotif uses this call. I am not sure why.
Thanks for the info.
Regards
Kanchan
>
> The RetainPermanent mode is used mostly by programs that set some
> resource, and then exit with the intent that the resource should
> remain set. If they didn't set the close down mode to RetainPermanent,
> then those resources would be freed.
>
> One of the clearest examples of this is xsetroot(1X), which changes
> the root image. It first releases the resources for the previous
> root image, then creates a new image, and sets it as the root
> background with the close down mode set to RetainPermanent. Then
> when xsetroot exits, the new image remains intact.
>
> To free an old client's resources, a later client must explicitly free
> them by calling XKillClient() with a resource used by the old client.
> In the case of xsetroot (and any compatible program that sets the
> root image, such as xv with the -root flag), this is done by using
> a window property named _XSETROOT_ID attached to the root window;
> the value of the atom identifies the root image.
>
> The following two functions free an old root image, and set a new
> root image, respectively.
>
> The RetainTemporary mode is similar to RetainPermanent, except that
> to free the resources, XKillClient() is passed the special value
> AllTemporary instead of the XID of an actual resource.
>
> ----------------------------------------------------------------------------
> /* Forget the old background image (left-over from a previous process) */
> static void forgetold(void)
> {
> Atom prop, type;
> int format;
> unsigned long length;
> unsigned long dummy;
> XID *valptr;
>
> /* Look for an "_XSETROOT_ID" atom. If it doesn't exist, then there
> * is no old image to forget about.
> */
> prop = XInternAtom(display, "_XSETROOT_ID", True);
> if (prop == None)
> return;
>
> /* Get the root window's value of that property */
> if (XGetWindowProperty(display, root, prop, 0L, 1L, True,
> AnyPropertyType, &type, &format, &length,
> &dummy, (unsigned char **)&valptr) == Success)
> {
> /* If the value is a pixmap, then free its resources */
> if (type==XA_PIXMAP && format==32 && length==1 && valptr)
> {
> XSetWindowBackground(display, root,
> BlackPixel(display, screen));
> XClearWindow(display, root);
> XKillClient(display, *valptr);
> XDeleteProperty(display, root, prop);
> }
>
> if (valptr) XFree((char *)valptr);
> }
> }
>
> /* This function arranges for the background pixmap to be retained after
> * "fractile" exits. It also sets the "_XSETROOT_ID" property so that some
> * other process can come along later and free it.
> */
> static void remembernew(Pixmap pixmap)
> {
> Atom prop;
>
> /* Create an Atom to be used to label the _XSETROOT_ID property */
> prop = XInternAtom(display, "_XSETROOT_ID", False);
> if (!prop)
> FAIL("Couldn't create _XSETROOT_ID atom");
>
> /* Store the pixmap's ID as the property value */
> XChangeProperty(display, root, prop, XA_PIXMAP, 32, PropModeReplace,
> (unsigned char *)&pixmap, 1);
>
> /* arrange for the pixmap to be retained upon exit */
> XSetCloseDownMode(display, RetainPermanent);
> }