Browse Source

Added an optional InterprocessLock to PropertiesFile

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
6bb4cbfb59
5 changed files with 73 additions and 16 deletions
  1. +4
    -0
      extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp
  2. +22
    -6
      juce_amalgamated.cpp
  3. +8
    -2
      juce_amalgamated.h
  4. +24
    -6
      src/utilities/juce_PropertiesFile.cpp
  5. +15
    -2
      src/utilities/juce_PropertiesFile.h

+ 4
- 0
extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp View File

@@ -701,6 +701,10 @@ private:
{ {
mouseDownCompUID = underMouse->getComponentUID(); mouseDownCompUID = underMouse->getComponentUID();
mouseDownResult = canvas.getSelection().addToSelectionOnMouseDown (mouseDownCompUID, e.mods); mouseDownResult = canvas.getSelection().addToSelectionOnMouseDown (mouseDownCompUID, e.mods);
updateSelectedComponentResizeFrames();
hideSizeGuides();
showSizeGuides();
} }
} }
} }


+ 22
- 6
juce_amalgamated.cpp View File

@@ -17620,19 +17620,23 @@ namespace PropertyFileConstants
static const char* const valueAttribute = "val"; static const char* const valueAttribute = "val";
} }


PropertiesFile::PropertiesFile (const File& f, const int millisecondsBeforeSaving, const int options_)
PropertiesFile::PropertiesFile (const File& f, const int millisecondsBeforeSaving,
const int options_, InterProcessLock* const processLock_)
: PropertySet (ignoreCaseOfKeyNames), : PropertySet (ignoreCaseOfKeyNames),
file (f), file (f),
timerInterval (millisecondsBeforeSaving), timerInterval (millisecondsBeforeSaving),
options (options_), options (options_),
loadedOk (false), loadedOk (false),
needsWriting (false)
needsWriting (false),
processLock (processLock_)
{ {
// You need to correctly specify just one storage format for the file // You need to correctly specify just one storage format for the file
jassert ((options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsBinary jassert ((options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsBinary
|| (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsCompressedBinary || (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsCompressedBinary
|| (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsXML); || (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsXML);


ProcessScopedLock pl (getProcessLock());

ScopedPointer<InputStream> fileStream (f.createInputStream()); ScopedPointer<InputStream> fileStream (f.createInputStream());


if (fileStream != 0) if (fileStream != 0)
@@ -17693,8 +17697,10 @@ PropertiesFile::PropertiesFile (const File& f, const int millisecondsBeforeSavin
} }
else else
{ {
// must be a pretty broken XML file we're trying to parse here!
jassertfalse
// must be a pretty broken XML file we're trying to parse here,
// or a sign that this object needs an InterProcessLock,
// or just a failure reading the file. This last reason is why
// we don't jassertfalse here.
} }
} }
} }
@@ -17711,6 +17717,11 @@ PropertiesFile::~PropertiesFile()
jassertfalse; jassertfalse;
} }


PropertiesFile::ProcessScopedLock PropertiesFile::getProcessLock() const
{
return ProcessScopedLock (processLock != 0 ? new InterProcessLock::ScopedLockType (*processLock) : 0);
}

bool PropertiesFile::saveIfNeeded() bool PropertiesFile::saveIfNeeded()
{ {
const ScopedLock sl (getLock()); const ScopedLock sl (getLock());
@@ -17760,6 +17771,8 @@ bool PropertiesFile::save()
getAllProperties().getAllValues() [i]); getAllProperties().getAllValues() [i]);
} }


ProcessScopedLock pl (getProcessLock());

if (doc.writeToFile (file, String::empty)) if (doc.writeToFile (file, String::empty))
{ {
needsWriting = false; needsWriting = false;
@@ -17768,6 +17781,8 @@ bool PropertiesFile::save()
} }
else else
{ {
ProcessScopedLock pl (getProcessLock());

TemporaryFile tempFile (file); TemporaryFile tempFile (file);
ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream()); ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream());


