[PATCH] Cannot wait for user lock in sync_while_locked
Keith Packard
keithp at keithp.com
Sat Mar 3 23:44:27 PST 2012
<#part sign=pgpmime>
On Sat, 3 Mar 2012 02:08:03 -0800, Keith Packard <keithp at keithp.com> wrote:
> sync_while_locked grabs the user lock before performing the sync
> operation. Telling InternalLockDisplay to wait for the user lock will
> thus deadlock, so don't do that.
I've managed to create a short test case for this problem. It uses
two threads, one allocating IDs and the other calling XPending. Both
threads run as fast as possible, each checking to make sure the other
one is still running and aborting when one gets stuck. After a few
seconds of run time, the thread calling XPending gets stuck.
/*
* Test Xlib sync_while_locked bug
*
*
* Compile with:
cc -o lockcheck -g lockcheck.c `pkg-config --cflags --libs x11` -lpthread
*/
#include <pthread.h>
#include <X11/Xlib.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
Display *dpy;
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
time_t pending_time;
time_t alloc_time;
void
check(void)
{
time_t now = time(NULL);
pthread_mutex_lock(&fastmutex);
if ((long) (now - pending_time) > 10) {
printf ("pending thread stuck\n");
abort();
}
if ((long) (now - alloc_time) > 10) {
printf ("alloc thread stuck\n");
abort();
}
pthread_mutex_unlock(&fastmutex);
}
static void *
run_pending (void *closure)
{
int i;
for (;;) {
pending_time = time(NULL);
XPending(dpy);
check();
}
}
static void *
run_alloc (void *closure)
{
for (;;) {
alloc_time = time(NULL);
XFreeGC(dpy, XCreateGC(dpy, RootWindow(dpy, 0), 0, NULL));
check();
}
}
main ()
{
pthread_t other_thread;
XInitThreads();
dpy = XOpenDisplay(NULL);
pthread_create (&other_thread, 0, run_pending, 0);
run_alloc(0);
}
--
keith.packard at intel.com
More information about the xorg-devel
mailing list