Browse Source

tags/2021-05-28
jules 17 years ago
parent
commit
ff3c2e9fce
9 changed files with 520 additions and 770 deletions
  1. +19
    -1
      build/linux/JUCE.make
  2. +11
    -171
      build/linux/platform_specific_code/juce_linux_Files.cpp
  3. +6
    -216
      build/linux/platform_specific_code/juce_linux_Threads.cpp
  4. +10
    -191
      build/macosx/platform_specific_code/juce_mac_Files.cpp
  5. +4
    -188
      build/macosx/platform_specific_code/juce_mac_Threads.cpp
  6. +466
    -0
      build/macosx/platform_specific_code/juce_posix_SharedCode.cpp
  7. +2
    -1
      docs/JUCE changelist.txt
  8. +1
    -1
      extras/juce demo/src/ApplicationStartup.cpp
  9. +1
    -1
      src/juce_appframework/audio/plugins/juce_PluginDescription.cpp

+ 19
- 1
build/linux/JUCE.make View File

@@ -26,7 +26,7 @@ ifeq ($(CONFIG),Release)
OBJDIR := ../../bin/intermediate_linux/Release OBJDIR := ../../bin/intermediate_linux/Release
OUTDIR := ../../bin OUTDIR := ../../bin
CPPFLAGS := -MMD -D "LINUX=1" -D "NDEBUG=1" -I "../../" -I "/usr/include" -I "/usr/include/freetype2" CPPFLAGS := -MMD -D "LINUX=1" -D "NDEBUG=1" -I "../../" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O2 -Wall
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O2 -O2 -Wall -fvisibility=hidden
CXXFLAGS := $(CFLAGS) CXXFLAGS := $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -s LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -s
LDDEPS := LDDEPS :=
@@ -60,6 +60,7 @@ OBJECTS := \
$(OBJDIR)/juce_Socket.o \ $(OBJDIR)/juce_Socket.o \
$(OBJDIR)/juce_URL.o \ $(OBJDIR)/juce_URL.o \
$(OBJDIR)/juce_BufferedInputStream.o \ $(OBJDIR)/juce_BufferedInputStream.o \
$(OBJDIR)/juce_FileInputSource.o \
$(OBJDIR)/juce_GZIPCompressorOutputStream.o \ $(OBJDIR)/juce_GZIPCompressorOutputStream.o \
$(OBJDIR)/juce_GZIPDecompressorInputStream.o \ $(OBJDIR)/juce_GZIPDecompressorInputStream.o \
$(OBJDIR)/juce_MemoryInputStream.o \ $(OBJDIR)/juce_MemoryInputStream.o \
@@ -126,6 +127,8 @@ OBJECTS := \
$(OBJDIR)/juce_AudioFormat.o \ $(OBJDIR)/juce_AudioFormat.o \
$(OBJDIR)/juce_AudioFormatManager.o \ $(OBJDIR)/juce_AudioFormatManager.o \
$(OBJDIR)/juce_AudioSubsectionReader.o \ $(OBJDIR)/juce_AudioSubsectionReader.o \
$(OBJDIR)/juce_AudioThumbnail.o \
$(OBJDIR)/juce_AudioThumbnailCache.o \
$(OBJDIR)/juce_FlacAudioFormat.o \ $(OBJDIR)/juce_FlacAudioFormat.o \
$(OBJDIR)/juce_OggVorbisAudioFormat.o \ $(OBJDIR)/juce_OggVorbisAudioFormat.o \
$(OBJDIR)/juce_WavAudioFormat.o \ $(OBJDIR)/juce_WavAudioFormat.o \
@@ -568,6 +571,11 @@ $(OBJDIR)/juce_BufferedInputStream.o: ../../src/juce_core/io/streams/juce_Buffer
@echo $(notdir $<) @echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $< @$(CXX) $(CXXFLAGS) -o $@ -c $<


$(OBJDIR)/juce_FileInputSource.o: ../../src/juce_core/io/streams/juce_FileInputSource.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/juce_GZIPCompressorOutputStream.o: ../../src/juce_core/io/streams/juce_GZIPCompressorOutputStream.cpp $(OBJDIR)/juce_GZIPCompressorOutputStream.o: ../../src/juce_core/io/streams/juce_GZIPCompressorOutputStream.cpp
-@$(CMD_MKOBJDIR) -@$(CMD_MKOBJDIR)
@echo $(notdir $<) @echo $(notdir $<)
@@ -898,6 +906,16 @@ $(OBJDIR)/juce_AudioSubsectionReader.o: ../../src/juce_appframework/audio/audio_
@echo $(notdir $<) @echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $< @$(CXX) $(CXXFLAGS) -o $@ -c $<


$(OBJDIR)/juce_AudioThumbnail.o: ../../src/juce_appframework/audio/audio_file_formats/juce_AudioThumbnail.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/juce_AudioThumbnailCache.o: ../../src/juce_appframework/audio/audio_file_formats/juce_AudioThumbnailCache.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/juce_FlacAudioFormat.o: ../../src/juce_appframework/audio/audio_file_formats/juce_FlacAudioFormat.cpp $(OBJDIR)/juce_FlacAudioFormat.o: ../../src/juce_appframework/audio/audio_file_formats/juce_FlacAudioFormat.cpp
-@$(CMD_MKOBJDIR) -@$(CMD_MKOBJDIR)
@echo $(notdir $<) @echo $(notdir $<)


