|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-10 by Raw Material Software Ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the GNU General
- Public License (Version 2), as published by the Free Software Foundation.
- A copy of the license is included in the JUCE distribution, or can be found
- online at www.gnu.org/licenses.
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.rawmaterialsoftware.com/juce for more information.
-
- ==============================================================================
- */
-
- // (This file gets included by juce_win32_NativeCode.cpp, rather than being
- // compiled on its own).
- #if JUCE_INCLUDED_FILE
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
- extern HWND juce_messageWindowHandle;
- #endif
-
- //==============================================================================
- #if ! JUCE_USE_INTRINSICS
- // In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in
- // older ones we have to actually call the ops as win32 functions..
- long juce_InterlockedExchange (volatile long* a, long b) throw() { return InterlockedExchange (a, b); }
- long juce_InterlockedIncrement (volatile long* a) throw() { return InterlockedIncrement (a); }
- long juce_InterlockedDecrement (volatile long* a) throw() { return InterlockedDecrement (a); }
- long juce_InterlockedExchangeAdd (volatile long* a, long b) throw() { return InterlockedExchangeAdd (a, b); }
- long juce_InterlockedCompareExchange (volatile long* a, long b, long c) throw() { return InterlockedCompareExchange (a, b, c); }
-
- __int64 juce_InterlockedCompareExchange64 (volatile __int64* value, __int64 newValue, __int64 valueToCompare) throw()
- {
- jassertfalse; // This operation isn't available in old MS compiler versions!
-
- __int64 oldValue = *value;
- if (oldValue == valueToCompare)
- *value = newValue;
-
- return oldValue;
- }
-
- #endif
-
- //==============================================================================
- CriticalSection::CriticalSection() throw()
- {
- // (just to check the MS haven't changed this structure and broken things...)
- #if _MSC_VER >= 1400
- static_jassert (sizeof (CRITICAL_SECTION) <= sizeof (internal));
- #else
- static_jassert (sizeof (CRITICAL_SECTION) <= 24);
- #endif
-
- InitializeCriticalSection ((CRITICAL_SECTION*) internal);
- }
-
- CriticalSection::~CriticalSection() throw()
- {
- DeleteCriticalSection ((CRITICAL_SECTION*) internal);
- }
-
- void CriticalSection::enter() const throw()
- {
- EnterCriticalSection ((CRITICAL_SECTION*) internal);
- }
-
- bool CriticalSection::tryEnter() const throw()
- {
- return TryEnterCriticalSection ((CRITICAL_SECTION*) internal) != FALSE;
- }
-
- void CriticalSection::exit() const throw()
- {
- LeaveCriticalSection ((CRITICAL_SECTION*) internal);
- }
-
- //==============================================================================
- WaitableEvent::WaitableEvent (const bool manualReset) throw()
- : internal (CreateEvent (0, manualReset ? TRUE : FALSE, FALSE, 0))
- {
- }
-
- WaitableEvent::~WaitableEvent() throw()
- {
- CloseHandle (internal);
- }
-
- bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
- {
- return WaitForSingleObject (internal, timeOutMillisecs) == WAIT_OBJECT_0;
- }
-
- void WaitableEvent::signal() const throw()
- {
- SetEvent (internal);
- }
-
- void WaitableEvent::reset() const throw()
- {
- ResetEvent (internal);
- }
-
- //==============================================================================
- void JUCE_API juce_threadEntryPoint (void*);
-
- static unsigned int __stdcall threadEntryProc (void* userData)
- {
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
- AttachThreadInput (GetWindowThreadProcessId (juce_messageWindowHandle, 0),
- GetCurrentThreadId(), TRUE);
- #endif
-
- juce_threadEntryPoint (userData);
-
- _endthreadex (0);
- return 0;
- }
-
- void juce_CloseThreadHandle (void* handle)
- {
- CloseHandle ((HANDLE) handle);
- }
-
- void* juce_createThread (void* userData)
- {
- unsigned int threadId;
- return (void*) _beginthreadex (0, 0, &threadEntryProc, userData, 0, &threadId);
- }
-
- void juce_killThread (void* handle)
- {
- if (handle != 0)
- {
- #if JUCE_DEBUG
- OutputDebugString (_T("** Warning - Forced thread termination **\n"));
- #endif
- TerminateThread (handle, 0);
- }
- }
-
- void juce_setCurrentThreadName (const String& name)
- {
- #if JUCE_DEBUG && JUCE_MSVC
- struct
- {
- DWORD dwType;
- LPCSTR szName;
- DWORD dwThreadID;
- DWORD dwFlags;
- } info;
-
- info.dwType = 0x1000;
- info.szName = name.toCString();
- info.dwThreadID = GetCurrentThreadId();
- info.dwFlags = 0;
-
- __try
- {
- RaiseException (0x406d1388 /*MS_VC_EXCEPTION*/, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info);
- }
- __except (EXCEPTION_CONTINUE_EXECUTION)
- {}
- #else
- (void) name;
- #endif
- }
-
- Thread::ThreadID Thread::getCurrentThreadId()
- {
- return (ThreadID) (pointer_sized_int) GetCurrentThreadId();
- }
-
- // priority 1 to 10 where 5=normal, 1=low
- bool juce_setThreadPriority (void* threadHandle, int priority)
- {
- int pri = THREAD_PRIORITY_TIME_CRITICAL;
-
- if (priority < 1)
- pri = THREAD_PRIORITY_IDLE;
- else if (priority < 2)
- pri = THREAD_PRIORITY_LOWEST;
- else if (priority < 5)
- pri = THREAD_PRIORITY_BELOW_NORMAL;
- else if (priority < 7)
- pri = THREAD_PRIORITY_NORMAL;
- else if (priority < 9)
- pri = THREAD_PRIORITY_ABOVE_NORMAL;
- else if (priority < 10)
- pri = THREAD_PRIORITY_HIGHEST;
-
- if (threadHandle == 0)
- threadHandle = GetCurrentThread();
-
- return SetThreadPriority (threadHandle, pri) != FALSE;
- }
-
- void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
- {
- SetThreadAffinityMask (GetCurrentThread(), affinityMask);
- }
-
- static HANDLE sleepEvent = 0;
-
- void juce_initialiseThreadEvents()
- {
- if (sleepEvent == 0)
- #if JUCE_DEBUG
- sleepEvent = CreateEvent (0, 0, 0, _T("Juce Sleep Event"));
- #else
- sleepEvent = CreateEvent (0, 0, 0, 0);
- #endif
- }
-
- void Thread::yield()
- {
- Sleep (0);
- }
-
- void JUCE_CALLTYPE Thread::sleep (const int millisecs)
- {
- if (millisecs >= 10)
- {
- Sleep (millisecs);
- }
- else
- {
- jassert (sleepEvent != 0);
-
- // unlike Sleep() this is guaranteed to return to the current thread after
- // the time expires, so we'll use this for short waits, which are more likely
- // to need to be accurate
- WaitForSingleObject (sleepEvent, millisecs);
- }
- }
-
- //==============================================================================
- static int lastProcessPriority = -1;
-
- // called by WindowDriver because Windows does wierd things to process priority
- // when you swap apps, and this forces an update when the app is brought to the front.
- void juce_repeatLastProcessPriority()
- {
- if (lastProcessPriority >= 0) // (avoid changing this if it's not been explicitly set by the app..)
- {
- DWORD p;
-
- switch (lastProcessPriority)
- {
- case Process::LowPriority: p = IDLE_PRIORITY_CLASS; break;
- case Process::NormalPriority: p = NORMAL_PRIORITY_CLASS; break;
- case Process::HighPriority: p = HIGH_PRIORITY_CLASS; break;
- case Process::RealtimePriority: p = REALTIME_PRIORITY_CLASS; break;
- default: jassertfalse; return; // bad priority value
- }
-
- SetPriorityClass (GetCurrentProcess(), p);
- }
- }
-
- void Process::setPriority (ProcessPriority prior)
- {
- if (lastProcessPriority != (int) prior)
- {
- lastProcessPriority = (int) prior;
- juce_repeatLastProcessPriority();
- }
- }
-
- bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger()
- {
- return IsDebuggerPresent() != FALSE;
- }
-
- bool JUCE_CALLTYPE Process::isRunningUnderDebugger()
- {
- return juce_isRunningUnderDebugger();
- }
-
-
- //==============================================================================
- void Process::raisePrivilege()
- {
- jassertfalse // xxx not implemented
- }
-
- void Process::lowerPrivilege()
- {
- jassertfalse // xxx not implemented
- }
-
- void Process::terminate()
- {
- #if JUCE_DEBUG && JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
- _CrtDumpMemoryLeaks();
- #endif
-
- // bullet in the head in case there's a problem shutting down..
- ExitProcess (0);
- }
-
- //==============================================================================
- void* PlatformUtilities::loadDynamicLibrary (const String& name)
- {
- void* result = 0;
-
- JUCE_TRY
- {
- result = LoadLibrary (name);
- }
- JUCE_CATCH_ALL
-
- return result;
- }
-
- void PlatformUtilities::freeDynamicLibrary (void* h)
- {
- JUCE_TRY
- {
- if (h != 0)
- FreeLibrary ((HMODULE) h);
- }
- JUCE_CATCH_ALL
- }
-
- void* PlatformUtilities::getProcedureEntryPoint (void* h, const String& name)
- {
- return (h != 0) ? GetProcAddress ((HMODULE) h, name.toCString()) : 0;
- }
-
-
- //==============================================================================
- class InterProcessLock::Pimpl
- {
- public:
- Pimpl (const String& name, const int timeOutMillisecs)
- : handle (0), refCount (1)
- {
- handle = CreateMutex (0, TRUE, "Global\\" + name.replaceCharacter ('\\','/'));
-
- if (handle != 0 && GetLastError() == ERROR_ALREADY_EXISTS)
- {
- if (timeOutMillisecs == 0)
- {
- close();
- return;
- }
-
- switch (WaitForSingleObject (handle, timeOutMillisecs < 0 ? INFINITE : timeOutMillisecs))
- {
- case WAIT_OBJECT_0:
- case WAIT_ABANDONED:
- break;
-
- case WAIT_TIMEOUT:
- default:
- close();
- break;
- }
- }
- }
-
- ~Pimpl()
- {
- close();
- }
-
- void close()
- {
- if (handle != 0)
- {
- ReleaseMutex (handle);
- CloseHandle (handle);
- handle = 0;
- }
- }
-
- HANDLE handle;
- int refCount;
- };
-
- InterProcessLock::InterProcessLock (const String& name_)
- : name (name_)
- {
- }
-
- InterProcessLock::~InterProcessLock()
- {
- }
-
- bool InterProcessLock::enter (const int timeOutMillisecs)
- {
- const ScopedLock sl (lock);
-
- if (pimpl == 0)
- {
- pimpl = new Pimpl (name, timeOutMillisecs);
-
- if (pimpl->handle == 0)
- pimpl = 0;
- }
- else
- {
- pimpl->refCount++;
- }
-
- return pimpl != 0;
- }
-
- void InterProcessLock::exit()
- {
- const ScopedLock sl (lock);
-
- // Trying to release the lock too many times!
- jassert (pimpl != 0);
-
- if (pimpl != 0 && --(pimpl->refCount) == 0)
- pimpl = 0;
- }
-
-
- #endif
|