@@ -17871,7 +17886,8 @@ PropertiesFile* PropertiesFile::createDefaultAppPropertiesFile (const String& ap
const String& folderName, const String& folderName,
const bool commonToAllUsers, const bool commonToAllUsers,
const int millisecondsBeforeSaving, const int millisecondsBeforeSaving,
const int propertiesFileOptions)
const int propertiesFileOptions,
InterProcessLock *processLock_)
{ {
const File file (getDefaultAppSettingsFile (applicationName, const File file (getDefaultAppSettingsFile (applicationName,
fileNameSuffix, fileNameSuffix,
@@ -17883,7 +17899,7 @@ PropertiesFile* PropertiesFile::createDefaultAppPropertiesFile (const String& ap
if (file == File::nonexistent) if (file == File::nonexistent)
return 0; return 0;


return new PropertiesFile (file, millisecondsBeforeSaving, propertiesFileOptions);
return new PropertiesFile (file, millisecondsBeforeSaving, propertiesFileOptions,processLock_);
} }


END_JUCE_NAMESPACE END_JUCE_NAMESPACE


+ 8
- 2
juce_amalgamated.h View File

@@ -13457,7 +13457,8 @@ public:


PropertiesFile (const File& file, PropertiesFile (const File& file,
int millisecondsBeforeSaving, int millisecondsBeforeSaving,
int optionFlags);
int optionFlags,
InterProcessLock* processLock = 0);


~PropertiesFile(); ~PropertiesFile();


@@ -13478,7 +13479,8 @@ public:
const String& folderName, const String& folderName,
bool commonToAllUsers, bool commonToAllUsers,
int millisecondsBeforeSaving, int millisecondsBeforeSaving,
int propertiesFileOptions);
int propertiesFileOptions,
InterProcessLock *ipl = NULL);


static const File getDefaultAppSettingsFile (const String& applicationName, static const File getDefaultAppSettingsFile (const String& applicationName,
const String& fileNameSuffix, const String& fileNameSuffix,
@@ -13497,6 +13499,10 @@ private:
const int options; const int options;
bool loadedOk, needsWriting; bool loadedOk, needsWriting;


InterProcessLock* processLock;
typedef ScopedPointer<InterProcessLock::ScopedLockType> ProcessScopedLock;
ProcessScopedLock getProcessLock() const;

void timerCallback(); void timerCallback();


PropertiesFile (const PropertiesFile&); PropertiesFile (const PropertiesFile&);


+ 24
- 6
src/utilities/juce_PropertiesFile.cpp View File

@@ -35,7 +35,9 @@ BEGIN_JUCE_NAMESPACE
#include "../io/streams/juce_SubregionStream.h" #include "../io/streams/juce_SubregionStream.h"
#include "../io/streams/juce_GZIPDecompressorInputStream.h" #include "../io/streams/juce_GZIPDecompressorInputStream.h"
#include "../io/streams/juce_GZIPCompressorOutputStream.h" #include "../io/streams/juce_GZIPCompressorOutputStream.h"
#include "../containers/juce_ScopedPointer.h"
#include "../core/juce_SystemStats.h" #include "../core/juce_SystemStats.h"
#include "../threads/juce_InterProcessLock.h"
#include "../text/juce_XmlDocument.h" #include "../text/juce_XmlDocument.h"
@@ -52,19 +54,23 @@ namespace PropertyFileConstants
} }
//============================================================================== //==============================================================================
PropertiesFile::PropertiesFile (const File& f, const int millisecondsBeforeSaving, const int options_)
PropertiesFile::PropertiesFile (const File& f, const int millisecondsBeforeSaving,
const int options_, InterProcessLock* const processLock_)
: PropertySet (ignoreCaseOfKeyNames), : PropertySet (ignoreCaseOfKeyNames),
file (f), file (f),
timerInterval (millisecondsBeforeSaving), timerInterval (millisecondsBeforeSaving),
options (options_), options (options_),
loadedOk (false), loadedOk (false),
needsWriting (false)
needsWriting (false),
processLock (processLock_)
{ {
// You need to correctly specify just one storage format for the file // You need to correctly specify just one storage format for the file
jassert ((options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsBinary jassert ((options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsBinary
|| (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsCompressedBinary || (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsCompressedBinary
|| (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsXML); || (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsXML);
ProcessScopedLock pl (getProcessLock());
ScopedPointer<InputStream> fileStream (f.createInputStream()); ScopedPointer<InputStream> fileStream (f.createInputStream());
if (fileStream != 0) if (fileStream != 0)
@@ -125,8 +131,10 @@ PropertiesFile::PropertiesFile (const File& f, const int millisecondsBeforeSavin
} }
else else
{ {
// must be a pretty broken XML file we're trying to parse here!
jassertfalse
// must be a pretty broken XML file we're trying to parse here,
// or a sign that this object needs an InterProcessLock,
// or just a failure reading the file. This last reason is why
// we don't jassertfalse here.
} }
} }
} }
@@ -143,6 +151,11 @@ PropertiesFile::~PropertiesFile()
jassertfalse; jassertfalse;
} }
PropertiesFile::ProcessScopedLock PropertiesFile::getProcessLock() const
{
return ProcessScopedLock (processLock != 0 ? new InterProcessLock::ScopedLockType (*processLock) : 0);
}
bool PropertiesFile::saveIfNeeded() bool PropertiesFile::saveIfNeeded()
{ {
const ScopedLock sl (getLock()); const ScopedLock sl (getLock());
@@ -192,6 +205,8 @@ bool PropertiesFile::save()
getAllProperties().getAllValues() [i]); getAllProperties().getAllValues() [i]);
} }
ProcessScopedLock pl (getProcessLock());
if (doc.writeToFile (file, String::empty)) if (doc.writeToFile (file, String::empty))
{ {
needsWriting = false; needsWriting = false;
@@ -200,6 +215,8 @@ bool PropertiesFile::save()
} }
else else
{ {
ProcessScopedLock pl (getProcessLock());
TemporaryFile tempFile (file); TemporaryFile tempFile (file);
ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream()); ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream());
@@ -304,7 +321,8 @@ PropertiesFile* PropertiesFile::createDefaultAppPropertiesFile (const String& ap
const String& folderName, const String& folderName,
const bool commonToAllUsers, const bool commonToAllUsers,
const int millisecondsBeforeSaving, const int millisecondsBeforeSaving,
const int propertiesFileOptions)
const int propertiesFileOptions,
InterProcessLock *processLock_)
{ {
const File file (getDefaultAppSettingsFile (applicationName, const File file (getDefaultAppSettingsFile (applicationName,
fileNameSuffix, fileNameSuffix,
@@ -316,7 +334,7 @@ PropertiesFile* PropertiesFile::createDefaultAppPropertiesFile (const String& ap
if (file == File::nonexistent) if (file == File::nonexistent)
return 0; return 0;
return new PropertiesFile (file, millisecondsBeforeSaving, propertiesFileOptions);
return new PropertiesFile (file, millisecondsBeforeSaving, propertiesFileOptions,processLock_);
} }


+ 15
- 2
src/utilities/juce_PropertiesFile.h View File

@@ -30,6 +30,7 @@
#include "../containers/juce_PropertySet.h" #include "../containers/juce_PropertySet.h"
#include "../events/juce_Timer.h" #include "../events/juce_Timer.h"
#include "../events/juce_ChangeBroadcaster.h" #include "../events/juce_ChangeBroadcaster.h"
#include "../threads/juce_InterProcessLock.h"
//============================================================================== //==============================================================================
@@ -76,10 +77,17 @@ public:
@param optionFlags a combination of the flags in the FileFormatOptions @param optionFlags a combination of the flags in the FileFormatOptions
enum, which specify the type of file to save, and other enum, which specify the type of file to save, and other
options. options.
@param processLock an optional InterprocessLock object that will be used to
prevent multiple threads or processes from writing to the file
at the same time. The PropertiesFile will keep a pointer to
this object but will not take ownership of it - the caller is
responsible for making sure that the lock doesn't get deleted
before the PropertiesFile has been deleted.
*/ */
PropertiesFile (const File& file, PropertiesFile (const File& file,
int millisecondsBeforeSaving, int millisecondsBeforeSaving,
int optionFlags);
int optionFlags,
InterProcessLock* processLock = 0);
/** Destructor. /** Destructor.
@@ -146,7 +154,8 @@ public:
const String& folderName, const String& folderName,
bool commonToAllUsers, bool commonToAllUsers,
int millisecondsBeforeSaving, int millisecondsBeforeSaving,
int propertiesFileOptions);
int propertiesFileOptions,
InterProcessLock *ipl = NULL);
/** Handy utility to choose a file in the standard OS-dependent location for application /** Handy utility to choose a file in the standard OS-dependent location for application
settings files. settings files.
@@ -187,6 +196,10 @@ private:
const int options; const int options;
bool loadedOk, needsWriting; bool loadedOk, needsWriting;
InterProcessLock* processLock;
typedef ScopedPointer<InterProcessLock::ScopedLockType> ProcessScopedLock;
ProcessScopedLock getProcessLock() const;
void timerCallback(); void timerCallback();
PropertiesFile (const PropertiesFile&); PropertiesFile (const PropertiesFile&);


Loading…
Cancel
Save