MessageMangerLock & ChangeBroadcast & Graphic Thread


#1

Hello,

I’m facing a problem in managing a continuous thread in a sequencer with graphical events,

as anybody know, this is more than dangerous to modify graphic comps from your own made continuous thread…

So, i’m watching all my code to patch antwhere i had badly developped, calling some repaint() or setBounds() in my thread…

Then, I made my concerned components BOTH change listeners and broadcasters for themselves.
For instance :
My thread tells A to become blue, A do that :

A::wantsToBeBlue = true ; sendSynchronousChangeMessage(A);

then :[code]
A::changeListenerCallback(…) {

A::setColour(blue);
}[/code]

Is using that is a working way to make graphics unattached from my thread ?..

I read the Jules’ doc about the “const mmLock” but I’m not actually convinced…

Thanks for help

Asr


#2

You can try using WaitableEvent class, wait () for stopping the thread, after which you can perform the UI events. After that call signal ( ) to start the thread.


#3

Thank you,
however the thread i mention is not derivated from Juce…


#4

Is that ok for my case ?[quote]MessageManagerLock Class Reference
List of all members.
Detailed Description
Used to make sure that the calling thread has exclusive access to the message loop.

Because it’s not thread-safe to call any of the Component or other UI classes from threads other than the message thread, one of these objects can be used to lock the message loop and allow this to be done. The message thread will be suspended for the lifetime of the MessageManagerLock object, so create one on the stack like this:

[code] void MyThread::run()
{
someData = 1234;

    const MessageManagerLock mmLock;
    // the event loop will now be locked so it's safe to make a few calls..

    myComponent->setBounds (newBounds);
    myComponent->repaint();

    // ..the event loop will now be unlocked as the MessageManagerLock goes out of scope
}[/code]

Obviously be careful not to create one of these and leave it lying around, or your app will grind to a halt!

Another caveat is that using this in conjunction with other CriticalSections can create lots of interesting ways of producing a deadlock! In particular, if your message thread calls stopThread() for a thread that uses these locks, you’ll get an (occasional) deadlock…

[/quote]
Thanks
asr


#5

I tested the “mmLock” thing, but it crashes when used in a ::timerCallback ?

Why ?

Thanks
AsR


#6

A mmlock isn’t needed in a timercallback, although it’s perfectly safe to use one there. If it’s crashing, it must be because you’re doing something with your own threads that’s messing it up.


#7

I thought it was illegal to call repaint() in a Thread other than the main (MessageManager) Thread?

Is it indeed legal, as long as you do lock the MessageManager?


#8

It is legal inside an mmlock - there could theoretically be problems if the OS doesn’t like its repaint functions being called on other threads, but I’ve never seen a problem like that.


#9

zamrate : the mmLock thing exists to be allowed to call repaint() even in the Main thread actually.


#10


#11

Many jassert are raised when I use simply mmLock as in the doc example :

[quote]
JUCE Assertion failure in /Developer/Library/Juce/build/macosx/…/…/src/juce_appframework/gui/components/juce_Component.cpp, line 221
JUCE Assertion failure in /Developer/Library/Juce/build/macosx/…/…/src/juce_appframework/gui/components/juce_Component.cpp, line 1641[/quote]

Someone knows why ?

i tried to delete the mmLock manually after using, but nothing changed.

Thanks,
asr


#12

If you read the assertion’s comment, you’ll see that it’s failing because it’s not locked. So you can’t have actually used an mmlock correctly. The fact that you mention deleting a lock indicates that you’re probably doing something silly, because the locks should be used as local stack objects, not heap objects.


#13

Is locker hierarchy acceptable ?

I mean, do i need to re-lock in method B() :

[code]void A() {

const MessageManagerLock mmLock;
if(!mmLock.lockWasGained()) return,

component->repaint();

B();
}[/code]


#14

Almost… loadWasGained is only meaningful if you’ve passed a thread into the constructor.


#15

So I did.

Well… Useless to make things complicate for nothing. It works 90% of times with following the Juce doc.

But rare times I get his awful things. I dont think any help is providable about it, but if ever…
It is in an Mac10.5 XCode project :