Another Linux bug


#1

In the JUCE Demo, in the Thread Demo, there are these little balls flying around. When I stop moving the mouse over the JUCE window, after a few seconds the balls stop moving, like the whole thing is not being repainted. When I move the mouse again, they continue moving, but not from the same position anymore, so they moved in background, but where not repainted.


#2

right, I’ll check that one out…


#3

it’s also the same in the OpenGL demo. 2 seconds after not moving the mouse, the 3d cube stops turning.


#4

I just made a bet with myself that this is again your Thread-based Timer Code not working, exactly as on OS X, when plugins freezed. There really might be a flaw in it when CPU usage goes up.


#5

Hi,

Any updates on this?

I’m having the exact same bug.

I also did some printf debugging and realized my 30ms timer is running as a 3s timer or so.

But if I move the mouse around, my timerCallback gets called much more often.

There must be a lock somewhere which gets released on X events or something.


#6

Okay, well, I fixed this problem. It works for me, my timer+repaint() based animations are now smooth on X :slight_smile:

By debugging I realized that the X client messages sent by juce_postMessageToSystemQueue() in juce_linux_Messaging.cpp were very slowly received by juce_dispatchNextMessageOnSystemQueue().

I got a lot of timeouts in InternalTimerThread::run(), unless I moved the mouse on the window, as previously said.

Googl’ing about x client messages, I found that the same X display handle shouldn’t be used in different threads.

So, to fix this, I reopen the display in juce_postMessageToSystemQueue():

Index: build/linux/platform_specific_code/juce_linux_Messaging.cpp

— build/linux/platform_specific_code/juce_linux_Messaging.cpp (revision 690)
+++ build/linux/platform_specific_code/juce_linux_Messaging.cpp (working copy)
@@ -61,6 +61,7 @@
static Atom specialId;
static Atom broadcastId;
static Atom specialCallbackId;
+static String _displayName;

// This is referenced from WindowDriver.cpp
XContext improbableNumber;
@@ -198,11 +199,11 @@
sigaction (SIGSYS, &saction, NULL);
#endif

  • String displayName (getenv (“DISPLAY”));
  • if (displayName.isEmpty())
  •    displayName = T(":0.0");
    
  • _displayName = getenv (“DISPLAY”);
  • if (_displayName.isEmpty())
  •    _displayName = T(":0.0");
    
  • display = XOpenDisplay (displayName);
  • display = XOpenDisplay (_displayName);

    if (display == 0)
    {
    @@ -264,6 +265,9 @@
    if (errorCondition)
    return false;

  • // Need to reopen display, because the display handle doesn’t play well

  • // across threads:

  • Display * display = XOpenDisplay (_displayName);
    XClientMessageEvent clientMsg;
    clientMsg.display = display;
    clientMsg.window = juce_messageWindowHandle;
    @@ -282,6 +286,8 @@

    XFlush (display); // This is necessary to ensure the event is delivered

  • XCloseDisplay (display);

  • return true;
    }


#7

Good bug-spotting there, but it seems a bit inefficient to keep reopening it - perhaps a thread-local variable might be the best way to access it, then it’d only need to be opened once per thread?


#8

Agreed, I thought about this, but didn’t have enough time for it. Anyway the main idea is in my small patch.


#9

i’m getting the same problem here. if i don’t move the mouse over my juce window for some seconds, the apps starts “thinking” and i get a wait cursor.

anyway your patch doesn’t work here. i get:


#10

In my case, the wait cursor only appeared with Juce release 1.46. Using svn r690, the animations were blocking too, but there was no wait cursor.

So I suspect you are using Juce 1.46. My patch is for Juce svn r690, not for 1.46. Here’s a clean version for download:
http://www.samalyse.com/code/misc/patches/juce-r690-xeventfix.diff


#11

oh yeah sorry, it happens with a project i’m actually doing that had an old version of the amalgamated version of juce i forgot to update.

i’ll apply the patches again and see what happens.


#12

This is also related to my OpenGL context threading shenanigans, and probably some problems I encounter when debugging and using printf on Linux.

For the OpenGL, I make a display connection and use that. I didn’t realize other, non graphics stuff was using the display connection, but I guess the messaging is? That’s interesting.

So, should every Linux thread actually have an X connection?

Bruce