Skip to content

Commit

Permalink
hack around Xlib deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
Be-ing committed Nov 28, 2018
1 parent 9fb543c commit 36a9c3d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
3 changes: 3 additions & 0 deletions build/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,10 @@ def enabled_modules(build):
'QtTest',
'QtXml',
]

if qt5:
if build.platform_is_linux:
build.env.Append(LIBS = 'Qt5X11Extras')
qt_modules.extend([
# Keep alphabetized.
'QtConcurrent',
Expand Down
37 changes: 37 additions & 0 deletions src/mixxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,41 @@
#include "preferences/dialog/dlgprefmodplug.h"
#endif

#ifdef Q_OS_LINUX
#include <QtGui/QX11Info>
#include <X11/Xlib.h>
#include <X11/Xlibint.h>
// ancient Xlibint.h that predates C++ defines macros that
// conflict with references to std::max and std:min
#undef max
#undef min
#endif

namespace {

const mixxx::Logger kLogger("MixxxMainWindow");

// hack around https://gitlab.freedesktop.org/xorg/lib/libx11/issues/25
// https://bugs.launchpad.net/mixxx/+bug/1805559
#ifdef Q_OS_LINUX
typedef Bool (*WireToErrorType)(Display*, XErrorEvent*, xError*);

const int NUM_HANDLERS = 256;
WireToErrorType __oldHandlers[NUM_HANDLERS] = {0};

Bool __xErrorHandler(Display* display, XErrorEvent* event, xError* error) {
// Call any previous handler first in case it needs to do real work.
auto code = static_cast<int>(event->error_code);
if (__oldHandlers[code] != NULL) {
__oldHandlers[code](display, event, error);
}

// Always return false so the error does not get passed to the normal
// application defined handler.
return False;
}
#endif

} // anonymous namespace

// static
Expand Down Expand Up @@ -169,6 +200,12 @@ MixxxMainWindow::~MixxxMainWindow() {
void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) {
ScopedTimer t("MixxxMainWindow::initialize");

#ifdef Q_OS_LINUX
for (auto i = 0; i < NUM_HANDLERS; ++i) {
XESetWireToError(QX11Info::display(), i, &__xErrorHandler);
}
#endif

UserSettingsPointer pConfig = m_pSettingsManager->settings();

Sandbox::initialize(QDir(pConfig->getSettingsPath()).filePath("sandbox.cfg"));
Expand Down

0 comments on commit 36a9c3d

Please sign in to comment.