Xlib and multithreading

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm experimenting Xlib and thread local storage on linux 2.6, and i'm
trying to open one connection to the X server by thread, but it seems
not to work.

I try to create a window, to set inputmask to ButtonPressMask, then to
wait events in each threads. And it segfault after receiving an event.

In fact even in the same thread, i can't open multi connection to the
same X server, i receive this error, just after the opening of a first
window:
-=-
feanor@tolfalas:~/wd$ ./open-multi-display
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  2 (X_ChangeWindowAttributes)
  Resource id in failed request:  0x3800001
  Serial number of failed request:  8
  Current serial number in output stream:  9
-=-

I attach my two test programs for you to see.



@+
/* Copyright 2003 Benjamin Dauvergne <feanor@xxxxxxxxxxxxxxx> */
/* Compile: -g -L/usr/X11R6/lib -lX11 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <X11/Xlib.h>

Display *display1, *display2;
Window wid1, wid2;
int screen1, screen2;


int main(int argc, char **argv) {
    display1 = XOpenDisplay(":0");
    display2 = XOpenDisplay(":0");
    screen1 = DefaultScreen(display1);
    screen2 = DefaultScreen(display2);
    XInitThreads();

    wid1 = XCreateSimpleWindow(display1, 
      RootWindow(display1, screen1),
      0, 0, 100, 100, 0,
      BlackPixel(display1, screen1),
      WhitePixel(display1, screen1));
    wid1 = XCreateSimpleWindow(display2, 
      RootWindow(display2, screen2),
      0, 0, 100, 100, 0,
      BlackPixel(display2, screen2),
      WhitePixel(display2, screen2));

    XSelectInput(display1, wid1, ButtonPressMask);
    XSelectInput(display2, wid2, ButtonPressMask);
    XMapWindow(display1, wid1);
    XMapWindow(display2, wid2);
    while(1) {
	XEvent event;
	if (XCheckMaskEvent(display1, ButtonPressMask, &event)) {
	    printf("Click1\n");
	    continue;
	}
	if (XCheckMaskEvent(display2, ButtonPressMask, &event)) {
	    printf("Click2\n");
	    continue;
	}
	sleep(1);
    }
    return 0;
}

/* Copyright 2003 Benjamin Dauvergne <feanor@xxxxxxxxxxxxxxx> */
/* Compile: -g -L/usr/X11R6/lib/ -lX11 -lpthread */
#include <cstdio>
extern "C" {
#include <X11/Xlib.h>
#include <pthread.h>
}

using namespace std;

static __thread bool _display_class_init = false;

class display {
public:
    static __thread Display *_display;
    static __thread pthread_t _self;
    void _init() {
	_display = XOpenDisplay(NULL);
	if (! _display)
	    throw;
	_self = pthread_self();
    }
public:
    display() {
	XInitThreads();
	if (!_display_class_init)
		_init();
	_display_class_init = true;
    }
    ~display() {
	XCloseDisplay(_display);
    }
    // If we are in another thread than where display object was created
    // create a new connection to X
    operator Display*() {
	if (_self != pthread_self())
	    _init();
	return _display;
    }
    void mainLoop() {
	XEvent report;
	while(1) {
	    printf("Thread %d in event loop %p\n", _self, _display);
	    XNextEvent(display(), &report);
	}
    }
};

display context;

class window {
public:
    Window wid;
    window(int x, int y, int w, int h, bool t) {
	wid = XCreateSimpleWindow(context, RootWindow((Display*)context, DefaultScreen((Display*)context)),
	  x, y, w, h, 0, 
	  ( t ? BlackPixel((Display*)context, DefaultScreen((Display*)context)) :
	      WhitePixel((Display*)context, DefaultScreen((Display*)context))),
	  ( ! t ? BlackPixel((Display*)context, DefaultScreen((Display*)context)) :
	      WhitePixel((Display*)context, DefaultScreen((Display*)context))));
    }
    void map() {
	XMapWindow(context, wid);
    }
    void setInputMask(long event_mask) {
	XSelectInput(context, wid, event_mask);
    }
};


void *main2(void *d) {
    window w(50,50,300,300,true);
    w.map();
    w.setInputMask(ButtonPressMask);
    printf("window id %d %d %p\n", w.wid, display::_self, display::_display);
    context.mainLoop();
}

__thread Display *display::_display;
__thread pthread_t display::_self;

int main(int argc, char **argv) {
    pthread_t one_thread;
    pthread_create(&one_thread, 0, main2, NULL);
    window w(10,10,100,100,false);
    w.setInputMask(ButtonPressMask);
    printf("window id %d %d %p\n", w.wid, display::_self, display::_display);
    w.map();
    context.mainLoop();
}


[Index of Archives]     [X Forum]     [Xorg]     [XFree86 Newbie]     [IETF Announce]     [Security]     [Font Config]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux Kernel]

  Powered by Linux