+ 11
- 171
build/linux/platform_specific_code/juce_linux_Files.cpp View File

@@ -57,48 +57,22 @@ BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/basics/juce_Time.h" #include "../../../src/juce_core/basics/juce_Time.h"
#include "../../../src/juce_core/io/network/juce_URL.h" #include "../../../src/juce_core/io/network/juce_URL.h"
#include "../../../src/juce_core/io/files/juce_NamedPipe.h" #include "../../../src/juce_core/io/files/juce_NamedPipe.h"
static File executableFile;
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
//============================================================================== //==============================================================================
bool juce_isDirectory (const String& fileName) throw()
{
if (fileName.isEmpty())
return true;
struct stat info;
const int res = stat (fileName.toUTF8(), &info);
if (res == 0)
return (info.st_mode & S_IFDIR) != 0;
return false;
}
bool juce_fileExists (const String& fileName, const bool dontCountDirectories) throw()
{
if (fileName.isEmpty())
return false;
bool exists = access (fileName.toUTF8(), F_OK) == 0;
if (exists && dontCountDirectories && juce_isDirectory (fileName))
exists = false;
/*
Note that a lot of methods that you'd expect to find in this file actually
live in juce_posix_SharedCode.cpp!
*/
#include "../../macosx/platform_specific_code/juce_posix_SharedCode.cpp"
return exists;
}
int64 juce_getFileSize (const String& fileName) throw()
{
struct stat info;
const int res = stat (fileName.toUTF8(), &info);
if (res == 0)
return info.st_size;
//==============================================================================
static File executableFile;
return 0;
}
//==============================================================================
void juce_getFileTimes (const String& fileName, void juce_getFileTimes (const String& fileName,
int64& modificationTime, int64& modificationTime,
int64& accessTime, int64& accessTime,
@@ -112,10 +86,6 @@ void juce_getFileTimes (const String& fileName,
const int res = stat (fileName.toUTF8(), &info); const int res = stat (fileName.toUTF8(), &info);
if (res == 0) if (res == 0)
{ {
/*
* Note: On Linux the st_ctime field is defined as last change time
* rather than creation.
*/
modificationTime = (int64) info.st_mtime * 1000; modificationTime = (int64) info.st_mtime * 1000;
accessTime = (int64) info.st_atime * 1000; accessTime = (int64) info.st_atime * 1000;
creationTime = (int64) info.st_ctime * 1000; creationTime = (int64) info.st_ctime * 1000;
@@ -134,11 +104,6 @@ bool juce_setFileTimes (const String& fileName,
return utime (fileName.toUTF8(), &times) == 0; return utime (fileName.toUTF8(), &times) == 0;
} }
bool juce_canWriteToFile (const String& fileName) throw()
{
return access (fileName.toUTF8(), W_OK) == 0;
}
bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw() bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw()
{ {
struct stat info; struct stat info;
@@ -157,14 +122,6 @@ bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw()
return chmod (fileName.toUTF8(), info.st_mode) == 0; return chmod (fileName.toUTF8(), info.st_mode) == 0;
} }
bool juce_deleteFile (const String& fileName) throw()
{
if (juce_isDirectory (fileName))
return rmdir (fileName.toUTF8()) == 0;
else
return remove (fileName.toUTF8()) == 0;
}
bool juce_copyFile (const String& s, const String& d) throw() bool juce_copyFile (const String& s, const String& d) throw()
{ {
const File source (s), dest (d); const File source (s), dest (d);
@@ -196,97 +153,6 @@ bool juce_copyFile (const String& s, const String& d) throw()
return ok; return ok;
} }
bool juce_moveFile (const String& source, const String& dest) throw()
{
if (rename (source.toUTF8(), dest.toUTF8()) == 0)
return true;
if (! juce_canWriteToFile (source))
return false;
if (juce_copyFile (source, dest))
{
if (juce_deleteFile (source))
return true;
juce_deleteFile (dest);
}
return false;
}
void juce_createDirectory (const String& fileName) throw()
{
mkdir (fileName.toUTF8(), 0777);
}
void* juce_fileOpen (const String& fileName, bool forWriting) throw()
{
const char* mode = "rb";
if (forWriting)
{
if (juce_fileExists (fileName, false))
{
FILE* f = fopen (fileName.toUTF8(), "r+b");
if (f != 0)
fseek (f, 0, SEEK_END);
return (void*) f;
}
else
{
mode = "w+b";
}
}
return (void*)fopen (fileName.toUTF8(), mode);
}
void juce_fileClose (void* handle) throw()
{
if (handle != 0)
fclose ((FILE*) handle);
}
int juce_fileRead (void* handle, void* buffer, int size) throw()
{
if (handle != 0)
return fread (buffer, 1, size, (FILE*) handle);
return 0;
}
int juce_fileWrite (void* handle, const void* buffer, int size) throw()
{
if (handle != 0)
return fwrite (buffer, 1, size, (FILE*) handle);
return 0;
}
int64 juce_fileSetPosition (void* handle, int64 pos) throw()
{
if (handle != 0 && fseek ((FILE*) handle, (long) pos, SEEK_SET) == 0)
return pos;
return -1;
}
int64 juce_fileGetPosition (void* handle) throw()
{
if (handle != 0)
return ftell ((FILE*) handle);
else
return -1;
}
void juce_fileFlush (void* handle) throw()
{
if (handle != 0)
fflush ((FILE*) handle);
}
const StringArray juce_getFileSystemRoots() throw() const StringArray juce_getFileSystemRoots() throw()
{ {
StringArray s; StringArray s;
@@ -294,28 +160,7 @@ const StringArray juce_getFileSystemRoots() throw()
return s; return s;
} }
const String juce_getVolumeLabel (const String& filenameOnVolume,
int& volumeSerialNumber) throw()
{
// There is no equivalent on Linux
volumeSerialNumber = 0;
return String::empty;
}
int64 File::getBytesFreeOnVolume() const throw()
{
struct statfs buf;
int64 free_space = 0;
if (statfs (getFullPathName().toUTF8(), &buf) == 0)
{
// Note: this returns space available to non-super user
free_space = (int64) buf.f_bsize * (int64) buf.f_bavail;
}
return free_space;
}
//==============================================================================
bool File::isOnCDRomDrive() const throw() bool File::isOnCDRomDrive() const throw()
{ {
struct statfs buf; struct statfs buf;
@@ -353,7 +198,6 @@ bool File::isOnHardDisk() const throw()
return true; return true;
} }
//============================================================================== //==============================================================================
const File File::getSpecialLocation (const SpecialLocationType type) const File File::getSpecialLocation (const SpecialLocationType type)
{ {
@@ -439,10 +283,6 @@ bool File::setAsCurrentWorkingDirectory() const throw()
return chdir (getFullPathName().toUTF8()) == 0; return chdir (getFullPathName().toUTF8()) == 0;
} }
//==============================================================================
const tchar File::separator = T('/');
const tchar* File::separatorString = T("/");
//============================================================================== //==============================================================================
struct FindFileStruct struct FindFileStruct
{ {


+ 6
- 216
build/linux/platform_specific_code/juce_linux_Threads.cpp View File

@@ -40,12 +40,17 @@ BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/threads/juce_CriticalSection.h" #include "../../../src/juce_core/threads/juce_CriticalSection.h"
#include "../../../src/juce_core/threads/juce_WaitableEvent.h" #include "../../../src/juce_core/threads/juce_WaitableEvent.h"
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
#include "../../../src/juce_core/threads/juce_Thread.h" #include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/threads/juce_Process.h" #include "../../../src/juce_core/threads/juce_Process.h"
#include "../../../src/juce_core/io/files/juce_File.h" #include "../../../src/juce_core/io/files/juce_File.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h" #include "../../../src/juce_core/basics/juce_SystemStats.h"
//==============================================================================
/*
Note that a lot of methods that you'd expect to find in this file actually
live in juce_posix_SharedCode.cpp!
*/
#ifndef CPU_ISSET #ifndef CPU_ISSET
#undef SUPPORT_AFFINITIES #undef SUPPORT_AFFINITIES
#endif #endif
@@ -169,143 +174,6 @@ void Thread::yield() throw()
sched_yield(); sched_yield();
} }
void JUCE_CALLTYPE Thread::sleep (int millisecs) throw()
{
struct timespec time;
time.tv_sec = millisecs / 1000;
time.tv_nsec = (millisecs % 1000) * 1000000;
nanosleep (&time, 0);
}
//==============================================================================
CriticalSection::CriticalSection() throw()
{
pthread_mutexattr_t atts;
pthread_mutexattr_init (&atts);
pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&internal, &atts);
}
CriticalSection::~CriticalSection() throw()
{
pthread_mutex_destroy (&internal);
}
void CriticalSection::enter() const throw()
{
pthread_mutex_lock (&internal);
}
bool CriticalSection::tryEnter() const throw()
{
return pthread_mutex_trylock (&internal) == 0;
}
void CriticalSection::exit() const throw()
{
pthread_mutex_unlock (&internal);
}
//==============================================================================
struct EventStruct
{
pthread_cond_t condition;
pthread_mutex_t mutex;
bool triggered;
};
WaitableEvent::WaitableEvent() throw()
{
EventStruct* const es = new EventStruct();
es->triggered = false;
pthread_cond_init (&es->condition, 0);
pthread_mutex_init (&es->mutex, 0);
internal = es;
}
WaitableEvent::~WaitableEvent() throw()
{
EventStruct* const es = (EventStruct*)internal;
pthread_cond_destroy (&es->condition);
pthread_mutex_destroy (&es->mutex);
delete es;
}
bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
{
EventStruct* const es = (EventStruct*)internal;
bool ok = true;
pthread_mutex_lock (&es->mutex);
if (! es->triggered)
{
if (timeOutMillisecs < 0)
{
pthread_cond_wait (&es->condition, &es->mutex);
}
else
{
struct timespec time;
struct timeval t;
int timeout = 0;
gettimeofday (&t, 0);
time.tv_sec = t.tv_sec + (timeOutMillisecs / 1000);
time.tv_nsec = (t.tv_usec + ((timeOutMillisecs % 1000) * 1000)) * 1000;
while (time.tv_nsec >= 1000000000)
{
time.tv_nsec -= 1000000000;
time.tv_sec++;
}
while (! timeout)
{
timeout = pthread_cond_timedwait (&es->condition, &es->mutex, &time);
if (! timeout)
// Success
break;
if (timeout == EINTR)
// Go round again
timeout = 0;
}
}
ok = es->triggered;
}
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
return ok;
}
void WaitableEvent::signal() const throw()
{
EventStruct* const es = (EventStruct*)internal;
pthread_mutex_lock (&es->mutex);
es->triggered = true;
pthread_cond_broadcast (&es->condition);
pthread_mutex_unlock (&es->mutex);
}
void WaitableEvent::reset() const throw()
{
EventStruct* const es = (EventStruct*)internal;
pthread_mutex_lock (&es->mutex);
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
}
//============================================================================== //==============================================================================
// sets the process to 0=low priority, 1=normal, 2=high, 3=realtime // sets the process to 0=low priority, 1=normal, 2=high, 3=realtime
@@ -404,82 +272,4 @@ void* Process::getProcedureEntryPoint (void* libraryHandle, const String& proced
#endif #endif
//==============================================================================
InterProcessLock::InterProcessLock (const String& name_) throw()
: internal (0),
name (name_),
reentrancyLevel (0)
{
const File tempDir (File::getSpecialLocation (File::tempDirectory));
const File temp (tempDir.getChildFile (name));
temp.create();
internal = (void*) open (temp.getFullPathName().toUTF8(), 'a');
}
InterProcessLock::~InterProcessLock() throw()
{
while (reentrancyLevel > 0)
this->exit();
#if JUCE_64BIT
close ((long long) internal);
#else
close ((int) internal);
#endif
}
bool InterProcessLock::enter (const int timeOutMillisecs) throw()
{
if (internal == 0)
return false;
if (reentrancyLevel != 0)
return true;
if (timeOutMillisecs <= 0)
{
if (flock ((long) internal,
timeOutMillisecs < 0 ? LOCK_EX
: (LOCK_EX | LOCK_NB)) == 0)
{
++reentrancyLevel;
return true;
}
}
else
{
const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs;
for (;;)
{
if (flock ((long) internal, LOCK_EX | LOCK_NB) == 0)
{
++reentrancyLevel;
return true;
}
if (Time::currentTimeMillis() >= endTime)
break;
Thread::sleep (10);
}
}
return false;
}
void InterProcessLock::exit() throw()
{
if (reentrancyLevel > 0 && internal != 0)
{
--reentrancyLevel;
const int result = flock ((long) internal, LOCK_UN);
(void) result;
jassert (result == 0);
}
}
END_JUCE_NAMESPACE END_JUCE_NAMESPACE

+ 10
- 191
build/macosx/platform_specific_code/juce_mac_Files.cpp View File

@@ -50,12 +50,18 @@ BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/basics/juce_SystemStats.h" #include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h" #include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#include "../../../src/juce_core/io/files/juce_NamedPipe.h" #include "../../../src/juce_core/io/files/juce_NamedPipe.h"
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
//============================================================================== //==============================================================================
const tchar File::separator = T('/');
const tchar* File::separatorString = T("/");
/*
Note that a lot of methods that you'd expect to find in this file actually
live in juce_posix_SharedCode.cpp!
*/
#include "juce_posix_SharedCode.cpp"
//==============================================================================
static File executableFile; static File executableFile;
@@ -193,54 +199,6 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s)
} }
//============================================================================== //==============================================================================
static bool juce_stat (const String& fileName, struct stat& info) throw()
{
return fileName.isNotEmpty()
&& (stat (fileName.toUTF8(), &info) == 0);
}
//==============================================================================
bool juce_isDirectory (const String& fileName) throw()
{
if (fileName.isEmpty())
return true;
struct stat info;
return juce_stat (fileName, info)
&& ((info.st_mode & S_IFDIR) != 0);
}
bool juce_fileExists (const String& fileName, const bool dontCountDirectories) throw()
{
if (fileName.isEmpty())
return false;
const char* const fileNameUTF8 = fileName.toUTF8();
bool exists = access (fileNameUTF8, F_OK) == 0;
if (exists && dontCountDirectories)
{
struct stat info;
const int res = stat (fileNameUTF8, &info);
if (res == 0 && (info.st_mode & S_IFDIR) != 0)
exists = false;
}
return exists;
}
int64 juce_getFileSize (const String& fileName) throw()
{
struct stat info;
if (juce_stat (fileName, info))
return info.st_size;
return 0;
}
const unsigned int macTimeToUnixTimeDiff = 0x7c25be90; const unsigned int macTimeToUnixTimeDiff = 0x7c25be90;
static uint64 utcDateTimeToUnixTime (const UTCDateTime& d) throw() static uint64 utcDateTimeToUnixTime (const UTCDateTime& d) throw()
@@ -328,11 +286,6 @@ bool juce_setFileTimes (const String& fileName,
return false; return false;
} }
bool juce_canWriteToFile (const String& fileName) throw()
{
return access (fileName.toUTF8(), W_OK) == 0;
}
bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw() bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw()
{ {
const char* const fileNameUTF8 = fileName.toUTF8(); const char* const fileNameUTF8 = fileName.toUTF8();
@@ -358,16 +311,6 @@ bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw()
return ok; return ok;
} }
bool juce_deleteFile (const String& fileName) throw()
{
const char* const fileNameUTF8 = fileName.toUTF8();
if (juce_isDirectory (fileName))
return rmdir (fileNameUTF8) == 0;
else
return remove (fileNameUTF8) == 0;
}
bool juce_copyFile (const String& src, const String& dst) throw() bool juce_copyFile (const String& src, const String& dst) throw()
{ {
const File destFile (dst); const File destFile (dst);
@@ -446,97 +389,6 @@ bool juce_copyFile (const String& src, const String& dst) throw()
return false; return false;
} }
bool juce_moveFile (const String& source, const String& dest) throw()
{
if (rename (source.toUTF8(), dest.toUTF8()) == 0)
return true;
if (juce_canWriteToFile (source)
&& juce_copyFile (source, dest))
{
if (juce_deleteFile (source))
return true;
juce_deleteFile (dest);
}
return false;
}
void juce_createDirectory (const String& fileName) throw()
{
mkdir (fileName.toUTF8(), 0777);
}
void* juce_fileOpen (const String& fileName, bool forWriting) throw()
{
const char* const fileNameUTF8 = fileName.toUTF8();
int flags = O_RDONLY;
if (forWriting)
{
if (juce_fileExists (fileName, false))
{
const int f = open (fileNameUTF8, O_RDWR, 00644);
if (f != -1)
lseek (f, 0, SEEK_END);
return (void*) f;
}
else
{
flags = O_RDWR + O_CREAT;
}
}
return (void*) open (fileNameUTF8, flags, 00644);
}
void juce_fileClose (void* handle) throw()
{
if (handle != 0)
close ((int) handle);
}
int juce_fileRead (void* handle, void* buffer, int size) throw()
{
if (handle != 0)
return read ((int) handle, buffer, size);
return 0;
}
int juce_fileWrite (void* handle, const void* buffer, int size) throw()
{
if (handle != 0)
return write ((int) handle, buffer, size);
return 0;
}
int64 juce_fileSetPosition (void* handle, int64 pos) throw()
{
if (handle != 0 && lseek ((int) handle, pos, SEEK_SET) == pos)
return pos;
return -1;
}
int64 juce_fileGetPosition (void* handle) throw()
{
if (handle != 0)
return lseek ((int) handle, 0, SEEK_CUR);
else
return -1;
}
void juce_fileFlush (void* handle) throw()
{
if (handle != 0)
fsync ((int) handle);
}
const StringArray juce_getFileSystemRoots() throw() const StringArray juce_getFileSystemRoots() throw()
{ {
StringArray s; StringArray s;
@@ -544,40 +396,6 @@ const StringArray juce_getFileSystemRoots() throw()
return s; return s;
} }
const String juce_getVolumeLabel (const String& filenameOnVolume, int& volumeSerialNumber) throw()
{
volumeSerialNumber = 0;
return String::empty;
}
// if this file doesn't exist, find a parent of it that does..
static bool doStatFS (const File* file, struct statfs& result) throw()
{
File f (*file);
for (int i = 5; --i >= 0;)
{
if (f.exists())
break;
f = f.getParentDirectory();
}
return statfs (f.getFullPathName().toUTF8(), &result) == 0;
}
int64 File::getBytesFreeOnVolume() const throw()
{
int64 free_space = 0;
struct statfs buf;
if (doStatFS (this, buf))
// Note: this returns space available to non-super user
free_space = (int64) buf.f_bsize * (int64) buf.f_bavail;
return free_space;
}
//============================================================================== //==============================================================================
static bool isFileOnDriveType (const File* const f, const char** types) throw() static bool isFileOnDriveType (const File* const f, const char** types) throw()
{ {
@@ -609,6 +427,7 @@ bool File::isOnHardDisk() const throw()
return ! (isOnCDRomDrive() || isFileOnDriveType (this, (const char**) nonHDTypes)); return ! (isOnCDRomDrive() || isFileOnDriveType (this, (const char**) nonHDTypes));
} }
//============================================================================== //==============================================================================
const File File::getSpecialLocation (const SpecialLocationType type) const File File::getSpecialLocation (const SpecialLocationType type)
{ {


+ 4
- 188
build/macosx/platform_specific_code/juce_mac_Threads.cpp View File

@@ -43,117 +43,14 @@ BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/threads/juce_WaitableEvent.h" #include "../../../src/juce_core/threads/juce_WaitableEvent.h"
#include "../../../src/juce_core/threads/juce_Thread.h" #include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/threads/juce_Process.h" #include "../../../src/juce_core/threads/juce_Process.h"
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h" #include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#include "../../../src/juce_core/io/files/juce_File.h" #include "../../../src/juce_core/io/files/juce_File.h"
//==============================================================================
CriticalSection::CriticalSection() throw()
{
pthread_mutexattr_t atts;
pthread_mutexattr_init (&atts);
pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&internal, &atts);
}
CriticalSection::~CriticalSection() throw()
{
pthread_mutex_destroy (&internal);
}
void CriticalSection::enter() const throw()
{
pthread_mutex_lock (&internal);
}
bool CriticalSection::tryEnter() const throw()
{
return pthread_mutex_trylock (&internal) == 0;
}
void CriticalSection::exit() const throw()
{
pthread_mutex_unlock (&internal);
}
//============================================================================== //==============================================================================
struct EventStruct
{
pthread_cond_t condition;
pthread_mutex_t mutex;
bool triggered;
};
WaitableEvent::WaitableEvent() throw()
{
EventStruct* const es = new EventStruct();
es->triggered = false;
pthread_cond_init (&es->condition, 0);
pthread_mutex_init (&es->mutex, 0);
internal = es;
}
WaitableEvent::~WaitableEvent() throw()
{
EventStruct* const es = (EventStruct*) internal;
pthread_cond_destroy (&es->condition);
pthread_mutex_destroy (&es->mutex);
delete es;
}
bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
{
EventStruct* const es = (EventStruct*) internal;
bool ok = true;
pthread_mutex_lock (&es->mutex);
if (! es->triggered)
{
if (timeOutMillisecs < 0)
{
pthread_cond_wait (&es->condition, &es->mutex);
}
else
{
struct timespec time;
time.tv_sec = timeOutMillisecs / 1000;
time.tv_nsec = (timeOutMillisecs % 1000) * 1000000;
pthread_cond_timedwait_relative_np (&es->condition, &es->mutex, &time);
}
ok = es->triggered;
}
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
return ok;
}
void WaitableEvent::signal() const throw()
{
EventStruct* const es = (EventStruct*) internal;
pthread_mutex_lock (&es->mutex);
es->triggered = true;
pthread_cond_broadcast (&es->condition);
pthread_mutex_unlock (&es->mutex);
}
void WaitableEvent::reset() const throw()
{
EventStruct* const es = (EventStruct*) internal;
pthread_mutex_lock (&es->mutex);
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
}
/*
Note that a lot of methods that you'd expect to find in this file actually
live in juce_posix_SharedCode.cpp!
*/
//============================================================================== //==============================================================================
void JUCE_API juce_threadEntryPoint (void*); void JUCE_API juce_threadEntryPoint (void*);
@@ -215,15 +112,6 @@ void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw()
jassertfalse jassertfalse
} }
void JUCE_CALLTYPE Thread::sleep (int millisecs) throw()
{
struct timespec time;
time.tv_sec = millisecs / 1000;
time.tv_nsec = (millisecs % 1000) * 1000000;
nanosleep (&time, 0);
}
//============================================================================== //==============================================================================
bool JUCE_CALLTYPE juce_isRunningUnderDebugger() throw() bool JUCE_CALLTYPE juce_isRunningUnderDebugger() throw()
{ {
@@ -311,77 +199,5 @@ void* Process::getProcedureEntryPoint (void* h, const String& procedureName)
return 0; return 0;
} }
//==============================================================================
InterProcessLock::InterProcessLock (const String& name_) throw()
: internal (0),
name (name_),
reentrancyLevel (0)
{
const File tempDir (File::getSpecialLocation (File::tempDirectory));
const File temp (tempDir.getChildFile (name));
temp.create();
internal = (void*) open (temp.getFullPathName().toUTF8(), O_NONBLOCK | O_RDONLY);
}
InterProcessLock::~InterProcessLock() throw()
{
while (reentrancyLevel > 0)
this->exit();
close ((int) internal);
}
bool InterProcessLock::enter (const int timeOutMillisecs) throw()
{
if (internal == 0)
return false;
if (reentrancyLevel != 0)
return true;
if (timeOutMillisecs <= 0)
{
if (flock ((int) internal,
timeOutMillisecs < 0 ? LOCK_EX
: (LOCK_EX | LOCK_NB)) == 0)
{
++reentrancyLevel;
return true;
}
}
else
{
const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs;
for (;;)
{
if (flock ((int) internal, LOCK_EX | LOCK_NB) == 0)
{
++reentrancyLevel;
return true;
}
if (Time::currentTimeMillis() >= endTime)
break;
Thread::sleep (10);
}
}
return false;
}
void InterProcessLock::exit() throw()
{
if (reentrancyLevel > 0 && internal != 0)
{
--reentrancyLevel;
const int result = flock ((int) internal, LOCK_UN);
(void) result;
jassert (result == 0);
}
}
END_JUCE_NAMESPACE END_JUCE_NAMESPACE

