From dca2d070bf1e2d4050990c9c93d109dab2e5760b Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Tue, 3 Apr 2012 13:50:32 +0200 Subject: [PATCH] platform/win32: moved the static variables in os-threads from the header to a separate cpp file, or it could lead to problems when included multiple times --- project/cec-config.vcxproj | 1 + project/cec-config.vcxproj.filters | 3 + project/libcec.vcxproj | 3 +- project/libcec.vcxproj.filters | 5 +- project/testclient.vcxproj | 1 + project/testclient.vcxproj.filters | 3 + src/lib/platform/windows/os-threads.cpp | 136 ++++++++++++++++++++++++ src/lib/platform/windows/os-threads.h | 105 ++---------------- 8 files changed, 156 insertions(+), 101 deletions(-) create mode 100644 src/lib/platform/windows/os-threads.cpp diff --git a/project/cec-config.vcxproj b/project/cec-config.vcxproj index 2243ff9..6ca84e4 100644 --- a/project/cec-config.vcxproj +++ b/project/cec-config.vcxproj @@ -173,6 +173,7 @@ + diff --git a/project/cec-config.vcxproj.filters b/project/cec-config.vcxproj.filters index 0d3f647..2ee5127 100644 --- a/project/cec-config.vcxproj.filters +++ b/project/cec-config.vcxproj.filters @@ -21,6 +21,9 @@ + + platform + diff --git a/project/libcec.vcxproj b/project/libcec.vcxproj index 3c1e89b..5b3c6f0 100644 --- a/project/libcec.vcxproj +++ b/project/libcec.vcxproj @@ -73,6 +73,7 @@ + @@ -238,4 +239,4 @@ - \ No newline at end of file + diff --git a/project/libcec.vcxproj.filters b/project/libcec.vcxproj.filters index 56f1a46..50ae8df 100644 --- a/project/libcec.vcxproj.filters +++ b/project/libcec.vcxproj.filters @@ -167,6 +167,9 @@ devices + + platform\windows + platform\windows @@ -183,4 +186,4 @@ - \ No newline at end of file + diff --git a/project/testclient.vcxproj b/project/testclient.vcxproj index fb19572..0862f27 100644 --- a/project/testclient.vcxproj +++ b/project/testclient.vcxproj @@ -170,6 +170,7 @@ + diff --git a/project/testclient.vcxproj.filters b/project/testclient.vcxproj.filters index 70acf3d..0fd21fb 100644 --- a/project/testclient.vcxproj.filters +++ b/project/testclient.vcxproj.filters @@ -18,6 +18,9 @@ + + platform + diff --git a/src/lib/platform/windows/os-threads.cpp b/src/lib/platform/windows/os-threads.cpp new file mode 100644 index 0000000..7c06d41 --- /dev/null +++ b/src/lib/platform/windows/os-threads.cpp @@ -0,0 +1,136 @@ +/* + * This file is part of the libCEC(R) library. + * + * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. + * libCEC(R) is an original work, containing original code. + * + * libCEC(R) is a trademark of Pulse-Eight Limited. + * + * This program is dual-licensed; you can redistribute it and/or modify + * it 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * Alternatively, you can license this library under a commercial license, + * please contact Pulse-Eight Licensing for more information. + * + * For more information contact: + * Pulse-Eight Licensing + * http://www.pulse-eight.com/ + * http://www.pulse-eight.net/ + */ + +#include "../os.h" +#include "os-threads.h" +using namespace PLATFORM; + +static ConditionArg g_InitializeConditionVariable; +static ConditionArg g_WakeConditionVariable; +static ConditionArg g_WakeAllConditionVariable; +static ConditionMutexArg g_SleepConditionVariableCS; + +// check whether vista+ conditions are available at runtime +static bool CheckVistaConditionFunctions(void) +{ + static int iHasVistaConditionFunctions(-1); + if (iHasVistaConditionFunctions == -1) + { + HMODULE handle = GetModuleHandle("Kernel32"); + if (handle == NULL) + { + iHasVistaConditionFunctions = 0; + } + else + { + g_InitializeConditionVariable = (ConditionArg) GetProcAddress(handle,"InitializeConditionVariable"); + g_WakeConditionVariable = (ConditionArg) GetProcAddress(handle,"WakeConditionVariable"); + g_WakeAllConditionVariable = (ConditionArg) GetProcAddress(handle,"WakeAllConditionVariable"); + g_SleepConditionVariableCS = (ConditionMutexArg)GetProcAddress(handle,"SleepConditionVariableCS"); + + // 1 when everything is resolved, 0 otherwise + iHasVistaConditionFunctions = g_InitializeConditionVariable && + g_WakeConditionVariable && + g_WakeAllConditionVariable && + g_SleepConditionVariableCS ? 1 : 0; + } + } + return iHasVistaConditionFunctions == 1; +} + +CConditionImpl::CConditionImpl(void) +{ + m_bOnVista = CheckVistaConditionFunctions(); + if (m_bOnVista) + (*g_InitializeConditionVariable)(m_conditionVista = new CONDITION_VARIABLE); + else + m_conditionPreVista = ::CreateEvent(NULL, TRUE, FALSE, NULL); +} + +CConditionImpl::~CConditionImpl(void) +{ + if (m_bOnVista) + delete m_conditionVista; + else + ::CloseHandle(m_conditionPreVista); +} + +void CConditionImpl::Signal(void) +{ + if (m_bOnVista) + (*g_WakeConditionVariable)(m_conditionVista); + else + ::SetEvent(m_conditionPreVista); +} + +void CConditionImpl::Broadcast(void) +{ + if (m_bOnVista) + (*g_WakeAllConditionVariable)(m_conditionVista); + else + ::SetEvent(m_conditionPreVista); +} + +bool CConditionImpl::Wait(mutex_t &mutex) +{ + if (m_bOnVista) + { + return ((*g_SleepConditionVariableCS)(m_conditionVista, mutex, INFINITE) ? true : false); + } + else + { + ::ResetEvent(m_conditionPreVista); + MutexUnlock(mutex); + DWORD iWaitReturn = ::WaitForSingleObject(m_conditionPreVista, 1000); + MutexLock(mutex); + return (iWaitReturn == 0); + } +} + +bool CConditionImpl::Wait(mutex_t &mutex, uint32_t iTimeoutMs) +{ + if (iTimeoutMs == 0) + return Wait(mutex); + + if (m_bOnVista) + { + return ((*g_SleepConditionVariableCS)(m_conditionVista, mutex, iTimeoutMs) ? true : false); + } + else + { + ::ResetEvent(m_conditionPreVista); + MutexUnlock(mutex); + DWORD iWaitReturn = ::WaitForSingleObject(m_conditionPreVista, iTimeoutMs); + MutexLock(mutex); + return (iWaitReturn == 0); + } +} diff --git a/src/lib/platform/windows/os-threads.h b/src/lib/platform/windows/os-threads.h index e082691..3714c16 100644 --- a/src/lib/platform/windows/os-threads.h +++ b/src/lib/platform/windows/os-threads.h @@ -47,109 +47,16 @@ namespace PLATFORM // windows vista+ conditions typedef VOID (WINAPI *ConditionArg) (CONDITION_VARIABLE*); typedef BOOL (WINAPI *ConditionMutexArg)(CONDITION_VARIABLE*, CRITICAL_SECTION*, DWORD); - static ConditionArg g_InitializeConditionVariable; - static ConditionArg g_WakeConditionVariable; - static ConditionArg g_WakeAllConditionVariable; - static ConditionMutexArg g_SleepConditionVariableCS; - - // check whether vista+ conditions are available at runtime - static bool CheckVistaConditionFunctions(void) - { - static int iHasVistaConditionFunctions(-1); - if (iHasVistaConditionFunctions == -1) - { - HMODULE handle = GetModuleHandle("Kernel32"); - if (handle == NULL) - { - iHasVistaConditionFunctions = 0; - } - else - { - g_InitializeConditionVariable = (ConditionArg) GetProcAddress(handle,"InitializeConditionVariable"); - g_WakeConditionVariable = (ConditionArg) GetProcAddress(handle,"WakeConditionVariable"); - g_WakeAllConditionVariable = (ConditionArg) GetProcAddress(handle,"WakeAllConditionVariable"); - g_SleepConditionVariableCS = (ConditionMutexArg)GetProcAddress(handle,"SleepConditionVariableCS"); - - // 1 when everything is resolved, 0 otherwise - iHasVistaConditionFunctions = g_InitializeConditionVariable && - g_WakeConditionVariable && - g_WakeAllConditionVariable && - g_SleepConditionVariableCS ? 1 : 0; - } - } - return iHasVistaConditionFunctions == 1; - } class CConditionImpl { public: - CConditionImpl(void) - { - m_bOnVista = CheckVistaConditionFunctions(); - if (m_bOnVista) - (*g_InitializeConditionVariable)(m_conditionVista = new CONDITION_VARIABLE); - else - m_conditionPreVista = ::CreateEvent(NULL, TRUE, FALSE, NULL); - } - - virtual ~CConditionImpl(void) - { - if (m_bOnVista) - delete m_conditionVista; - else - ::CloseHandle(m_conditionPreVista); - } - - void Signal(void) - { - if (m_bOnVista) - (*g_WakeConditionVariable)(m_conditionVista); - else - ::SetEvent(m_conditionPreVista); - } - - void Broadcast(void) - { - if (m_bOnVista) - (*g_WakeAllConditionVariable)(m_conditionVista); - else - ::SetEvent(m_conditionPreVista); - } - - bool Wait(mutex_t &mutex) - { - if (m_bOnVista) - { - return ((*g_SleepConditionVariableCS)(m_conditionVista, mutex, INFINITE) ? true : false); - } - else - { - ::ResetEvent(m_conditionPreVista); - MutexUnlock(mutex); - DWORD iWaitReturn = ::WaitForSingleObject(m_conditionPreVista, 1000); - MutexLock(mutex); - return (iWaitReturn == 0); - } - } - - bool Wait(mutex_t &mutex, uint32_t iTimeoutMs) - { - if (iTimeoutMs == 0) - return Wait(mutex); - - if (m_bOnVista) - { - return ((*g_SleepConditionVariableCS)(m_conditionVista, mutex, iTimeoutMs) ? true : false); - } - else - { - ::ResetEvent(m_conditionPreVista); - MutexUnlock(mutex); - DWORD iWaitReturn = ::WaitForSingleObject(m_conditionPreVista, iTimeoutMs); - MutexLock(mutex); - return (iWaitReturn == 0); - } - } + CConditionImpl(void); + virtual ~CConditionImpl(void); + void Signal(void); + void Broadcast(void); + bool Wait(mutex_t &mutex); + bool Wait(mutex_t &mutex, uint32_t iTimeoutMs); bool m_bOnVista; CONDITION_VARIABLE *m_conditionVista; -- 2.34.1