Permalink
Browse files

Improved scheduling when multiple threads are fighting for the Messag…

…eManagerLock
  • Loading branch information...
hogliux committed Oct 19, 2017
1 parent 4f617f8 commit b9b34393d1cc66e2dffe1a6c6f375d5c09f5b9c7
@@ -194,16 +194,22 @@ class GenericScopedTryLock
//==============================================================================
/** Creates a GenericScopedTryLock.
As soon as it is created, this will attempt to acquire the lock, and when the
GenericScopedTryLock is deleted, the lock will be released (if the lock was
successfully acquired).
If acquireLockOnInitialisation is true then as soon as this ScopedTryLock
is created, it will attempt to acquire the lock with tryEnter.
You can retry acquiring the lock by calling retryLock.
When GenericScopedTryLock is deleted, the lock will be released (if the lock
was successfully acquired).
Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen! Best just to use it
as a local stack object, rather than creating one with the new() operator.
@see retryLock, isLocked
*/
inline explicit GenericScopedTryLock (const LockType& lock) noexcept
: lock_ (lock), lockWasSuccessful (lock.tryEnter()) {}
inline explicit GenericScopedTryLock (const LockType& lock, bool acquireLockOnInitialisation = true) noexcept
: lock_ (lock), lockWasSuccessful (acquireLockOnInitialisation && lock.tryEnter()) {}

/** Destructor.
@@ -218,10 +224,13 @@ class GenericScopedTryLock
/** Returns true if the mutex was successfully locked. */
bool isLocked() const noexcept { return lockWasSuccessful; }

/** Retry gaining the lock by calling tryEnter on the underlying lock. */
bool retryLock() const noexcept { lockWasSuccessful = lock_.tryEnter(); return lockWasSuccessful; }

private:
//==============================================================================
const LockType& lock_;
const bool lockWasSuccessful;
mutable bool lockWasSuccessful;

JUCE_DECLARE_NON_COPYABLE (GenericScopedTryLock)
};
@@ -167,6 +167,7 @@ Thread* JUCE_CALLTYPE Thread::getCurrentThread()
void Thread::signalThreadShouldExit()
{
shouldExit = true;
listeners.call (&Listener::exitSignalSent);
}

bool Thread::currentThreadShouldExit()
@@ -229,6 +230,16 @@ bool Thread::stopThread (const int timeOutMilliseconds)
return true;
}

void Thread::addListener (Listener* listener)
{
listeners.add (listener);
}

void Thread::removeListener (Listener* listener)
{
listeners.remove (listener);
}

//==============================================================================
bool Thread::setPriority (int newPriority)
{
@@ -172,6 +172,27 @@ class JUCE_API Thread
*/
bool waitForThreadToExit (int timeOutMilliseconds) const;

//==============================================================================
class Listener
{
public:
virtual ~Listener() {}

/** Called if Thread::signalThreadShouldExit was called.
@see Thread::threadShouldExit, Thread::addListener, Thread::removeListener
*/
virtual void exitSignalSent() = 0;
};

/** Add a listener to this thread which will receive a callback when
signalThreadShouldExit was called on this thread.
@see signalThreadShouldExit, removeListener
*/
void addListener (Listener*);

/** Removes a listener added with addListener. */
void removeListener (Listener*);

//==============================================================================
/** Special realtime audio thread priority
@@ -313,6 +334,7 @@ class JUCE_API Thread
uint32 affinityMask = 0;
bool deleteOnThreadEnd = false;
bool volatile shouldExit = false;
ListenerList<Listener, Array<Listener*, CriticalSection>> listeners;

#if JUCE_ANDROID
bool isAndroidRealtimeThread = false;
@@ -69,6 +69,17 @@ void ThreadPoolJob::setJobName (const String& newName)
void ThreadPoolJob::signalJobShouldExit()
{
shouldStop = true;
listeners.call (&Thread::Listener::exitSignalSent);
}

void ThreadPoolJob::addListener (Thread::Listener* listener)
{
listeners.add (listener);
}

void ThreadPoolJob::removeListener (Thread::Listener* listener)
{
listeners.remove (listener);
}

ThreadPoolJob* ThreadPoolJob::getCurrentThreadPoolJob()
@@ -113,6 +113,16 @@ class JUCE_API ThreadPoolJob
*/
void signalJobShouldExit();

/** Add a listener to this thread job which will receive a callback when
signalJobShouldExit was called on this thread job.
@see signalJobShouldExit, removeListener
*/
void addListener (Thread::Listener*);

/** Removes a listener added with addListener. */
void removeListener (Thread::Listener*);

//==============================================================================
/** If the calling thread is being invoked inside a runJob() method, this will
return the ThreadPoolJob that it belongs to.
@@ -126,6 +136,7 @@ class JUCE_API ThreadPoolJob
String jobName;
ThreadPool* pool = nullptr;
bool shouldStop = false, isActive = false, shouldBeDeleted = false;
ListenerList<Thread::Listener, Array<Thread::Listener*, CriticalSection>> listeners;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPoolJob)
};
Oops, something went wrong.

0 comments on commit b9b3439

Please sign in to comment.