+ 466
- 0
build/macosx/platform_specific_code/juce_posix_SharedCode.cpp View File

@@ -0,0 +1,466 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
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.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
/*
This file contains posix routines that are common to both the Linux and Mac builds.
It gets included directly in the cpp files for these platforms.
*/
//==============================================================================
CriticalSection::CriticalSection() throw()
{
pthread_mutexattr_t atts;
pthread_mutexattr_init (&atts);
pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&internal, &atts);
}
CriticalSection::~CriticalSection() throw()
{
pthread_mutex_destroy (&internal);
}
void CriticalSection::enter() const throw()
{
pthread_mutex_lock (&internal);
}
bool CriticalSection::tryEnter() const throw()
{
return pthread_mutex_trylock (&internal) == 0;
}
void CriticalSection::exit() const throw()
{
pthread_mutex_unlock (&internal);
}
//==============================================================================
struct EventStruct
{
pthread_cond_t condition;
pthread_mutex_t mutex;
bool triggered;
};
WaitableEvent::WaitableEvent() throw()
{
EventStruct* const es = new EventStruct();
es->triggered = false;
pthread_cond_init (&es->condition, 0);
pthread_mutex_init (&es->mutex, 0);
internal = es;
}
WaitableEvent::~WaitableEvent() throw()
{
EventStruct* const es = (EventStruct*) internal;
pthread_cond_destroy (&es->condition);
pthread_mutex_destroy (&es->mutex);
delete es;
}
bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
{
EventStruct* const es = (EventStruct*) internal;
bool ok = true;
pthread_mutex_lock (&es->mutex);
if (! es->triggered)
{
if (timeOutMillisecs < 0)
{
pthread_cond_wait (&es->condition, &es->mutex);
}
else
{
struct timespec time;
#if JUCE_MAC
time.tv_sec = timeOutMillisecs / 1000;
time.tv_nsec = (timeOutMillisecs % 1000) * 1000000;
pthread_cond_timedwait_relative_np (&es->condition, &es->mutex, &time);
#else
struct timeval t;
int timeout = 0;
gettimeofday (&t, 0);
time.tv_sec = t.tv_sec + (timeOutMillisecs / 1000);
time.tv_nsec = (t.tv_usec + ((timeOutMillisecs % 1000) * 1000)) * 1000;
while (time.tv_nsec >= 1000000000)
{
time.tv_nsec -= 1000000000;
time.tv_sec++;
}
while (! timeout)
{
timeout = pthread_cond_timedwait (&es->condition, &es->mutex, &time);
if (! timeout)
// Success
break;
if (timeout == EINTR)
// Go round again
timeout = 0;
}
#endif
}
ok = es->triggered;
}
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
return ok;
}
void WaitableEvent::signal() const throw()
{
EventStruct* const es = (EventStruct*) internal;
pthread_mutex_lock (&es->mutex);
es->triggered = true;
pthread_cond_broadcast (&es->condition);
pthread_mutex_unlock (&es->mutex);
}
void WaitableEvent::reset() const throw()
{
EventStruct* const es = (EventStruct*) internal;
pthread_mutex_lock (&es->mutex);
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
}
//==============================================================================
void JUCE_CALLTYPE Thread::sleep (int millisecs) throw()
{
struct timespec time;
time.tv_sec = millisecs / 1000;
time.tv_nsec = (millisecs % 1000) * 1000000;
nanosleep (&time, 0);
}
//==============================================================================
const tchar File::separator = T('/');
const tchar* File::separatorString = T("/");
//==============================================================================
bool juce_copyFile (const String& s, const String& d) throw();
static bool juce_stat (const String& fileName, struct stat& info) throw()
{
return fileName.isNotEmpty()
&& (stat (fileName.toUTF8(), &info) == 0);
}
bool juce_isDirectory (const String& fileName) throw()
{
struct stat info;
return fileName.isEmpty()
|| (juce_stat (fileName, info)
&& ((info.st_mode & S_IFDIR) != 0));
}
bool juce_fileExists (const String& fileName, const bool dontCountDirectories) throw()
{
if (fileName.isEmpty())
return false;
const char* const fileNameUTF8 = fileName.toUTF8();
bool exists = access (fileNameUTF8, F_OK) == 0;
if (exists && dontCountDirectories)
{
struct stat info;
const int res = stat (fileNameUTF8, &info);
if (res == 0 && (info.st_mode & S_IFDIR) != 0)
exists = false;
}
return exists;
}
int64 juce_getFileSize (const String& fileName) throw()
{
struct stat info;
return juce_stat (fileName, info) ? info.st_size : 0;
}
//==============================================================================
bool juce_canWriteToFile (const String& fileName) throw()
{
return access (fileName.toUTF8(), W_OK) == 0;
}
bool juce_deleteFile (const String& fileName) throw()
{
const char* const fileNameUTF8 = fileName.toUTF8();
if (juce_isDirectory (fileName))
return rmdir (fileNameUTF8) == 0;
else
return remove (fileNameUTF8) == 0;
}
bool juce_moveFile (const String& source, const String& dest) throw()
{
if (rename (source.toUTF8(), dest.toUTF8()) == 0)
return true;
if (juce_canWriteToFile (source)
&& juce_copyFile (source, dest))
{
if (juce_deleteFile (source))
return true;
juce_deleteFile (dest);
}
return false;
}
void juce_createDirectory (const String& fileName) throw()
{
mkdir (fileName.toUTF8(), 0777);
}
void* juce_fileOpen (const String& fileName, bool forWriting) throw()
{
const char* const fileNameUTF8 = fileName.toUTF8();
int flags = O_RDONLY;
if (forWriting)
{
if (juce_fileExists (fileName, false))
{
const int f = open (fileNameUTF8, O_RDWR, 00644);
if (f != -1)
lseek (f, 0, SEEK_END);
return (void*) f;
}
else
{
flags = O_RDWR + O_CREAT;
}
}
return (void*) open (fileNameUTF8, flags, 00644);
}
void juce_fileClose (void* handle) throw()
{
if (handle != 0)
close ((int) handle);
}
int juce_fileRead (void* handle, void* buffer, int size) throw()
{
if (handle != 0)
return read ((int) handle, buffer, size);
return 0;
}
int juce_fileWrite (void* handle, const void* buffer, int size) throw()
{
if (handle != 0)
return write ((int) handle, buffer, size);
return 0;
}
int64 juce_fileSetPosition (void* handle, int64 pos) throw()
{
if (handle != 0 && lseek ((int) handle, pos, SEEK_SET) == pos)
return pos;
return -1;
}
int64 juce_fileGetPosition (void* handle) throw()
{
if (handle != 0)
return lseek ((int) handle, 0, SEEK_CUR);
else
return -1;
}
void juce_fileFlush (void* handle) throw()
{
if (handle != 0)
fsync ((int) handle);
}
//==============================================================================
// if this file doesn't exist, find a parent of it that does..
static bool doStatFS (const File* file, struct statfs& result) throw()
{
File f (*file);
for (int i = 5; --i >= 0;)
{
if (f.exists())
break;
f = f.getParentDirectory();
}
return statfs (f.getFullPathName().toUTF8(), &result) == 0;
}
int64 File::getBytesFreeOnVolume() const throw()
{
int64 free_space = 0;
struct statfs buf;
if (doStatFS (this, buf))
// Note: this returns space available to non-super user
free_space = (int64) buf.f_bsize * (int64) buf.f_bavail;
return free_space;
}
const String juce_getVolumeLabel (const String& filenameOnVolume,
int& volumeSerialNumber) throw()
{
// There is no equivalent on Linux
volumeSerialNumber = 0;
return String::empty;
}
//==============================================================================
#if JUCE_64BIT
#define filedesc ((long long) internal)
#else
#define filedesc ((int) internal)
#endif
InterProcessLock::InterProcessLock (const String& name_) throw()
: internal (0),
name (name_),
reentrancyLevel (0)
{
const File tempDir (File::getSpecialLocation (File::tempDirectory));
const File temp (tempDir.getChildFile (name));
temp.create();
internal = (void*) open (temp.getFullPathName().toUTF8(), O_RDWR);
}
InterProcessLock::~InterProcessLock() throw()
{
while (reentrancyLevel > 0)
this->exit();
close (filedesc);
}
bool InterProcessLock::enter (const int timeOutMillisecs) throw()
{
if (internal == 0)
return false;
if (reentrancyLevel != 0)
return true;
const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs;
struct flock fl;
zerostruct (fl);
fl.l_whence = SEEK_SET;
fl.l_type = F_WRLCK;
for (;;)
{
const int result = fcntl (filedesc, F_SETLK, &fl);
if (result >= 0)
{
++reentrancyLevel;
return true;
}
if (errno != EINTR)
{
if (timeOutMillisecs == 0
|| (timeOutMillisecs > 0 && Time::currentTimeMillis() >= endTime))
break;
Thread::sleep (10);
}
}
return false;
}
void InterProcessLock::exit() throw()
{
if (reentrancyLevel > 0 && internal != 0)
{
--reentrancyLevel;
struct flock fl;
zerostruct (fl);
fl.l_whence = SEEK_SET;
fl.l_type = F_UNLCK;
for (;;)
{
const int result = fcntl (filedesc, F_SETLKW, &fl);
if (result >= 0 || errno != EINTR)
break;
}
}
}

