Browse Source

win32 font name length fix. Tidied up ScopedLock class structure, creating some templated classes for generic RAII locking.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
fa04e0cf93
58 changed files with 704 additions and 559 deletions
  1. +2
    -2
      Builds/MacOSX/Juce.xcodeproj/project.pbxproj
  2. +1
    -1
      Builds/VisualStudio2005/Juce.vcproj
  3. +1
    -1
      Builds/VisualStudio2008/Juce.vcproj
  4. +1
    -1
      Builds/VisualStudio2008_DLL/Juce.vcproj
  5. +1
    -1
      Builds/VisualStudio2010/Juce.vcxproj
  6. +2
    -2
      Builds/VisualStudio2010/Juce.vcxproj.filters
  7. +2
    -2
      Builds/iOS/Juce.xcodeproj/project.pbxproj
  8. +1
    -2
      Juce.jucer
  9. +16
    -23
      juce_amalgamated.cpp
  10. +357
    -263
      juce_amalgamated.h
  11. +0
    -1
      src/audio/audio_sources/juce_AudioFormatReaderSource.cpp
  12. +0
    -1
      src/audio/audio_sources/juce_AudioSourcePlayer.cpp
  13. +0
    -1
      src/audio/audio_sources/juce_AudioTransportSource.cpp
  14. +0
    -1
      src/audio/audio_sources/juce_BufferingAudioSource.cpp
  15. +0
    -1
      src/audio/audio_sources/juce_ChannelRemappingAudioSource.cpp
  16. +0
    -1
      src/audio/audio_sources/juce_MixerAudioSource.cpp
  17. +1
    -1
      src/audio/audio_sources/juce_ResamplingAudioSource.h
  18. +0
    -1
      src/audio/dsp/juce_IIRFilter.cpp
  19. +0
    -1
      src/audio/midi/juce_MidiKeyboardState.h
  20. +0
    -1
      src/audio/midi/juce_MidiMessageCollector.cpp
  21. +0
    -1
      src/audio/midi/juce_MidiOutput.cpp
  22. +1
    -1
      src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm
  23. +1
    -1
      src/audio/plugins/formats/juce_VSTPluginFormat.cpp
  24. +0
    -1
      src/audio/processors/juce_AudioProcessor.cpp
  25. +0
    -1
      src/audio/processors/juce_AudioProcessorPlayer.cpp
  26. +0
    -1
      src/audio/synthesisers/juce_Synthesiser.cpp
  27. +0
    -1
      src/containers/juce_PropertySet.cpp
  28. +0
    -1
      src/core/juce_FileLogger.cpp
  29. +0
    -2
      src/core/juce_Singleton.h
  30. +1
    -1
      src/core/juce_StandardHeader.h
  31. +0
    -1
      src/events/juce_ActionBroadcaster.cpp
  32. +0
    -1
      src/events/juce_InterprocessConnection.cpp
  33. +0
    -1
      src/events/juce_MessageManager.cpp
  34. +1
    -0
      src/events/juce_MultiTimer.h
  35. +1
    -1
      src/events/juce_Timer.cpp
  36. +0
    -1
      src/gui/components/filebrowser/juce_DirectoryContentsList.cpp
  37. +1
    -0
      src/gui/components/mouse/juce_MouseCursor.cpp
  38. +0
    -1
      src/gui/components/special/juce_OpenGLComponent.cpp
  39. +0
    -1
      src/gui/graphics/imaging/juce_ImageCache.cpp
  40. +0
    -1
      src/io/files/juce_ZipFile.cpp
  41. +0
    -1
      src/io/network/juce_Socket.cpp
  42. +0
    -1
      src/io/streams/juce_OutputStream.cpp
  43. +3
    -3
      src/juce_core_includes.h
  44. +0
    -1
      src/native/linux/juce_linux_NativeCode.cpp
  45. +16
    -23
      src/native/windows/juce_win32_Fonts.cpp
  46. +1
    -0
      src/text/juce_LocalisedStrings.cpp
  47. +96
    -60
      src/threads/juce_CriticalSection.h
  48. +0
    -1
      src/threads/juce_ReadWriteLock.cpp
  49. +1
    -0
      src/threads/juce_ReadWriteLock.h
  50. +107
    -35
      src/threads/juce_ScopedLock.h
  51. +0
    -101
      src/threads/juce_ScopedTryLock.h
  52. +87
    -0
      src/threads/juce_SpinLock.h
  53. +1
    -1
      src/threads/juce_Thread.cpp
  54. +0
    -1
      src/threads/juce_ThreadPool.h
  55. +0
    -1
      src/threads/juce_TimeSliceThread.cpp
  56. +1
    -1
      src/utilities/juce_DeletedAtShutdown.cpp
  57. +0
    -1
      src/utilities/juce_PropertiesFile.cpp
  58. +0
    -1
      src/utilities/juce_UnitTest.cpp

+ 2
- 2
Builds/MacOSX/Juce.xcodeproj/project.pbxproj View File

@@ -1069,8 +1069,8 @@
9E622C38E4BD511B6ABBF7AA = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ReadWriteLock.h; path = ../../src/threads/juce_ReadWriteLock.h; sourceTree = SOURCE_ROOT; };
6734838B47EF0D9ACEE571CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedLock.h; path = ../../src/threads/juce_ScopedLock.h; sourceTree = SOURCE_ROOT; };
F00BDEF5CE2B281CBE2E89A2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedReadLock.h; path = ../../src/threads/juce_ScopedReadLock.h; sourceTree = SOURCE_ROOT; };
18AD809DE191E1CF42D0BF53 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedTryLock.h; path = ../../src/threads/juce_ScopedTryLock.h; sourceTree = SOURCE_ROOT; };
C5F20B02D7843F3C5ABEDFD4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedWriteLock.h; path = ../../src/threads/juce_ScopedWriteLock.h; sourceTree = SOURCE_ROOT; };
1FD1C9A3D2DB64C825FDAC8B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_SpinLock.h; path = ../../src/threads/juce_SpinLock.h; sourceTree = SOURCE_ROOT; };
4D60F7F748CF6702D1E45960 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Thread.cpp; path = ../../src/threads/juce_Thread.cpp; sourceTree = SOURCE_ROOT; };
EFE26D4E1E2B92828DBA3A99 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Thread.h; path = ../../src/threads/juce_Thread.h; sourceTree = SOURCE_ROOT; };
EF06213027EA3F7C54EE0F18 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ThreadPool.cpp; path = ../../src/threads/juce_ThreadPool.cpp; sourceTree = SOURCE_ROOT; };
@@ -1904,8 +1904,8 @@
9E622C38E4BD511B6ABBF7AA,
6734838B47EF0D9ACEE571CD,
F00BDEF5CE2B281CBE2E89A2,
18AD809DE191E1CF42D0BF53,
C5F20B02D7843F3C5ABEDFD4,
1FD1C9A3D2DB64C825FDAC8B,
4D60F7F748CF6702D1E45960,
EFE26D4E1E2B92828DBA3A99,
EF06213027EA3F7C54EE0F18,


+ 1
- 1
Builds/VisualStudio2005/Juce.vcproj View File

@@ -993,8 +993,8 @@
<File RelativePath="..\..\src\threads\juce_ReadWriteLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedReadLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedTryLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedWriteLock.h"/>
<File RelativePath="..\..\src\threads\juce_SpinLock.h"/>
<File RelativePath="..\..\src\threads\juce_Thread.cpp"/>
<File RelativePath="..\..\src\threads\juce_Thread.h"/>
<File RelativePath="..\..\src\threads\juce_ThreadPool.cpp"/>


+ 1
- 1
Builds/VisualStudio2008/Juce.vcproj View File

@@ -993,8 +993,8 @@
<File RelativePath="..\..\src\threads\juce_ReadWriteLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedReadLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedTryLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedWriteLock.h"/>
<File RelativePath="..\..\src\threads\juce_SpinLock.h"/>
<File RelativePath="..\..\src\threads\juce_Thread.cpp"/>
<File RelativePath="..\..\src\threads\juce_Thread.h"/>
<File RelativePath="..\..\src\threads\juce_ThreadPool.cpp"/>


+ 1
- 1
Builds/VisualStudio2008_DLL/Juce.vcproj View File

