mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-27 02:20:05 +00:00
Fix for threading bug in GlyphCache.
This commit is contained in:
parent
2f91b1c5f4
commit
2dbd55db3e
3 changed files with 30 additions and 33 deletions
|
|
@ -105,18 +105,8 @@ void ReadWriteLock::enterWrite() const noexcept
|
|||
const Thread::ThreadID threadId = Thread::getCurrentThreadId();
|
||||
const SpinLock::ScopedLockType sl (accessLock);
|
||||
|
||||
for (;;)
|
||||
while (! tryEnterWriteInternal (threadId))
|
||||
{
|
||||
if (readerThreads.size() + numWriters == 0
|
||||
|| threadId == writerThreadId
|
||||
|| (readerThreads.size() == 1
|
||||
&& readerThreads.getReference(0).threadID == threadId))
|
||||
{
|
||||
writerThreadId = threadId;
|
||||
++numWriters;
|
||||
break;
|
||||
}
|
||||
|
||||
++numWaitingWriters;
|
||||
accessLock.exit();
|
||||
waitEvent.wait (100);
|
||||
|
|
@ -127,13 +117,15 @@ void ReadWriteLock::enterWrite() const noexcept
|
|||
|
||||
bool ReadWriteLock::tryEnterWrite() const noexcept
|
||||
{
|
||||
const Thread::ThreadID threadId = Thread::getCurrentThreadId();
|
||||
const SpinLock::ScopedLockType sl (accessLock);
|
||||
return tryEnterWriteInternal (Thread::getCurrentThreadId());
|
||||
}
|
||||
|
||||
bool ReadWriteLock::tryEnterWriteInternal (Thread::ThreadID threadId) const noexcept
|
||||
{
|
||||
if (readerThreads.size() + numWriters == 0
|
||||
|| threadId == writerThreadId
|
||||
|| (readerThreads.size() == 1
|
||||
&& readerThreads.getReference(0).threadID == threadId))
|
||||
|| (readerThreads.size() == 1 && readerThreads.getReference(0).threadID == threadId))
|
||||
{
|
||||
writerThreadId = threadId;
|
||||
++numWriters;
|
||||
|
|
|
|||
|
|
@ -143,6 +143,8 @@ private:
|
|||
|
||||
mutable Array <ThreadRecursionCount> readerThreads;
|
||||
|
||||
bool tryEnterWriteInternal (Thread::ThreadID) const noexcept;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (ReadWriteLock)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -164,30 +164,16 @@ public:
|
|||
//==============================================================================
|
||||
void drawGlyph (RenderTargetType& target, const Font& font, const int glyphNumber, Point<float> pos)
|
||||
{
|
||||
const ScopedReadLock srl (lock);
|
||||
|
||||
if (CachedGlyphType* glyph = findExistingGlyph (font, glyphNumber))
|
||||
if (ReferenceCountedObjectPtr<CachedGlyphType> glyph = findOrCreateGlyph (font, glyphNumber))
|
||||
{
|
||||
++hits;
|
||||
glyph->lastAccessCount = ++accessCounter;
|
||||
glyph->draw (target, pos);
|
||||
return;
|
||||
}
|
||||
|
||||
const ScopedWriteLock swl (lock);
|
||||
|
||||
++misses;
|
||||
CachedGlyphType* glyph = getGlyphForReuse();
|
||||
jassert (glyph != nullptr);
|
||||
|
||||
glyph->generate (font, glyphNumber);
|
||||
glyph->lastAccessCount = ++accessCounter;
|
||||
glyph->draw (target, pos);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
const ScopedWriteLock swl (lock);
|
||||
const ScopedLock sl (lock);
|
||||
glyphs.clear();
|
||||
addNewGlyphSlots (120);
|
||||
hits.set (0);
|
||||
|
|
@ -196,9 +182,26 @@ public:
|
|||
|
||||
private:
|
||||
friend struct ContainerDeletePolicy<CachedGlyphType>;
|
||||
OwnedArray<CachedGlyphType> glyphs;
|
||||
ReferenceCountedArray<CachedGlyphType> glyphs;
|
||||
Atomic<int> accessCounter, hits, misses;
|
||||
ReadWriteLock lock;
|
||||
CriticalSection lock;
|
||||
|
||||
ReferenceCountedObjectPtr<CachedGlyphType> findOrCreateGlyph (const Font& font, int glyphNumber)
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
if (CachedGlyphType* g = findExistingGlyph (font, glyphNumber))
|
||||
{
|
||||
++hits;
|
||||
return g;
|
||||
}
|
||||
|
||||
++misses;
|
||||
CachedGlyphType* g = getGlyphForReuse();
|
||||
jassert (g != nullptr);
|
||||
g->generate (font, glyphNumber);
|
||||
return g;
|
||||
}
|
||||
|
||||
CachedGlyphType* findExistingGlyph (const Font& font, int glyphNumber) const
|
||||
{
|
||||
|
|
@ -267,7 +270,7 @@ private:
|
|||
//==============================================================================
|
||||
/** Caches a glyph as an edge-table. */
|
||||
template <class RendererType>
|
||||
class CachedGlyphEdgeTable
|
||||
class CachedGlyphEdgeTable : public ReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
CachedGlyphEdgeTable() : glyph (0), lastAccessCount (0) {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue