|
- /*
- ==============================================================================
-
- 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.
-
- ==============================================================================
- */
-
- #include "win32_headers.h"
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #include <crtdbg.h>
- #endif
-
- #include <process.h>
- #include "../../../src/juce_core/basics/juce_StandardHeader.h"
-
- BEGIN_JUCE_NAMESPACE
-
- #include "../../../src/juce_core/text/juce_String.h"
- #include "../../../src/juce_core/threads/juce_CriticalSection.h"
- #include "../../../src/juce_core/threads/juce_WaitableEvent.h"
- #include "../../../src/juce_core/threads/juce_Thread.h"
- #include "../../../src/juce_core/threads/juce_Process.h"
- #include "../../../src/juce_core/threads/juce_InterProcessLock.h"
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
- extern HWND juce_messageWindowHandle;
- #endif
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #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() throw()
- : internal (CreateEvent (0, 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) throw()
- {
- #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) throw()
- {
- CloseHandle ((HANDLE) handle);
- }
-
- void* juce_createThread (void* userData) throw()
- {
- unsigned int threadId;
-
- return (void*) _beginthreadex (0, 0,
- &threadEntryProc,
- userData,
- 0, &threadId);
- }
-
- void juce_killThread (void* handle) throw()
- {
- if (handle != 0)
- {
- #ifdef JUCE_DEBUG
- OutputDebugString (_T("** Warning - Forced thread termination **\n"));
- #endif
- TerminateThread (handle, 0);
- }
- }
-
- void juce_setCurrentThreadName (const String& name) throw()
- {
- #if defined (JUCE_DEBUG) && JUCE_MSVC
- struct
- {
- DWORD dwType;
- LPCSTR szName;
- DWORD dwThreadID;
- DWORD dwFlags;
- } info;
-
- info.dwType = 0x1000;
- info.szName = name;
- info.dwThreadID = GetCurrentThreadId();
- info.dwFlags = 0;
-
- #define MS_VC_EXCEPTION 0x406d1388
-
- __try
- {
- RaiseException (MS_VC_EXCEPTION, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info);
- }
- __except (EXCEPTION_CONTINUE_EXECUTION)
- {}
- #else
- (void) name;
- #endif
- }
-
- int Thread::getCurrentThreadId() throw()
- {
- return (int) GetCurrentThreadId();
- }
-
- // priority 1 to 10 where 5=normal, 1=low
- void juce_setThreadPriority (void* threadHandle, int priority) throw()
- {
- 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();
-
- SetThreadPriority (threadHandle, pri);
- }
-
- void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw()
- {
- SetThreadAffinityMask (GetCurrentThread(), affinityMask);
- }
-
- static HANDLE sleepEvent = 0;
-
- void juce_initialiseThreadEvents() throw()
- {
- if (sleepEvent == 0)
- #ifdef JUCE_DEBUG
- sleepEvent = CreateEvent (0, 0, 0, _T("Juce Sleep Event"));
- #else
- sleepEvent = CreateEvent (0, 0, 0, 0);
- #endif
- }
-
- void Thread::yield() throw()
- {
- Sleep (0);
- }
-
- void JUCE_CALLTYPE Thread::sleep (const int millisecs) throw()
- {
- 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() throw()
- {
- 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 // bad priority value
- return;
- }
-
- SetPriorityClass (GetCurrentProcess(), p);
- }
- }
-
- void Process::setPriority (ProcessPriority prior)
- {
- if (lastProcessPriority != (int) prior)
- {
- lastProcessPriority = (int) prior;
- juce_repeatLastProcessPriority();
- }
- }
-
- bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger() throw()
- {
- return IsDebuggerPresent() != FALSE;
- }
-
- bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw()
- {
- return juce_isRunningUnderDebugger();
- }
-
-
- //==============================================================================
- void Process::raisePrivilege()
- {
- jassertfalse // xxx not implemented
- }
-
- void Process::lowerPrivilege()
- {
- jassertfalse // xxx not implemented
- }
-
- void Process::terminate()
- {
- #if defined (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* Process::loadDynamicLibrary (const String& name)
- {
- void* result = 0;
-
- JUCE_TRY
- {
- result = (void*) LoadLibrary (name);
- }
- JUCE_CATCH_ALL
-
- return result;
- }
-
- void Process::freeDynamicLibrary (void* h)
- {
- JUCE_TRY
- {
- if (h != 0)
- FreeLibrary ((HMODULE) h);
- }
- JUCE_CATCH_ALL
- }
-
- void* Process::getProcedureEntryPoint (void* h, const String& name)
- {
- return (h != 0) ? (void*) GetProcAddress ((HMODULE) h, name)
- : 0;
- }
-
-
- //==============================================================================
- InterProcessLock::InterProcessLock (const String& name_) throw()
- : internal (0),
- name (name_),
- reentrancyLevel (0)
- {
- }
-
- InterProcessLock::~InterProcessLock() throw()
- {
- exit();
- }
-
- bool InterProcessLock::enter (const int timeOutMillisecs) throw()
- {
- if (reentrancyLevel++ == 0)
- {
- internal = CreateMutex (0, TRUE, name);
-
- if (internal != 0 && GetLastError() == ERROR_ALREADY_EXISTS)
- {
- if (timeOutMillisecs == 0
- || WaitForSingleObject (internal, (timeOutMillisecs < 0) ? INFINITE : timeOutMillisecs)
- == WAIT_TIMEOUT)
- {
- ReleaseMutex (internal);
- CloseHandle (internal);
- internal = 0;
- }
- }
- }
-
- return (internal != 0);
- }
-
- void InterProcessLock::exit() throw()
- {
- if (--reentrancyLevel == 0 && internal != 0)
- {
- ReleaseMutex (internal);
- CloseHandle (internal);
- internal = 0;
- }
- }
-
-
-
- END_JUCE_NAMESPACE
|