OpenShot Library | libopenshot-audio 0.2.0
juce_ReadWriteLock.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
30
32{
33 jassert (readerThreads.size() == 0);
34 jassert (numWriters == 0);
35}
36
37//==============================================================================
39{
40 while (! tryEnterRead())
41 waitEvent.wait (100);
42}
43
45{
47
48 const SpinLock::ScopedLockType sl (accessLock);
49
50 for (int i = 0; i < readerThreads.size(); ++i)
51 {
52 ThreadRecursionCount& trc = readerThreads.getReference(i);
53
54 if (trc.threadID == threadId)
55 {
56 trc.count++;
57 return true;
58 }
59 }
60
61 if (numWriters + numWaitingWriters == 0
62 || (threadId == writerThreadId && numWriters > 0))
63 {
64 ThreadRecursionCount trc = { threadId, 1 };
65 readerThreads.add (trc);
66 return true;
67 }
68
69 return false;
70}
71
73{
75 const SpinLock::ScopedLockType sl (accessLock);
76
77 for (int i = 0; i < readerThreads.size(); ++i)
78 {
79 ThreadRecursionCount& trc = readerThreads.getReference(i);
80
81 if (trc.threadID == threadId)
82 {
83 if (--(trc.count) == 0)
84 {
85 readerThreads.remove (i);
86 waitEvent.signal();
87 }
88
89 return;
90 }
91 }
92
93 jassertfalse; // unlocking a lock that wasn't locked..
94}
95
96//==============================================================================
98{
100 const SpinLock::ScopedLockType sl (accessLock);
101
102 while (! tryEnterWriteInternal (threadId))
103 {
104 ++numWaitingWriters;
105 accessLock.exit();
106 waitEvent.wait (100);
107 accessLock.enter();
108 --numWaitingWriters;
109 }
110}
111
113{
114 const SpinLock::ScopedLockType sl (accessLock);
115 return tryEnterWriteInternal (Thread::getCurrentThreadId());
116}
117
118bool ReadWriteLock::tryEnterWriteInternal (Thread::ThreadID threadId) const noexcept
119{
120 if (readerThreads.size() + numWriters == 0
121 || threadId == writerThreadId
122 || (readerThreads.size() == 1 && readerThreads.getReference(0).threadID == threadId))
123 {
124 writerThreadId = threadId;
125 ++numWriters;
126 return true;
127 }
128
129 return false;
130}
131
133{
134 const SpinLock::ScopedLockType sl (accessLock);
135
136 // check this thread actually had the lock..
137 jassert (numWriters > 0 && writerThreadId == Thread::getCurrentThreadId());
138
139 if (--numWriters == 0)
140 {
141 writerThreadId = {};
142 waitEvent.signal();
143 }
144}
145
146} // namespace juce
Holds a resizable array of primitive or copy-by-value objects.
Definition juce_Array.h:60
void ensureStorageAllocated(int minNumElements)
Increases the array's internal storage to hold a minimum number of elements.
int size() const noexcept
Returns the current number of elements in the array.
Definition juce_Array.h:219
void remove(int indexToRemove)
Removes an element from the array.
Definition juce_Array.h:724
void add(const ElementType &newElement)
Appends a new element at the end of the array.
Definition juce_Array.h:375
ElementType & getReference(int index) const noexcept
Returns a direct reference to one of the elements in the array, without checking the index passed in.
Definition juce_Array.h:271
ReadWriteLock() noexcept
Creates a ReadWriteLock object.
bool tryEnterRead() const noexcept
Tries to lock this object for reading.
void enterWrite() const noexcept
Locks this object for writing.
~ReadWriteLock() noexcept
Destructor.
void exitRead() const noexcept
Releases the read-lock.
void enterRead() const noexcept
Locks this object for reading.
void exitWrite() const noexcept
Releases the write-lock.
bool tryEnterWrite() const noexcept
Tries to lock this object for writing.
void exit() const noexcept
Releases the lock.
void enter() const noexcept
Acquires the lock.
void * ThreadID
A value type used for thread IDs.
static ThreadID JUCE_CALLTYPE getCurrentThreadId()
Returns an id that identifies the caller thread.
bool wait(int timeOutMilliseconds=-1) const noexcept
Suspends the calling thread until the event has been signalled.
void signal() const noexcept
Wakes up any threads that are currently waiting on this object.