Add remaining files
[juce-lv2.git] / juce / source / src / threads / juce_ReadWriteLock.cpp
blobcc253984357143f668809b9c867fccbf74c92596
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../core/juce_StandardHeader.h"
28 BEGIN_JUCE_NAMESPACE
30 #include "juce_ReadWriteLock.h"
31 #include "juce_Thread.h"
34 //==============================================================================
35 ReadWriteLock::ReadWriteLock() noexcept
36 : numWaitingWriters (0),
37 numWriters (0),
38 writerThreadId (0)
42 ReadWriteLock::~ReadWriteLock() noexcept
44 jassert (readerThreads.size() == 0);
45 jassert (numWriters == 0);
48 //==============================================================================
49 void ReadWriteLock::enterRead() const noexcept
51 const Thread::ThreadID threadId = Thread::getCurrentThreadId();
52 const SpinLock::ScopedLockType sl (accessLock);
54 for (;;)
56 jassert (readerThreads.size() % 2 == 0);
58 int i;
59 for (i = 0; i < readerThreads.size(); i += 2)
60 if (readerThreads.getUnchecked(i) == threadId)
61 break;
63 if (i < readerThreads.size()
64 || numWriters + numWaitingWriters == 0
65 || (threadId == writerThreadId && numWriters > 0))
67 if (i < readerThreads.size())
69 readerThreads.set (i + 1, (Thread::ThreadID) (1 + (pointer_sized_int) readerThreads.getUnchecked (i + 1)));
71 else
73 readerThreads.add (threadId);
74 readerThreads.add ((Thread::ThreadID) 1);
77 return;
80 const SpinLock::ScopedUnlockType ul (accessLock);
81 waitEvent.wait (100);
85 void ReadWriteLock::exitRead() const noexcept
87 const Thread::ThreadID threadId = Thread::getCurrentThreadId();
88 const SpinLock::ScopedLockType sl (accessLock);
90 for (int i = 0; i < readerThreads.size(); i += 2)
92 if (readerThreads.getUnchecked(i) == threadId)
94 const pointer_sized_int newCount = ((pointer_sized_int) readerThreads.getUnchecked (i + 1)) - 1;
96 if (newCount == 0)
98 readerThreads.removeRange (i, 2);
99 waitEvent.signal();
101 else
103 readerThreads.set (i + 1, (Thread::ThreadID) newCount);
106 return;
110 jassertfalse; // unlocking a lock that wasn't locked..
113 //==============================================================================
114 void ReadWriteLock::enterWrite() const noexcept
116 const Thread::ThreadID threadId = Thread::getCurrentThreadId();
117 const SpinLock::ScopedLockType sl (accessLock);
119 for (;;)
121 if (readerThreads.size() + numWriters == 0
122 || threadId == writerThreadId
123 || (readerThreads.size() == 2
124 && readerThreads.getUnchecked(0) == threadId))
126 writerThreadId = threadId;
127 ++numWriters;
128 break;
131 ++numWaitingWriters;
132 accessLock.exit();
133 waitEvent.wait (100);
134 accessLock.enter();
135 --numWaitingWriters;
139 bool ReadWriteLock::tryEnterWrite() const noexcept
141 const Thread::ThreadID threadId = Thread::getCurrentThreadId();
142 const SpinLock::ScopedLockType sl (accessLock);
144 if (readerThreads.size() + numWriters == 0
145 || threadId == writerThreadId
146 || (readerThreads.size() == 2
147 && readerThreads.getUnchecked(0) == threadId))
149 writerThreadId = threadId;
150 ++numWriters;
151 return true;
154 return false;
157 void ReadWriteLock::exitWrite() const noexcept
159 const SpinLock::ScopedLockType sl (accessLock);
161 // check this thread actually had the lock..
162 jassert (numWriters > 0 && writerThreadId == Thread::getCurrentThreadId());
164 if (--numWriters == 0)
166 writerThreadId = 0;
167 waitEvent.signal();
171 END_JUCE_NAMESPACE