mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
This commit is contained in:
parent
88fa4e0e56
commit
ff3c2e9fce
9 changed files with 521 additions and 771 deletions
|
|
@ -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 $<)
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
|
||||||
|
#include "../../../src/juce_core/threads/juce_Thread.h"
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
static File executableFile;
|
static File executableFile;
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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(), ×) == 0;
|
return utime (fileName.toUTF8(), ×) == 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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
const tchar File::separator = T('/');
|
|
||||||
const tchar* File::separatorString = T("/");
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
/*
|
||||||
{
|
Note that a lot of methods that you'd expect to find in this file actually
|
||||||
pthread_mutexattr_t atts;
|
live in juce_posix_SharedCode.cpp!
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
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
build/macosx/platform_specific_code/juce_posix_SharedCode.cpp
Normal file
466
build/macosx/platform_specific_code/juce_posix_SharedCode.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ public:
|
||||||
|
|
||||||
bool moreThanOneInstanceAllowed()
|
bool moreThanOneInstanceAllowed()
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void anotherInstanceStarted (const String& commandLine)
|
void anotherInstanceStarted (const String& commandLine)
|
||||||
|
|
|
||||||
|
|
@ -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…
Add table
Add a link
Reference in a new issue