Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

On "Assertion `((int) ((xcb_req) - (dpy->request)) >= 0)' failed"

3 views
Skip to first unread message

maxlo

unread,
Aug 13, 2008, 11:48:45 AM8/13/08
to
Hello

I need to redisplay very quickly an XmLabel, in order to show the user
that the program is working.
I have read several ideas here, and tried a bunch of different
approaches.

Finally, I came up with this code (which is executed by a different
thread):

// -------------------------- begin thread code
------------------------------------ //
void* tProgressLabel (void* data)
{
#define USLEEP_TIME 40000

/* myProgressLabel was created with XmCreateLabel() */
Widget myProgressLabel = (Widget) data;
const int nr_strings = 4;
int i = 0;
static const char* vals[nr_strings] = {"|", "/", "-", "\\"};

XmString s[nr_strings];
for (i = 0; i < nr_strings; i++){
s[i] = XmStringCreateSimple((char*)vals[i]);
}

while(true){
i = i%nr_strings;
XtAppPending(app); // app is the XtAppContext
usleep(USLEEP_TIME);
XtVaSetValues(myProgressLabel, XmNlabelString, s[i++], NULL);
usleep(USLEEP_TIME);
}
return NULL;
#undef USLEEP_TIME
}
// -------------------------- end thread code
------------------------------------ //

The idea is to show the 4 characters ("|", "/", "-", "\") one after
the other, in a similar fashion of some command line applications.

However, I am facing the following assertion failure when moving or
resizing the window (and the thread is re-drawing the XmLabel):
../../src/xcb_lock.c:77: _XGetXCBBuffer: Assertion `((int) ((xcb_req)
- (dpy->request)) >= 0)' failed.

If I launch my application and do *not* resize or move the window,
then is no problem at all. If I move or resize the window while the
program is working, then *sometimes* the assertion fails and the
program is terminated (for instance, USLEEP_TIME=100 causes the
program to abort even without moving the window!!)

I have also seen that reducing the value of USLEEP_TIME increases the
chance of assertion failure. If I don't launch the thread that redraws
the label, then there is not problem at all, i.e., the assertion never
fails.

So, I am kind of confused here... which could be the problem? Is this
a bug in the Motif implementation that I use? (openmotif 2.2.3). More
important yet: is there a better way to change the text of an XmLabel
in a stable way? or... can I tell Motif to ignore that particular
assertion?

Please note that:
* I am new to Motif programming
* Following suggestions found in the web, I have tried using
XmDrawnButton instead of XmLabel with similar results. I have also
tried with XmScale, similar results
* Besides the assertion failure, sometimes I get a "double free or
corruption" error in libXt.so.

Any hint will be very much appreciated!
maxi

Bill

unread,
Aug 13, 2008, 7:22:36 PM8/13/08
to
This may not be useful, but I hit a very similar bug in a
multithreaded
Motif program, and tracked it down to (or at least convinced myself
I had tracked it down to) XmUpdateDisplay -- you can't call this
in more than one thread. I believe that the real bug is in libxcb,
or some such library, and a fix is beginning to percolate through
the distributions.

maxlo

unread,
Aug 14, 2008, 4:26:58 AM8/14/08
to

I see, thanks for the info.

Does someone knows if there is a nice way to provide the user some
indication that the program is doing something? A progress bar or
similar...

Thanks.

Fred

unread,
Aug 14, 2008, 10:44:38 AM8/14/08
to


XmtWorkingBox, from O'Reilly Volume 6C

All GUI calls (X, Xt, Motif) must be made in a single thread.
There are several approaches for this kind of thing.

One way is to perform your long task in a separate thread; then
in the GUI thread you just register an XtTimer that is called
every n milliseconds; that timer proc changes the label. When
the other thread is done, it sets a flag that the timer proc
can check to kn ow when to quit showing the progress bar.

If your time-consuming task can be broken down into short
loops that take less than around500 milliseconds each pass,
you can do it all in a single thread, using a timeout proc instead
of a timer.
--
Fred Kleinschmidt

0 new messages