@@ -995,8 +995,8 @@
<File RelativePath="..\..\src\threads\juce_ReadWriteLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedReadLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedTryLock.h"/>
<File RelativePath="..\..\src\threads\juce_ScopedWriteLock.h"/>
<File RelativePath="..\..\src\threads\juce_SpinLock.h"/>
<File RelativePath="..\..\src\threads\juce_Thread.cpp"/>
<File RelativePath="..\..\src\threads\juce_Thread.h"/>
<File RelativePath="..\..\src\threads\juce_ThreadPool.cpp"/>


+ 1
- 1
Builds/VisualStudio2010/Juce.vcxproj View File

@@ -800,8 +800,8 @@
<ClInclude Include="..\..\src\threads\juce_ReadWriteLock.h"/>
<ClInclude Include="..\..\src\threads\juce_ScopedLock.h"/>
<ClInclude Include="..\..\src\threads\juce_ScopedReadLock.h"/>
<ClInclude Include="..\..\src\threads\juce_ScopedTryLock.h"/>
<ClInclude Include="..\..\src\threads\juce_ScopedWriteLock.h"/>
<ClInclude Include="..\..\src\threads\juce_SpinLock.h"/>
<ClInclude Include="..\..\src\threads\juce_Thread.h"/>
<ClInclude Include="..\..\src\threads\juce_ThreadPool.h"/>
<ClInclude Include="..\..\src\threads\juce_TimeSliceThread.h"/>


+ 2
- 2
Builds/VisualStudio2010/Juce.vcxproj.filters View File

@@ -2334,10 +2334,10 @@
<ClInclude Include="..\..\src\threads\juce_ScopedReadLock.h">
<Filter>Juce\Source\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\src\threads\juce_ScopedTryLock.h">
<ClInclude Include="..\..\src\threads\juce_ScopedWriteLock.h">
<Filter>Juce\Source\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\src\threads\juce_ScopedWriteLock.h">
<ClInclude Include="..\..\src\threads\juce_SpinLock.h">
<Filter>Juce\Source\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\src\threads\juce_Thread.h">


+ 2
- 2
Builds/iOS/Juce.xcodeproj/project.pbxproj View File

@@ -1069,8 +1069,8 @@
9E622C38E4BD511B6ABBF7AA = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ReadWriteLock.h; path = ../../src/threads/juce_ReadWriteLock.h; sourceTree = SOURCE_ROOT; };
6734838B47EF0D9ACEE571CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedLock.h; path = ../../src/threads/juce_ScopedLock.h; sourceTree = SOURCE_ROOT; };
F00BDEF5CE2B281CBE2E89A2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedReadLock.h; path = ../../src/threads/juce_ScopedReadLock.h; sourceTree = SOURCE_ROOT; };
18AD809DE191E1CF42D0BF53 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedTryLock.h; path = ../../src/threads/juce_ScopedTryLock.h; sourceTree = SOURCE_ROOT; };
C5F20B02D7843F3C5ABEDFD4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedWriteLock.h; path = ../../src/threads/juce_ScopedWriteLock.h; sourceTree = SOURCE_ROOT; };
1FD1C9A3D2DB64C825FDAC8B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_SpinLock.h; path = ../../src/threads/juce_SpinLock.h; sourceTree = SOURCE_ROOT; };
4D60F7F748CF6702D1E45960 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Thread.cpp; path = ../../src/threads/juce_Thread.cpp; sourceTree = SOURCE_ROOT; };
EFE26D4E1E2B92828DBA3A99 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Thread.h; path = ../../src/threads/juce_Thread.h; sourceTree = SOURCE_ROOT; };
EF06213027EA3F7C54EE0F18 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ThreadPool.cpp; path = ../../src/threads/juce_ThreadPool.cpp; sourceTree = SOURCE_ROOT; };
@@ -1904,8 +1904,8 @@
9E622C38E4BD511B6ABBF7AA,
6734838B47EF0D9ACEE571CD,
F00BDEF5CE2B281CBE2E89A2,
18AD809DE191E1CF42D0BF53,
C5F20B02D7843F3C5ABEDFD4,
1FD1C9A3D2DB64C825FDAC8B,
4D60F7F748CF6702D1E45960,
EFE26D4E1E2B92828DBA3A99,
EF06213027EA3F7C54EE0F18,


+ 1
- 2
Juce.jucer View File

@@ -1541,10 +1541,9 @@
file="src/threads/juce_ScopedLock.h"/>
<FILE id="4fVPnhFxo" name="juce_ScopedReadLock.h" compile="0" resource="0"
file="src/threads/juce_ScopedReadLock.h"/>
<FILE id="3YrDBGCt7" name="juce_ScopedTryLock.h" compile="0" resource="0"
file="src/threads/juce_ScopedTryLock.h"/>
<FILE id="ZzfHTAct1" name="juce_ScopedWriteLock.h" compile="0" resource="0"
file="src/threads/juce_ScopedWriteLock.h"/>
<FILE id="B67j1G" name="juce_SpinLock.h" compile="0" resource="0" file="src/threads/juce_SpinLock.h"/>
<FILE id="91WC4L0ai" name="juce_Thread.cpp" compile="1" resource="0"
file="src/threads/juce_Thread.cpp"/>
<FILE id="g4jLEfRco" name="juce_Thread.h" compile="0" resource="0"


+ 16
- 23
juce_amalgamated.cpp View File

@@ -244672,10 +244672,7 @@ void MessageManager::doPlatformSpecificShutdown()
// compiled on its own).
#if JUCE_INCLUDED_FILE

static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe,
NEWTEXTMETRICEXW*,
int type,
LPARAM lParam)
static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam)
{
if (lpelfe != 0 && (type & RASTER_FONTTYPE) == 0)
{
@@ -244687,10 +244684,7 @@ static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe,
return 1;
}

static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe,
NEWTEXTMETRICEXW*,
int type,
LPARAM lParam)
static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam)
{
if (lpelfe != 0 && (type & RASTER_FONTTYPE) == 0)
{
@@ -244703,7 +244697,7 @@ static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe,
lf.lfPitchAndFamily = FF_DONTCARE;

const String fontName (lpelfe->elfLogFont.lfFaceName);
fontName.copyToUTF16 (lf.lfFaceName, LF_FACESIZE - 1);
fontName.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));

HDC dc = CreateCompatibleDC (0);
EnumFontFamiliesEx (dc, &lf,
@@ -244728,7 +244722,6 @@ const StringArray Font::findAllTypefaceNames()
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfPitchAndFamily = FF_DONTCARE;
lf.lfFaceName[0] = 0;

EnumFontFamiliesEx (dc, &lf,
(FONTENUMPROCW) &wfontEnum1,
@@ -244794,18 +244787,18 @@ public:
SetMapperFlags (dc, 0);
SetMapMode (dc, MM_TEXT);

LOGFONTW lfw = { 0 };
lfw.lfCharSet = DEFAULT_CHARSET;
lfw.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lfw.lfOutPrecision = OUT_OUTLINE_PRECIS;
lfw.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lfw.lfQuality = PROOF_QUALITY;
lfw.lfItalic = (BYTE) (italic ? TRUE : FALSE);
lfw.lfWeight = bold ? FW_BOLD : FW_NORMAL;
fontName.copyToUTF16 (lfw.lfFaceName, LF_FACESIZE - 1);
LOGFONTW lf = { 0 };
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lf.lfQuality = PROOF_QUALITY;
lf.lfItalic = (BYTE) (italic ? TRUE : FALSE);
lf.lfWeight = bold ? FW_BOLD : FW_NORMAL;
lf.lfHeight = size > 0 ? size : -256;
fontName.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));

lfw.lfHeight = size > 0 ? size : -256;
HFONT standardSizedFont = CreateFontIndirect (&lfw);
HFONT standardSizedFont = CreateFontIndirect (&lf);

