Search code examples
multithreadingx11xlib

Xlib fails (Segmentation fault) even with each connection per thread


So far as I know about X11 with Xlib, is that with multi threading a programmer has 2 choices

  1. call early enough XInitThreads
  2. or use new connection (XOpenDisplay) per thread.

Suppose i don't like first the first method with XInitThreads() call. Why does second fail?

#include <X11/Xlib.h>
#include <thread>


void startBasicWin() {
    Display *display;

    if ( (display=XOpenDisplay(NULL)) == NULL )
    {
        fprintf( stderr, "cannot connect to X server\n");
        exit( -1 );
    }
    XCloseDisplay(display);
}

int main() {
    std::thread t3 = std::thread(startBasicWin);
    std::thread t4 = std::thread(startBasicWin);
    std::thread t5 = std::thread(startBasicWin);
    std::thread t6 = std::thread(startBasicWin);
    std::thread t7 = std::thread(startBasicWin);
    std::thread t8 = std::thread(startBasicWin);
    std::thread t9 = std::thread(startBasicWin);
    t3.join();
    t4.join();
    t5.join();
    t6.join();
    t7.join();
    t8.join();
    t9.join();
}

compiled with g++ -o xlib_multi xlib_multi.cpp -lX11 -std=c++11 -pthread -g

sometimes produces output:

Segmentation fault

or

No protocol specified
cannot connect to X server :0

Can it be, that I can't use XOpenDisplay() without thread-synchronization? But once the X11 connections are created with Xlib, I could use Xlib in multi-threaded environment without any problems? Is such assumption correct?

Or is Xlib just buggy for multi-threading anyway?


Solution

  • Chances are that XOpenDisplay() uses some global variable internally that is not thread-safe or shares data between the displays. I don't think it's wise to call XOpenDisplay like that from within a thread; I suggest opening the displays sequentially first, then start the threads with a Display pointer. Or protect the code section around XOpenDisplay (and XCloseDisplay!) with a mutex.

    Either way, the fact that there is a separate XInitThreads() call makes your assumption that everything will be fine "after" XOpenDisplay() very dangerous.