+ 2
- 1
docs/JUCE changelist.txt View File

@@ -23,7 +23,8 @@ Changelist for version 1.46
- new method: PlatformUtilities::launchEmailWithAttachments - new method: PlatformUtilities::launchEmailWithAttachments
- new classes: AudioThumbnail and AudioThumbnailCache, which allow easy rendering of low-res waveform previews - new classes: AudioThumbnail and AudioThumbnailCache, which allow easy rendering of low-res waveform previews
- new classes: InputSource and FileInputSource. These encapsulate some kind of resource, and also replace the XmlInputSource class. - new classes: InputSource and FileInputSource. These encapsulate some kind of resource, and also replace the XmlInputSource class.

- moved some of the posix code that was the same in the mac and linux builds into a single, shared file
- fixed InterprocessLock on mac/linux so that it can't get stuck when an app quits unexpectedly


============================================================================== ==============================================================================
Changelist for version 1.45 Changelist for version 1.45


+ 1
- 1
extras/juce demo/src/ApplicationStartup.cpp View File

@@ -103,7 +103,7 @@ public:
bool moreThanOneInstanceAllowed() bool moreThanOneInstanceAllowed()
{ {
return true;
return false;
} }
void anotherInstanceStarted (const String& commandLine) void anotherInstanceStarted (const String& commandLine)


+ 1
- 1
src/juce_appframework/audio/plugins/juce_PluginDescription.cpp View File

@@ -57,9 +57,9 @@ PluginDescription::PluginDescription (const PluginDescription& other) throw()
manufacturerName (other.manufacturerName), manufacturerName (other.manufacturerName),
version (other.version), version (other.version),
file (other.file), file (other.file),
lastFileModTime (other.lastFileModTime),
uid (other.uid), uid (other.uid),
isInstrument (other.isInstrument), isInstrument (other.isInstrument),
lastFileModTime (other.lastFileModTime),
numInputChannels (other.numInputChannels), numInputChannels (other.numInputChannels),
numOutputChannels (other.numOutputChannels) numOutputChannels (other.numOutputChannels)
{ {


Loading…
Cancel
Save