if (standardSizedFont != 0)
{
@@ -244818,8 +244811,8 @@ public:
OUTLINETEXTMETRIC otm;
if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0)
{
lfw.lfHeight = -(int) otm.otmEMSquare;
fontH = CreateFontIndirect (&lfw);
lf.lfHeight = -(int) otm.otmEMSquare;
fontH = CreateFontIndirect (&lf);

SelectObject (dc, fontH);
DeleteObject (standardSizedFont);


+ 357
- 263
juce_amalgamated.h View File

@@ -73,7 +73,7 @@ namespace JuceDummyNamespace {}
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 63
#define JUCE_BUILDNUMBER 64

/** Current Juce version number.

@@ -6454,10 +6454,210 @@ public:
#ifndef __JUCE_CRITICALSECTION_JUCEHEADER__
#define __JUCE_CRITICALSECTION_JUCEHEADER__

#ifndef DOXYGEN
class ScopedLock;
class ScopedUnlock;
#endif

/*** Start of inlined file: juce_ScopedLock.h ***/
#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__
#define __JUCE_SCOPEDLOCK_JUCEHEADER__

/**
Automatically locks and unlocks a mutex object.

Use one of these as a local variable to provide RAII-based locking of a mutex.

The templated class could be a CriticalSection, SpinLock, or anything else that
provides enter() and exit() methods.

e.g. @code
CriticalSection myCriticalSection;

for (;;)
{
const GenericScopedLock<CriticalSection> myScopedLock (myCriticalSection);
// myCriticalSection is now locked

...do some stuff...

// myCriticalSection gets unlocked here.
}
@endcode

@see GenericScopedUnlock, CriticalSection, SpinLock, ScopedLock, ScopedUnlock
*/
template <class LockType>
class GenericScopedLock
{
public:

/** Creates a GenericScopedLock.

As soon as it is created, this will acquire the lock, and when the GenericScopedLock
object is deleted, the lock will be released.

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.
*/
inline explicit GenericScopedLock (const LockType& lock) throw() : lock_ (lock) { lock.enter(); }

/** Destructor.
The lock will be released when the destructor is called.
Make sure this object is created and deleted by the same thread, otherwise there are
no guarantees what will happen!
*/
inline ~GenericScopedLock() throw() { lock_.exit(); }

private:

const LockType& lock_;

JUCE_DECLARE_NON_COPYABLE (GenericScopedLock);
};

/**
Automatically unlocks and re-locks a mutex object.

This is the reverse of a GenericScopedLock object - instead of locking the mutex
for the lifetime of this object, it unlocks it.

Make sure you don't try to unlock mutexes that aren't actually locked!

e.g. @code

CriticalSection myCriticalSection;

for (;;)
{
const GenericScopedLock<CriticalSection> myScopedLock (myCriticalSection);
// myCriticalSection is now locked

... do some stuff with it locked ..

while (xyz)
{
... do some stuff with it locked ..

const GenericScopedUnlock<CriticalSection> unlocker (myCriticalSection);

// myCriticalSection is now unlocked for the remainder of this block,
// and re-locked at the end.

...do some stuff with it unlocked ...
}

// myCriticalSection gets unlocked here.
}
@endcode

@see GenericScopedLock, CriticalSection, ScopedLock, ScopedUnlock
*/
template <class LockType>
class GenericScopedUnlock
{
public:

/** Creates a GenericScopedUnlock.

As soon as it is created, this will unlock the CriticalSection, and
when the ScopedLock object is deleted, the CriticalSection will
be re-locked.

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.
*/
inline explicit GenericScopedUnlock (const LockType& lock) throw() : lock_ (lock) { lock.exit(); }

/** Destructor.

The CriticalSection will be unlocked when the destructor is called.

Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
inline ~GenericScopedUnlock() throw() { lock_.enter(); }

private:

const LockType& lock_;

JUCE_DECLARE_NON_COPYABLE (GenericScopedUnlock);
};

/**
Automatically locks and unlocks a mutex object.

Use one of these as a local variable to provide RAII-based locking of a mutex.

The templated class could be a CriticalSection, SpinLock, or anything else that
provides enter() and exit() methods.

e.g. @code

CriticalSection myCriticalSection;

for (;;)
{
const GenericScopedTryLock<CriticalSection> myScopedTryLock (myCriticalSection);

// Unlike using a ScopedLock, this may fail to actually get the lock, so you
// should test this with the isLocked() method before doing your thread-unsafe
// action..
if (myScopedTryLock.isLocked())
{
...do some stuff...
}
else
{
..our attempt at locking failed because another thread had already locked it..
}

// myCriticalSection gets unlocked here (if it was locked)
}
@endcode

@see CriticalSection::tryEnter, GenericScopedLock, GenericScopedUnlock
*/
template <class LockType>
class GenericScopedTryLock
{
public:

/** 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).

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.
*/
inline explicit GenericScopedTryLock (const LockType& lock) throw()
: lock_ (lock), lockWasSuccessful (lock.tryEnter()) {}

/** Destructor.

The mutex will be unlocked (if it had been successfully locked) when the
destructor is called.

Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
inline ~GenericScopedTryLock() throw() { if (lockWasSuccessful) lock_.exit(); }

/** Returns true if the mutex was successfully locked. */
bool isLocked() const throw() { return lockWasSuccessful; }

private:

const LockType& lock_;
const bool lockWasSuccessful;

JUCE_DECLARE_NON_COPYABLE (GenericScopedTryLock);
};

#endif // __JUCE_SCOPEDLOCK_JUCEHEADER__
/*** End of inlined file: juce_ScopedLock.h ***/

/**
A mutex class.
@@ -6466,7 +6666,7 @@ public:
one of these is by using RAII in the form of a local ScopedLock object - have a look
through the codebase for many examples of how to do this.

@see ScopedLock, SpinLock, Thread, InterProcessLock
@see ScopedLock, ScopedTryLock, ScopedUnlock, SpinLock, ReadWriteLock, Thread, InterProcessLock
*/
class JUCE_API CriticalSection
{
@@ -6485,8 +6685,9 @@ public:

If the lock is already held by the caller thread, the method returns immediately.
If the lock is currently held by another thread, this will wait until it becomes free.
Remember that it's highly recommended that you never use this method, but use a ScopedLock
to manage the locking instead.

It's strongly recommended that you never call this method directly - instead use the
ScopedLock class to manage the locking using an RAII pattern instead.

@see exit, tryEnter, ScopedLock
*/
@@ -6514,11 +6715,14 @@ public:
*/
void exit() const throw();

/** Provides the type of scoped lock to use with this type of critical section object. */
typedef ScopedLock ScopedLockType;
/** Provides the type of scoped lock to use with a CriticalSection. */
typedef GenericScopedLock <CriticalSection> ScopedLockType;

/** Provides the type of scoped unlocker to use with this type of critical section object. */
typedef ScopedUnlock ScopedUnlockType;
/** Provides the type of scoped unlocker to use with a CriticalSection. */
typedef GenericScopedUnlock <CriticalSection> ScopedUnlockType;

/** Provides the type of scoped try-locker to use with a CriticalSection. */
typedef GenericScopedTryLock <CriticalSection> ScopedTryLockType;

private:

@@ -6571,63 +6775,99 @@ private:
};

/**
A simple spin-lock class that can be used as a simple, low-overhead mutex for
uncontended situations.
Automatically locks and unlocks a CriticalSection object.

Note that unlike a CriticalSection, this type of lock is not re-entrant, and may
be less efficient when used it a highly contended situation, but it's very small and
requires almost no initialisation.
It's most appropriate for simple situations where you're only going to hold the
lock for a very brief time.
Use one of these as a local variable to provide RAII-based locking of a CriticalSection.

@see CriticalSection
*/
class JUCE_API SpinLock
{
public:
inline SpinLock() throw() {}
inline ~SpinLock() throw() {}
e.g. @code

void enter() const throw();
bool tryEnter() const throw();
CriticalSection myCriticalSection;

inline void exit() const throw()
for (;;)
{
jassert (lock.value == 1); // Agh! Releasing a lock that isn't currently held!
lock = 0;
const ScopedLock myScopedLock (myCriticalSection);
// myCriticalSection is now locked

...do some stuff...

// myCriticalSection gets unlocked here.
}
@endcode

/** A scoped-lock type to use with a SpinLock. */
class ScopedLockType
{
public:
inline explicit ScopedLockType (const SpinLock& lock_) throw() : lock (lock_) { lock_.enter(); }
inline ~ScopedLockType() throw() { lock.exit(); }
@see CriticalSection, ScopedUnlock
*/
typedef CriticalSection::ScopedLockType ScopedLock;

private:
/**
Automatically unlocks and re-locks a CriticalSection object.

const SpinLock& lock;
JUCE_DECLARE_NON_COPYABLE (ScopedLockType);
};
This is the reverse of a ScopedLock object - instead of locking the critical
section for the lifetime of this object, it unlocks it.

/** A scoped-unlocker type to use with a SpinLock. */
class ScopedUnlockType
Make sure you don't try to unlock critical sections that aren't actually locked!

e.g. @code

CriticalSection myCriticalSection;

for (;;)
{
public:
inline explicit ScopedUnlockType (const SpinLock& lock_) throw() : lock (lock_) { lock_.exit(); }
inline ~ScopedUnlockType() throw() { lock.enter(); }
const ScopedLock myScopedLock (myCriticalSection);
// myCriticalSection is now locked

private:
... do some stuff with it locked ..

const SpinLock& lock;
JUCE_DECLARE_NON_COPYABLE (ScopedUnlockType);
};
while (xyz)
{
... do some stuff with it locked ..

private:
const ScopedUnlock unlocker (myCriticalSection);

mutable Atomic<int> lock;
JUCE_DECLARE_NON_COPYABLE (SpinLock);
};
// myCriticalSection is now unlocked for the remainder of this block,
// and re-locked at the end.

...do some stuff with it unlocked ...
}

// myCriticalSection gets unlocked here.
}
@endcode

@see CriticalSection, ScopedLock
*/
typedef CriticalSection::ScopedUnlockType ScopedUnlock;

/**
Automatically tries to lock and unlock a CriticalSection object.

Use one of these as a local variable to control access to a CriticalSection.

e.g. @code
CriticalSection myCriticalSection;

for (;;)
{
const ScopedTryLock myScopedTryLock (myCriticalSection);

// Unlike using a ScopedLock, this may fail to actually get the lock, so you
// should test this with the isLocked() method before doing your thread-unsafe
// action..
if (myScopedTryLock.isLocked())
{
...do some stuff...
}
else
{
..our attempt at locking failed because another thread had already locked it..
}

// myCriticalSection gets unlocked here (if it was locked)
}
@endcode

@see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock
*/
typedef CriticalSection::ScopedTryLockType ScopedTryLock;

#endif // __JUCE_CRITICALSECTION_JUCEHEADER__
/*** End of inlined file: juce_CriticalSection.h ***/
@@ -17507,137 +17747,6 @@ private:
#ifndef __JUCE_SINGLETON_JUCEHEADER__
#define __JUCE_SINGLETON_JUCEHEADER__


/*** Start of inlined file: juce_ScopedLock.h ***/
#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__
#define __JUCE_SCOPEDLOCK_JUCEHEADER__

/**
Automatically locks and unlocks a CriticalSection object.

Use one of these as a local variable to control access to a CriticalSection.

e.g. @code

CriticalSection myCriticalSection;

for (;;)
{
const ScopedLock myScopedLock (myCriticalSection);
// myCriticalSection is now locked

...do some stuff...

// myCriticalSection gets unlocked here.
}
@endcode

@see CriticalSection, ScopedUnlock
*/
class ScopedLock
{
public:

/** Creates a ScopedLock.

As soon as it is created, this will lock the CriticalSection, and
when the ScopedLock object is deleted, the CriticalSection will
be unlocked.

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.
*/
inline explicit ScopedLock (const CriticalSection& lock) throw() : lock_ (lock) { lock.enter(); }

/** Destructor.

The CriticalSection will be unlocked when the destructor is called.

Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
inline ~ScopedLock() throw() { lock_.exit(); }

private:

const CriticalSection& lock_;

JUCE_DECLARE_NON_COPYABLE (ScopedLock);
};

/**
Automatically unlocks and re-locks a CriticalSection object.

This is the reverse of a ScopedLock object - instead of locking the critical
section for the lifetime of this object, it unlocks it.

Make sure you don't try to unlock critical sections that aren't actually locked!

e.g. @code

CriticalSection myCriticalSection;

for (;;)
{
const ScopedLock myScopedLock (myCriticalSection);
// myCriticalSection is now locked

... do some stuff with it locked ..

while (xyz)
{
... do some stuff with it locked ..

const ScopedUnlock unlocker (myCriticalSection);

// myCriticalSection is now unlocked for the remainder of this block,
// and re-locked at the end.

...do some stuff with it unlocked ...
}

// myCriticalSection gets unlocked here.
}
@endcode

@see CriticalSection, ScopedLock
*/
class ScopedUnlock
{
public:

/** Creates a ScopedUnlock.

As soon as it is created, this will unlock the CriticalSection, and
when the ScopedLock object is deleted, the CriticalSection will
be re-locked.

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.
*/
inline explicit ScopedUnlock (const CriticalSection& lock) throw() : lock_ (lock) { lock.exit(); }

/** Destructor.

The CriticalSection will be unlocked when the destructor is called.

Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
inline ~ScopedUnlock() throw() { lock_.enter(); }

private:

const CriticalSection& lock_;

JUCE_DECLARE_NON_COPYABLE (ScopedUnlock);
};

#endif // __JUCE_SCOPEDLOCK_JUCEHEADER__
/*** End of inlined file: juce_ScopedLock.h ***/

/**
Macro to declare member variables and methods for a singleton class.

@@ -21897,6 +22006,66 @@ private:
#define __JUCE_READWRITELOCK_JUCEHEADER__


/*** Start of inlined file: juce_SpinLock.h ***/
#ifndef __JUCE_SPINLOCK_JUCEHEADER__
#define __JUCE_SPINLOCK_JUCEHEADER__

/**
A simple spin-lock class that can be used as a simple, low-overhead mutex for
uncontended situations.

Note that unlike a CriticalSection, this type of lock is not re-entrant, and may
be less efficient when used it a highly contended situation, but it's very small and
requires almost no initialisation.
It's most appropriate for simple situations where you're only going to hold the
lock for a very brief time.

@see CriticalSection
*/
class JUCE_API SpinLock
{
public:
inline SpinLock() throw() {}
inline ~SpinLock() throw() {}

/** Acquires the lock.
This will block until the lock has been successfully acquired by this thread.
Note that a SpinLock is NOT re-entrant, and is not smart enough to know whether the
caller thread already has the lock - so if a thread tries to acquire a lock that it
already holds, this method will never return!

It's strongly recommended that you never call this method directly - instead use the
ScopedLockType class to manage the locking using an RAII pattern instead.
*/
void enter() const throw();

/** Attempts to acquire the lock, returning true if this was successful. */
bool tryEnter() const throw();

/** Releases the lock. */
inline void exit() const throw()
{
jassert (lock.value == 1); // Agh! Releasing a lock that isn't currently held!
lock = 0;
}

/** Provides the type of scoped lock to use for locking a SpinLock. */
typedef GenericScopedLock <SpinLock> ScopedLockType;

/** Provides the type of scoped unlocker to use with a SpinLock. */
typedef GenericScopedUnlock <SpinLock> ScopedUnlockType;

private:

mutable Atomic<int> lock;

JUCE_DECLARE_NON_COPYABLE (SpinLock);
};

#endif // __JUCE_SPINLOCK_JUCEHEADER__
/*** End of inlined file: juce_SpinLock.h ***/


/*** Start of inlined file: juce_WaitableEvent.h ***/
#ifndef __JUCE_WAITABLEEVENT_JUCEHEADER__
#define __JUCE_WAITABLEEVENT_JUCEHEADER__
@@ -22401,84 +22570,6 @@ private:
/*** End of inlined file: juce_ScopedReadLock.h ***/


#endif
#ifndef __JUCE_SCOPEDTRYLOCK_JUCEHEADER__

/*** Start of inlined file: juce_ScopedTryLock.h ***/
#ifndef __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
#define __JUCE_SCOPEDTRYLOCK_JUCEHEADER__

/**
Automatically tries to lock and unlock a CriticalSection object.

Use one of these as a local variable to control access to a CriticalSection.

e.g. @code

CriticalSection myCriticalSection;

for (;;)
{
const ScopedTryLock myScopedTryLock (myCriticalSection);

// Unlike using a ScopedLock, this may fail to actually get the lock, so you
// should test this with the isLocked() method before doing your thread-unsafe
// action..
if (myScopedTryLock.isLocked())
{
...do some stuff...
}
else
{
..our attempt at locking failed because another thread had already locked it..
}

// myCriticalSection gets unlocked here (if it was locked)
}
@endcode

@see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock
*/
class JUCE_API ScopedTryLock
{
public:

/** Creates a ScopedTryLock.

As soon as it is created, this will try to lock the CriticalSection, and
when the ScopedTryLock object is deleted, the CriticalSection will
be unlocked if the lock was successful.

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.
*/
inline explicit ScopedTryLock (const CriticalSection& lock) throw() : lock_ (lock), lockWasSuccessful (lock.tryEnter()) {}

/** Destructor.

The CriticalSection will be unlocked (if locked) when the destructor is called.

Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
inline ~ScopedTryLock() throw() { if (lockWasSuccessful) lock_.exit(); }

/** Returns true if the CriticalSection was successfully locked. */
bool isLocked() const throw() { return lockWasSuccessful; }

private:

const CriticalSection& lock_;
const bool lockWasSuccessful;

JUCE_DECLARE_NON_COPYABLE (ScopedTryLock);
};

#endif // __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
/*** End of inlined file: juce_ScopedTryLock.h ***/


#endif
#ifndef __JUCE_SCOPEDWRITELOCK_JUCEHEADER__

@@ -22544,6 +22635,9 @@ private:
/*** End of inlined file: juce_ScopedWriteLock.h ***/


#endif
#ifndef __JUCE_SPINLOCK_JUCEHEADER__

#endif
#ifndef __JUCE_THREAD_JUCEHEADER__



+ 0
- 1
src/audio/audio_sources/juce_AudioFormatReaderSource.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_AudioFormatReaderSource.h"
#include "../../threads/juce_ScopedLock.h"
//==============================================================================


+ 0
- 1
src/audio/audio_sources/juce_AudioSourcePlayer.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_AudioSourcePlayer.h"
#include "../../threads/juce_ScopedLock.h"
//==============================================================================


+ 0
- 1
src/audio/audio_sources/juce_AudioTransportSource.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_AudioTransportSource.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../memory/juce_ScopedPointer.h"


+ 0
- 1
src/audio/audio_sources/juce_BufferingAudioSource.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_BufferingAudioSource.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../core/juce_Singleton.h"
#include "../../containers/juce_Array.h"
#include "../../utilities/juce_DeletedAtShutdown.h"


+ 0
- 1
src/audio/audio_sources/juce_ChannelRemappingAudioSource.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_ChannelRemappingAudioSource.h"
#include "../../threads/juce_ScopedLock.h"
//==============================================================================


+ 0
- 1
src/audio/audio_sources/juce_MixerAudioSource.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_MixerAudioSource.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../containers/juce_OwnedArray.h"


+ 1
- 1
src/audio/audio_sources/juce_ResamplingAudioSource.h View File

@@ -27,7 +27,7 @@
#define __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__
#include "juce_AudioSource.h"
#include "../../threads/juce_CriticalSection.h"
#include "../../threads/juce_SpinLock.h"
//==============================================================================


+ 0
- 1
src/audio/dsp/juce_IIRFilter.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_IIRFilter.h"
#include "../../threads/juce_ScopedLock.h"
//==============================================================================


+ 0
- 1
src/audio/midi/juce_MidiKeyboardState.h View File

@@ -27,7 +27,6 @@
#define __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__
#include "juce_MidiBuffer.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../containers/juce_Array.h"
class MidiKeyboardState;


+ 0
- 1
src/audio/midi/juce_MidiMessageCollector.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_MidiMessageCollector.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../core/juce_Time.h"


+ 0
- 1
src/audio/midi/juce_MidiOutput.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_MidiOutput.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../core/juce_Time.h"


+ 1
- 1
src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm View File

@@ -43,7 +43,7 @@ BEGIN_JUCE_NAMESPACE
#include "juce_AudioUnitPluginFormat.h"
#include "../juce_PluginDescription.h"
#include "../../../threads/juce_ScopedLock.h"
#include "../../../threads/juce_CriticalSection.h"
#include "../../../events/juce_Timer.h"
#include "../../../core/juce_PlatformUtilities.h"
#include "../../../gui/components/layout/juce_ComponentMovementWatcher.h"


+ 1
- 1
src/audio/plugins/formats/juce_VSTPluginFormat.cpp View File

@@ -63,7 +63,7 @@ BEGIN_JUCE_NAMESPACE
#include "juce_VSTPluginFormat.h"
#include "../../../threads/juce_Process.h"
#include "../../../threads/juce_ScopedLock.h"
#include "../../../threads/juce_CriticalSection.h"
#include "../../../maths/juce_Random.h"
#include "../../../io/files/juce_DirectoryIterator.h"
#include "../../../events/juce_Timer.h"


+ 0
- 1
src/audio/processors/juce_AudioProcessor.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_AudioProcessor.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../text/juce_XmlDocument.h"


+ 0
- 1
src/audio/processors/juce_AudioProcessorPlayer.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_AudioProcessorPlayer.h"
#include "../../threads/juce_ScopedLock.h"
//==============================================================================


+ 0
- 1
src/audio/synthesisers/juce_Synthesiser.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_Synthesiser.h"
#include "../../threads/juce_ScopedLock.h"
//==============================================================================


+ 0
- 1
src/containers/juce_PropertySet.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_PropertySet.h"
#include "../threads/juce_ScopedLock.h"
#include "../text/juce_XmlDocument.h"


+ 0
- 1
src/core/juce_FileLogger.cpp View File

@@ -30,7 +30,6 @@ BEGIN_JUCE_NAMESPACE
#include "juce_FileLogger.h"
#include "../io/files/juce_FileOutputStream.h"
#include "../io/files/juce_FileInputStream.h"
#include "../threads/juce_ScopedLock.h"
#include "../memory/juce_ScopedPointer.h"
#include "juce_SystemStats.h"


+ 0
- 2
src/core/juce_Singleton.h View File

@@ -26,8 +26,6 @@
#ifndef __JUCE_SINGLETON_JUCEHEADER__
#define __JUCE_SINGLETON_JUCEHEADER__
#include "../threads/juce_ScopedLock.h"
//==============================================================================
/**


+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -33,7 +33,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 63
#define JUCE_BUILDNUMBER 64
/** Current Juce version number.


+ 0
- 1
src/events/juce_ActionBroadcaster.cpp View File

@@ -29,7 +29,6 @@ BEGIN_JUCE_NAMESPACE
#include "juce_ActionBroadcaster.h"
#include "juce_MessageManager.h"
#include "../threads/juce_ScopedLock.h"
//==============================================================================


+ 0
- 1
src/events/juce_InterprocessConnection.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_InterprocessConnection.h"
#include "../threads/juce_ScopedLock.h"
#include "../memory/juce_ScopedPointer.h"


+ 0
- 1
src/events/juce_MessageManager.cpp View File

@@ -32,7 +32,6 @@ BEGIN_JUCE_NAMESPACE
#include "../application/juce_Application.h"
#include "../gui/components/juce_Component.h"
#include "../threads/juce_Thread.h"
#include "../threads/juce_ScopedLock.h"
#include "../core/juce_Time.h"
//==============================================================================


+ 1
- 0
src/events/juce_MultiTimer.h View File

@@ -28,6 +28,7 @@
#include "juce_Timer.h"
#include "../containers/juce_OwnedArray.h"
#include "../threads/juce_SpinLock.h"
//==============================================================================


+ 1
- 1
src/events/juce_Timer.cpp View File

@@ -34,7 +34,7 @@ BEGIN_JUCE_NAMESPACE
#include "../utilities/juce_DeletedAtShutdown.h"
#include "../core/juce_Time.h"
#include "../threads/juce_Thread.h"
#include "../threads/juce_ScopedLock.h"
#include "../threads/juce_SpinLock.h"
//==============================================================================


+ 0
- 1
src/gui/components/filebrowser/juce_DirectoryContentsList.cpp View File

@@ -29,7 +29,6 @@ BEGIN_JUCE_NAMESPACE
#include "juce_DirectoryContentsList.h"
#include "../../graphics/imaging/juce_ImageCache.h"
#include "../../../threads/juce_ScopedLock.h"
//==============================================================================


+ 1
- 0
src/gui/components/mouse/juce_MouseCursor.cpp View File

@@ -31,6 +31,7 @@ BEGIN_JUCE_NAMESPACE
#include "../juce_Component.h"
#include "../lookandfeel/juce_LookAndFeel.h"
#include "../mouse/juce_MouseInputSource.h"
#include "../../../threads/juce_SpinLock.h"
//==============================================================================


+ 0
- 1
src/gui/components/special/juce_OpenGLComponent.cpp View File

@@ -32,7 +32,6 @@ BEGIN_JUCE_NAMESPACE
#include "juce_OpenGLComponent.h"
#include "../windows/juce_ComponentPeer.h"
#include "../layout/juce_ComponentMovementWatcher.h"
#include "../../../threads/juce_ScopedLock.h"
//==============================================================================


+ 0
- 1
src/gui/graphics/imaging/juce_ImageCache.cpp View File

@@ -29,7 +29,6 @@ BEGIN_JUCE_NAMESPACE
#include "juce_ImageCache.h"
#include "juce_ImageFileFormat.h"
#include "../../../threads/juce_ScopedLock.h"
#include "../../../utilities/juce_DeletedAtShutdown.h"
#include "../../../containers/juce_OwnedArray.h"
#include "../../../events/juce_Timer.h"


+ 0
- 1
src/io/files/juce_ZipFile.cpp View File

@@ -35,7 +35,6 @@ BEGIN_JUCE_NAMESPACE
#include "../streams/juce_GZIPCompressorOutputStream.h"
#include "juce_FileInputStream.h"
#include "juce_FileOutputStream.h"
#include "../../threads/juce_ScopedLock.h"
//==============================================================================


+ 0
- 1
src/io/network/juce_Socket.cpp View File

@@ -58,7 +58,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_Socket.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../threads/juce_Thread.h"
#if JUCE_WINDOWS


+ 0
- 1
src/io/streams/juce_OutputStream.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_OutputStream.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../containers/juce_Array.h"
#include "../../memory/juce_ScopedPointer.h"
#include "../files/juce_FileInputStream.h"


+ 3
- 3
src/juce_core_includes.h View File

@@ -296,12 +296,12 @@
#ifndef __JUCE_SCOPEDREADLOCK_JUCEHEADER__
#include "threads/juce_ScopedReadLock.h"
#endif
#ifndef __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
#include "threads/juce_ScopedTryLock.h"
#endif
#ifndef __JUCE_SCOPEDWRITELOCK_JUCEHEADER__
#include "threads/juce_ScopedWriteLock.h"
#endif
#ifndef __JUCE_SPINLOCK_JUCEHEADER__
#include "threads/juce_SpinLock.h"
#endif
#ifndef __JUCE_THREAD_JUCEHEADER__
#include "threads/juce_Thread.h"
#endif


+ 0
- 1
src/native/linux/juce_linux_NativeCode.cpp View File

@@ -56,7 +56,6 @@ BEGIN_JUCE_NAMESPACE
#include "../../text/juce_XmlDocument.h"
#include "../../threads/juce_CriticalSection.h"
#include "../../threads/juce_Thread.h"
#include "../../threads/juce_ScopedLock.h"
#include "../../threads/juce_InterProcessLock.h"
#include "../../threads/juce_WaitableEvent.h"
#include "../../threads/juce_Process.h"


+ 16
- 23
src/native/windows/juce_win32_Fonts.cpp View File

@@ -29,10 +29,7 @@
//==============================================================================
static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe,
NEWTEXTMETRICEXW*,
int type,
LPARAM lParam)
static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam)
{
if (lpelfe != 0 && (type & RASTER_FONTTYPE) == 0)
{
@@ -44,10 +41,7 @@ static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe,
return 1;
}
static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe,
NEWTEXTMETRICEXW*,
int type,
LPARAM lParam)
static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam)
{
if (lpelfe != 0 && (type & RASTER_FONTTYPE) == 0)
{
@@ -60,7 +54,7 @@ static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe,
lf.lfPitchAndFamily = FF_DONTCARE;
const String fontName (lpelfe->elfLogFont.lfFaceName);
fontName.copyToUTF16 (lf.lfFaceName, LF_FACESIZE - 1);
fontName.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
HDC dc = CreateCompatibleDC (0);
EnumFontFamiliesEx (dc, &lf,
@@ -85,7 +79,6 @@ const StringArray Font::findAllTypefaceNames()
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfPitchAndFamily = FF_DONTCARE;
lf.lfFaceName[0] = 0;
EnumFontFamiliesEx (dc, &lf,
(FONTENUMPROCW) &wfontEnum1,
@@ -154,18 +147,18 @@ public:
SetMapperFlags (dc, 0);
SetMapMode (dc, MM_TEXT);
LOGFONTW lfw = { 0 };
lfw.lfCharSet = DEFAULT_CHARSET;
lfw.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lfw.lfOutPrecision = OUT_OUTLINE_PRECIS;
lfw.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lfw.lfQuality = PROOF_QUALITY;
lfw.lfItalic = (BYTE) (italic ? TRUE : FALSE);
lfw.lfWeight = bold ? FW_BOLD : FW_NORMAL;
fontName.copyToUTF16 (lfw.lfFaceName, LF_FACESIZE - 1);
LOGFONTW lf = { 0 };
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lf.lfQuality = PROOF_QUALITY;
lf.lfItalic = (BYTE) (italic ? TRUE : FALSE);
lf.lfWeight = bold ? FW_BOLD : FW_NORMAL;
lf.lfHeight = size > 0 ? size : -256;
fontName.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
lfw.lfHeight = size > 0 ? size : -256;
HFONT standardSizedFont = CreateFontIndirect (&lfw);
HFONT standardSizedFont = CreateFontIndirect (&lf);
if (standardSizedFont != 0)
{
@@ -178,8 +171,8 @@ public:
OUTLINETEXTMETRIC otm;
if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0)
{
lfw.lfHeight = -(int) otm.otmEMSquare;
fontH = CreateFontIndirect (&lfw);
lf.lfHeight = -(int) otm.otmEMSquare;
fontH = CreateFontIndirect (&lf);
SelectObject (dc, fontH);
DeleteObject (standardSizedFont);


+ 1
- 0
src/text/juce_LocalisedStrings.cpp View File

@@ -28,6 +28,7 @@
BEGIN_JUCE_NAMESPACE
#include "juce_LocalisedStrings.h"
#include "../threads/juce_SpinLock.h"
//==============================================================================


+ 96
- 60
src/threads/juce_CriticalSection.h View File

@@ -26,10 +26,7 @@
#ifndef __JUCE_CRITICALSECTION_JUCEHEADER__
#define __JUCE_CRITICALSECTION_JUCEHEADER__
#ifndef DOXYGEN
class ScopedLock;
class ScopedUnlock;
#endif
#include "juce_ScopedLock.h"
//==============================================================================
@@ -40,7 +37,7 @@
one of these is by using RAII in the form of a local ScopedLock object - have a look
through the codebase for many examples of how to do this.
@see ScopedLock, SpinLock, Thread, InterProcessLock
@see ScopedLock, ScopedTryLock, ScopedUnlock, SpinLock, ReadWriteLock, Thread, InterProcessLock
*/
class JUCE_API CriticalSection
{
@@ -60,8 +57,9 @@ public:
If the lock is already held by the caller thread, the method returns immediately.
If the lock is currently held by another thread, this will wait until it becomes free.
Remember that it's highly recommended that you never use this method, but use a ScopedLock
to manage the locking instead.
It's strongly recommended that you never call this method directly - instead use the
ScopedLock class to manage the locking using an RAII pattern instead.
@see exit, tryEnter, ScopedLock
*/
@@ -91,11 +89,14 @@ public:
//==============================================================================
/** Provides the type of scoped lock to use with this type of critical section object. */
typedef ScopedLock ScopedLockType;
/** Provides the type of scoped lock to use with a CriticalSection. */
typedef GenericScopedLock <CriticalSection> ScopedLockType;
/** Provides the type of scoped unlocker to use with a CriticalSection. */
typedef GenericScopedUnlock <CriticalSection> ScopedUnlockType;
/** Provides the type of scoped unlocker to use with this type of critical section object. */
typedef ScopedUnlock ScopedUnlockType;
/** Provides the type of scoped try-locker to use with a CriticalSection. */
typedef GenericScopedTryLock <CriticalSection> ScopedTryLockType;
private:
@@ -151,68 +152,103 @@ private:
JUCE_DECLARE_NON_COPYABLE (DummyCriticalSection);
};
//==============================================================================
/**
A simple spin-lock class that can be used as a simple, low-overhead mutex for
uncontended situations.
Automatically locks and unlocks a CriticalSection object.
Note that unlike a CriticalSection, this type of lock is not re-entrant, and may
be less efficient when used it a highly contended situation, but it's very small and
requires almost no initialisation.
It's most appropriate for simple situations where you're only going to hold the
lock for a very brief time.
Use one of these as a local variable to provide RAII-based locking of a CriticalSection.
@see CriticalSection
*/
class JUCE_API SpinLock
{
public:
inline SpinLock() throw() {}
inline ~SpinLock() throw() {}
e.g. @code
void enter() const throw();
bool tryEnter() const throw();
CriticalSection myCriticalSection;
inline void exit() const throw()
for (;;)
{
jassert (lock.value == 1); // Agh! Releasing a lock that isn't currently held!
lock = 0;
const ScopedLock myScopedLock (myCriticalSection);
// myCriticalSection is now locked
...do some stuff...
// myCriticalSection gets unlocked here.
}
@endcode
//==============================================================================
/** A scoped-lock type to use with a SpinLock. */
class ScopedLockType
@see CriticalSection, ScopedUnlock
*/
typedef CriticalSection::ScopedLockType ScopedLock;
//==============================================================================
/**
Automatically unlocks and re-locks a CriticalSection object.
This is the reverse of a ScopedLock object - instead of locking the critical
section for the lifetime of this object, it unlocks it.
Make sure you don't try to unlock critical sections that aren't actually locked!
e.g. @code
CriticalSection myCriticalSection;
for (;;)
{
public:
inline explicit ScopedLockType (const SpinLock& lock_) throw() : lock (lock_) { lock_.enter(); }
inline ~ScopedLockType() throw() { lock.exit(); }
private:
//==============================================================================
const SpinLock& lock;
JUCE_DECLARE_NON_COPYABLE (ScopedLockType);
};
const ScopedLock myScopedLock (myCriticalSection);
// myCriticalSection is now locked
//==============================================================================
/** A scoped-unlocker type to use with a SpinLock. */
class ScopedUnlockType
... do some stuff with it locked ..
while (xyz)
{
... do some stuff with it locked ..
const ScopedUnlock unlocker (myCriticalSection);
// myCriticalSection is now unlocked for the remainder of this block,
// and re-locked at the end.
...do some stuff with it unlocked ...
}
// myCriticalSection gets unlocked here.
}
@endcode
@see CriticalSection, ScopedLock
*/
typedef CriticalSection::ScopedUnlockType ScopedUnlock;
//==============================================================================
/**
Automatically tries to lock and unlock a CriticalSection object.
Use one of these as a local variable to control access to a CriticalSection.
e.g. @code
CriticalSection myCriticalSection;
for (;;)
{
public:
inline explicit ScopedUnlockType (const SpinLock& lock_) throw() : lock (lock_) { lock_.exit(); }
inline ~ScopedUnlockType() throw() { lock.enter(); }
private:
//==============================================================================
const SpinLock& lock;
JUCE_DECLARE_NON_COPYABLE (ScopedUnlockType);
};
const ScopedTryLock myScopedTryLock (myCriticalSection);
// Unlike using a ScopedLock, this may fail to actually get the lock, so you
// should test this with the isLocked() method before doing your thread-unsafe
// action..
if (myScopedTryLock.isLocked())
{
...do some stuff...
}
else
{
..our attempt at locking failed because another thread had already locked it..
}
// myCriticalSection gets unlocked here (if it was locked)
}
@endcode
private:
//==============================================================================
mutable Atomic<int> lock;
JUCE_DECLARE_NON_COPYABLE (SpinLock);
};
@see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock
*/
typedef CriticalSection::ScopedTryLockType ScopedTryLock;
#endif // __JUCE_CRITICALSECTION_JUCEHEADER__

+ 0
- 1
src/threads/juce_ReadWriteLock.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_ReadWriteLock.h"
#include "juce_ScopedLock.h"
#include "juce_Thread.h"


+ 1
- 0
src/threads/juce_ReadWriteLock.h View File

@@ -27,6 +27,7 @@
#define __JUCE_READWRITELOCK_JUCEHEADER__
#include "juce_CriticalSection.h"
#include "juce_SpinLock.h"
#include "juce_WaitableEvent.h"
#include "juce_Thread.h"
#include "../containers/juce_Array.h"


+ 107
- 35
src/threads/juce_ScopedLock.h View File

@@ -26,22 +26,22 @@
#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__
#define __JUCE_SCOPEDLOCK_JUCEHEADER__
#include "juce_CriticalSection.h"
//==============================================================================
/**
Automatically locks and unlocks a CriticalSection object.
Automatically locks and unlocks a mutex object.
Use one of these as a local variable to control access to a CriticalSection.
Use one of these as a local variable to provide RAII-based locking of a mutex.
e.g. @code
The templated class could be a CriticalSection, SpinLock, or anything else that
provides enter() and exit() methods.
e.g. @code
CriticalSection myCriticalSection;
for (;;)
{
const ScopedLock myScopedLock (myCriticalSection);
const GenericScopedLock<CriticalSection> myScopedLock (myCriticalSection);
// myCriticalSection is now locked
...do some stuff...
@@ -50,50 +50,47 @@
}
@endcode
@see CriticalSection, ScopedUnlock
@see GenericScopedUnlock, CriticalSection, SpinLock, ScopedLock, ScopedUnlock
*/
class ScopedLock
template <class LockType>
class GenericScopedLock
{
public:
//==============================================================================
/** Creates a ScopedLock.
/** Creates a GenericScopedLock.
As soon as it is created, this will lock the CriticalSection, and
when the ScopedLock object is deleted, the CriticalSection will
be unlocked.
As soon as it is created, this will acquire the lock, and when the GenericScopedLock
object is deleted, the lock will be released.
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.
*/
inline explicit ScopedLock (const CriticalSection& lock) throw() : lock_ (lock) { lock.enter(); }
inline explicit GenericScopedLock (const LockType& lock) throw() : lock_ (lock) { lock.enter(); }
/** Destructor.
The CriticalSection will be unlocked when the destructor is called.
Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
The lock will be released when the destructor is called.
Make sure this object is created and deleted by the same thread, otherwise there are
no guarantees what will happen!
*/
inline ~ScopedLock() throw() { lock_.exit(); }
inline ~GenericScopedLock() throw() { lock_.exit(); }
private:
//==============================================================================
const CriticalSection& lock_;
const LockType& lock_;
JUCE_DECLARE_NON_COPYABLE (ScopedLock);
JUCE_DECLARE_NON_COPYABLE (GenericScopedLock);
};
//==============================================================================
/**
Automatically unlocks and re-locks a CriticalSection object.
Automatically unlocks and re-locks a mutex object.
This is the reverse of a ScopedLock object - instead of locking the critical
section for the lifetime of this object, it unlocks it.
This is the reverse of a GenericScopedLock object - instead of locking the mutex
for the lifetime of this object, it unlocks it.
Make sure you don't try to unlock critical sections that aren't actually locked!
Make sure you don't try to unlock mutexes that aren't actually locked!
e.g. @code
@@ -101,7 +98,7 @@ private:
for (;;)
{
const ScopedLock myScopedLock (myCriticalSection);
const GenericScopedLock<CriticalSection> myScopedLock (myCriticalSection);
// myCriticalSection is now locked
... do some stuff with it locked ..
@@ -110,7 +107,7 @@ private:
{
... do some stuff with it locked ..
const ScopedUnlock unlocker (myCriticalSection);
const GenericScopedUnlock<CriticalSection> unlocker (myCriticalSection);
// myCriticalSection is now unlocked for the remainder of this block,
// and re-locked at the end.
@@ -122,13 +119,14 @@ private:
}
@endcode
@see CriticalSection, ScopedLock
@see GenericScopedLock, CriticalSection, ScopedLock, ScopedUnlock
*/
class ScopedUnlock
template <class LockType>
class GenericScopedUnlock
{
public:
//==============================================================================
/** Creates a ScopedUnlock.
/** Creates a GenericScopedUnlock.
As soon as it is created, this will unlock the CriticalSection, and
when the ScopedLock object is deleted, the CriticalSection will
@@ -138,7 +136,7 @@ public:
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.
*/
inline explicit ScopedUnlock (const CriticalSection& lock) throw() : lock_ (lock) { lock.exit(); }
inline explicit GenericScopedUnlock (const LockType& lock) throw() : lock_ (lock) { lock.exit(); }
/** Destructor.
@@ -147,16 +145,90 @@ public:
Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
inline ~ScopedUnlock() throw() { lock_.enter(); }
inline ~GenericScopedUnlock() throw() { lock_.enter(); }
private:
//==============================================================================
const CriticalSection& lock_;
const LockType& lock_;
JUCE_DECLARE_NON_COPYABLE (ScopedUnlock);
JUCE_DECLARE_NON_COPYABLE (GenericScopedUnlock);
};
//==============================================================================
/**
Automatically locks and unlocks a mutex object.
Use one of these as a local variable to provide RAII-based locking of a mutex.
The templated class could be a CriticalSection, SpinLock, or anything else that
provides enter() and exit() methods.
e.g. @code
CriticalSection myCriticalSection;
for (;;)
{
const GenericScopedTryLock<CriticalSection> myScopedTryLock (myCriticalSection);
// Unlike using a ScopedLock, this may fail to actually get the lock, so you
// should test this with the isLocked() method before doing your thread-unsafe
// action..
if (myScopedTryLock.isLocked())
{
...do some stuff...
}
else
{
..our attempt at locking failed because another thread had already locked it..
}
// myCriticalSection gets unlocked here (if it was locked)
}
@endcode
@see CriticalSection::tryEnter, GenericScopedLock, GenericScopedUnlock
*/
template <class LockType>
class GenericScopedTryLock
{
public:
//==============================================================================
/** 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).
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.
*/
inline explicit GenericScopedTryLock (const LockType& lock) throw()
: lock_ (lock), lockWasSuccessful (lock.tryEnter()) {}
/** Destructor.
The mutex will be unlocked (if it had been successfully locked) when the
destructor is called.
Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
inline ~GenericScopedTryLock() throw() { if (lockWasSuccessful) lock_.exit(); }
/** Returns true if the mutex was successfully locked. */
bool isLocked() const throw() { return lockWasSuccessful; }
private:
//==============================================================================
const LockType& lock_;
const bool lockWasSuccessful;
JUCE_DECLARE_NON_COPYABLE (GenericScopedTryLock);
};
#endif // __JUCE_SCOPEDLOCK_JUCEHEADER__

+ 0
- 101
src/threads/juce_ScopedTryLock.h View File

@@ -1,101 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
#define __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
#include "juce_CriticalSection.h"
//==============================================================================
/**
Automatically tries to lock and unlock a CriticalSection object.
Use one of these as a local variable to control access to a CriticalSection.
e.g. @code
CriticalSection myCriticalSection;
for (;;)
{
const ScopedTryLock myScopedTryLock (myCriticalSection);
// Unlike using a ScopedLock, this may fail to actually get the lock, so you
// should test this with the isLocked() method before doing your thread-unsafe
// action..
if (myScopedTryLock.isLocked())
{
...do some stuff...
}
else
{
..our attempt at locking failed because another thread had already locked it..
}
// myCriticalSection gets unlocked here (if it was locked)
}
@endcode
@see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock
*/
class JUCE_API ScopedTryLock
{
public:
//==============================================================================
/** Creates a ScopedTryLock.
As soon as it is created, this will try to lock the CriticalSection, and
when the ScopedTryLock object is deleted, the CriticalSection will
be unlocked if the lock was successful.
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.
*/
inline explicit ScopedTryLock (const CriticalSection& lock) throw() : lock_ (lock), lockWasSuccessful (lock.tryEnter()) {}
/** Destructor.
The CriticalSection will be unlocked (if locked) when the destructor is called.
Make sure this object is created and deleted by the same thread,
otherwise there are no guarantees what will happen!
*/
inline ~ScopedTryLock() throw() { if (lockWasSuccessful) lock_.exit(); }
/** Returns true if the CriticalSection was successfully locked. */
bool isLocked() const throw() { return lockWasSuccessful; }
private:
//==============================================================================
const CriticalSection& lock_;
const bool lockWasSuccessful;
JUCE_DECLARE_NON_COPYABLE (ScopedTryLock);
};
#endif // __JUCE_SCOPEDTRYLOCK_JUCEHEADER__

+ 87
- 0
src/threads/juce_SpinLock.h View File

@@ -0,0 +1,87 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_SPINLOCK_JUCEHEADER__
#define __JUCE_SPINLOCK_JUCEHEADER__
#include "juce_ScopedLock.h"
//==============================================================================
/**
A simple spin-lock class that can be used as a simple, low-overhead mutex for
uncontended situations.
Note that unlike a CriticalSection, this type of lock is not re-entrant, and may
be less efficient when used it a highly contended situation, but it's very small and
requires almost no initialisation.
It's most appropriate for simple situations where you're only going to hold the
lock for a very brief time.
@see CriticalSection
*/
class JUCE_API SpinLock
{
public:
inline SpinLock() throw() {}
inline ~SpinLock() throw() {}
/** Acquires the lock.
This will block until the lock has been successfully acquired by this thread.
Note that a SpinLock is NOT re-entrant, and is not smart enough to know whether the
caller thread already has the lock - so if a thread tries to acquire a lock that it
already holds, this method will never return!
It's strongly recommended that you never call this method directly - instead use the
ScopedLockType class to manage the locking using an RAII pattern instead.
*/
void enter() const throw();
/** Attempts to acquire the lock, returning true if this was successful. */
bool tryEnter() const throw();
/** Releases the lock. */
inline void exit() const throw()
{
jassert (lock.value == 1); // Agh! Releasing a lock that isn't currently held!
lock = 0;
}
//==============================================================================
/** Provides the type of scoped lock to use for locking a SpinLock. */
typedef GenericScopedLock <SpinLock> ScopedLockType;
/** Provides the type of scoped unlocker to use with a SpinLock. */
typedef GenericScopedUnlock <SpinLock> ScopedUnlockType;
private:
//==============================================================================
mutable Atomic<int> lock;
JUCE_DECLARE_NON_COPYABLE (SpinLock);
};
#endif // __JUCE_SPINLOCK_JUCEHEADER__

+ 1
- 1
src/threads/juce_Thread.cpp View File

@@ -28,7 +28,7 @@
BEGIN_JUCE_NAMESPACE
#include "juce_Thread.h"
#include "juce_ScopedLock.h"
#include "juce_SpinLock.h"
#include "../core/juce_Time.h"


+ 0
- 1
src/threads/juce_ThreadPool.h View File

@@ -27,7 +27,6 @@
#define __JUCE_THREADPOOL_JUCEHEADER__
#include "juce_Thread.h"
#include "juce_ScopedLock.h"
#include "../text/juce_StringArray.h"
#include "../containers/juce_Array.h"
#include "../containers/juce_OwnedArray.h"


+ 0
- 1
src/threads/juce_TimeSliceThread.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_TimeSliceThread.h"
#include "juce_ScopedLock.h"
//==============================================================================


+ 1
- 1
src/utilities/juce_DeletedAtShutdown.cpp View File

@@ -29,8 +29,8 @@ BEGIN_JUCE_NAMESPACE
#include "juce_DeletedAtShutdown.h"
#include "../containers/juce_Array.h"
#include "../threads/juce_ScopedLock.h"
#include "../application/juce_Application.h"
#include "../threads/juce_SpinLock.h"
//==============================================================================


+ 0
- 1
src/utilities/juce_PropertiesFile.cpp View File

@@ -38,7 +38,6 @@ BEGIN_JUCE_NAMESPACE
#include "../memory/juce_ScopedPointer.h"
#include "../core/juce_SystemStats.h"
#include "../threads/juce_InterProcessLock.h"
#include "../threads/juce_ScopedLock.h"
#include "../text/juce_XmlDocument.h"


+ 0
- 1
src/utilities/juce_UnitTest.cpp View File

@@ -28,7 +28,6 @@
BEGIN_JUCE_NAMESPACE
#include "juce_UnitTest.h"
#include "../threads/juce_ScopedLock.h"
//==============================================================================


Loading…
Cancel
Save