[fj.windows.x] Parent Killer

yuki@flab.fujitsu.co.jp (Hiroyuki YOSHIDA) (06/01/90)

We coded a parent killer such as:

/* ARGSUSED */
static void parentKiller(w,client_data,call_data)
     Widget w;			
     caddr_t client_data;	/* UNUSED */
     caddr_t call_data;		/* UNUSED */
{
  Widget papa = XtParent(w);
  int brothers = ((CompositeWidget)papa)->composite.num_children;
  if( brothers == 0 )
      XtDestroyWidget(papa);
}

Then, attached the killer for widgets in a widgets tree using:

  XtAddCallback(w,XtNdestroyCallback,parentKiller,(caddr_t)NULL);

This successfully worked before we patched fix-10 & -11.

After fix-10/11, a server error occurs and the program exits. The
error message is:
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  4 (X_DestroyWindow)
  Minor opcode of failed request:  0
  Resource id in failed request:  0xb0039d
  Serial number of failed request:  4073
  Current serial number in output stream:  4198

The resource id (0xb0039d) designates the child's window.

We can avoid the error using work-proc technique, such as:

/* ARGSUSED */
static void parentKiller(w,client_data,call_data)
     Widget w;			
     caddr_t client_data;	/* UNUSED */
     caddr_t call_data;		/* UNUSED */
{
  Widget papa = XtParent(w);
  int brothers = ((CompositeWidget)papa)->composite.num_children;
  if( brothers == 0 )
      (void)XtAppAddWorkProc(app,XtDestroyWidget,(caddr_t)papa);
	/* Killing parent is postponed. */
}


In addition, we can avoid the error by not applying a part of fix-10:

*** /tmp/,RCSt1a03963	Thu Apr 19 19:44:53 1990
--- mit/lib/Xt/Destroy.c	Thu Apr 19 19:44:55 1990
***************
*** 155,162 ****
      Recursive(widget, Phase2Destroy);
      app->in_phase2_destroy = outerInPhase2Destroy;
  
!     /* popups destroy their own window if parent->being_destroyed */
!     if (window != NULL && (parent == NULL || !parent->core.being_destroyed))
  	XDestroyWindow(display, window);
  } /* XtPhase2Destroy */
  
--- 165,171 ----
      Recursive(widget, Phase2Destroy);
      app->in_phase2_destroy = outerInPhase2Destroy;
  
!     if (window)
  	XDestroyWindow(display, window);
  } /* XtPhase2Destroy */
  

The problem may occur when the child's window is doubly destroyed in a
very short time.

Where is the BUG? In fix-10, server program, or our usage?
--
Hiroyuki Yoshida
yuki@flab.fujitsu.co.jp
yuki%flab.fujitsu.co.jp@uunet.uu.NET