Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #3145 from jimfcarroll/removexp

Remove the Xp specific threading code.
  • Loading branch information...
commit bcf99dc264c6a8b9b91ab625b9f92b5bfe04e3bb 2 parents 2b2e2d1 + 331c04e
@MartijnKaijser MartijnKaijser authored
View
1  project/VS2010Express/XbmcThreads.vcxproj
@@ -19,7 +19,6 @@
<ClInclude Include="..\..\xbmc\threads\platform\win\ThreadImpl.cpp" />
<ClInclude Include="..\..\xbmc\threads\platform\ThreadImpl.cpp" />
<ClCompile Include="..\..\xbmc\threads\platform\Implementation.cpp" />
- <ClInclude Include="..\..\xbmc\threads\platform\win\Implementation.cpp" />
<ClCompile Include="..\..\xbmc\threads\platform\win\Win32Exception.cpp" />
<ClCompile Include="..\..\xbmc\threads\SystemClock.cpp" />
<ClCompile Include="..\..\xbmc\threads\Thread.cpp" />
View
3  project/VS2010Express/XbmcThreads.vcxproj.filters
@@ -58,9 +58,6 @@
<ClInclude Include="..\..\xbmc\threads\platform\ThreadImpl.cpp">
<Filter>platform</Filter>
</ClInclude>
- <ClInclude Include="..\..\xbmc\threads\platform\win\Implementation.cpp">
- <Filter>platform\win</Filter>
- </ClInclude>
<ClInclude Include="..\..\xbmc\threads\platform\win\Win32Exception.h">
<Filter>platform\win</Filter>
</ClInclude>
View
26 xbmc/threads/Lockables.h
@@ -63,21 +63,31 @@ namespace XbmcThreads
/**
* This implements the "exitable" behavior mentioned above.
+ *
+ * This can be used to ALMOST exit, but not quite, by passing
+ * the number of locks to leave. This is used in the windows
+ * ConditionVariable which requires that the lock be entered
+ * only once, and so it backs out ALMOST all the way, but
+ * leaves one still there.
*/
- inline unsigned int exit()
+ inline unsigned int exit(unsigned int leave = 0)
{
// it's possibe we don't actually own the lock
// so we will try it.
unsigned int ret = 0;
if (try_lock())
{
- ret = count - 1; // The -1 is because we don't want
- // to count the try_lock increment.
- // We must NOT compare "count" in this loop since
- // as soon as the last unlock is called another thread
- // can modify it.
- for (unsigned int i = 0; i <= ret; i++) // This will also unlock the try_lock.
- unlock();
+ if (leave < (count - 1))
+ {
+ ret = count - 1 - leave; // The -1 is because we don't want
+ // to count the try_lock increment.
+ // We must NOT compare "count" in this loop since
+ // as soon as the last unlock is called another thread
+ // can modify it.
+ for (unsigned int i = 0; i < ret; i++)
+ unlock();
+ }
+ unlock(); // undo the try_lock before returning
}
return ret;
View
2  xbmc/threads/platform/Implementation.cpp
@@ -20,6 +20,4 @@
#if (defined TARGET_POSIX)
#include "threads/platform/pthreads/Implementation.cpp"
-#elif (defined TARGET_WINDOWS)
-#include "threads/platform/win/Implementation.cpp"
#endif
View
237 xbmc/threads/platform/win/Condition.h
@@ -27,227 +27,46 @@
namespace XbmcThreads
{
- class ConditionVariable;
-
- namespace intern
+ /**
+ * This is condition variable implementation that uses the underlying
+ * Windows mechanisms and assumes Vista (or later)
+ */
+ class ConditionVariable : public NonCopyable
{
- /**
- * ConditionVariableXp is effectively a condition variable implementation
- * assuming we're on Windows XP or earlier. This means we don't have
- * access to InitializeConditionVariable and that the structure
- * CONDITION_VARIABLE doesnt actually exist.
- *
- * This code is basically copied from SDL_syscond.c but structured to use
- * native windows threading primitives rather than other SDL primitives.
- */
- class ConditionVariableXp : public NonCopyable
- {
- friend class ConditionVariable;
- CCriticalSection lock;
- int waiting;
- int signals;
-
- class Semaphore
- {
- friend class ConditionVariableXp;
- HANDLE sem;
- volatile LONG count;
-
- inline Semaphore() : count(0L), sem(NULL) { }
- inline ~Semaphore() { if (sem) CloseHandle(sem); }
-
- inline void Init() { sem = CreateSemaphore(NULL,0,32*1024,NULL); }
-
- inline bool wait(DWORD dwMilliseconds)
- {
- return (WAIT_OBJECT_0 == WaitForSingleObject(sem, dwMilliseconds)) ?
- (InterlockedDecrement(&count), true) : false;
- }
-
- inline bool post()
- {
- /* Increase the counter in the first place, because
- * after a successful release the semaphore may
- * immediately get destroyed by another thread which
- * is waiting for this semaphore.
- */
- InterlockedIncrement(&count);
- return ReleaseSemaphore(sem, 1, NULL) ? true : (InterlockedDecrement(&count), false);
- }
- };
-
- Semaphore wait_sem;
- Semaphore wait_done;
-
- inline ConditionVariableXp() : waiting(0), signals(0) { }
- inline ~ConditionVariableXp() {}
-
- inline void Init() { wait_sem.Init(); wait_done.Init(); }
-
- inline void wait(CCriticalSection& mutex)
- {
- wait(mutex,(unsigned long)-1L);
- }
-
- inline bool wait(CCriticalSection& mutex, unsigned long milliseconds)
- {
- bool success = false;
- DWORD ms = ((unsigned long)-1L) == milliseconds ? INFINITE : (DWORD)milliseconds;
-
- {
- CSingleLock l(lock);
- waiting++;
- }
-
- {
- CSingleExit ex(mutex);
- success = wait_sem.wait(ms);
-
- {
- CSingleLock l(lock);
- if (signals > 0)
- {
- if (!success)
- wait_sem.wait(INFINITE);
- wait_done.post();
- --signals;
- }
- --waiting;
- }
- }
-
- return success;
- }
-
-
- inline void wait(CSingleLock& lock) { wait(lock.get_underlying()); }
- inline bool wait(CSingleLock& lock, unsigned long milliseconds) { return wait(lock.get_underlying(), milliseconds); }
-
- inline void notifyAll()
- {
- /* If there are waiting threads not already signalled, then
- signal the condition and wait for the thread to respond.
- */
- CSingleLock l(lock);
- if ( waiting > signals )
- {
- int i, num_waiting;
-
- num_waiting = (waiting - signals);
- signals = waiting;
- for ( i=0; i<num_waiting; ++i )
- wait_sem.post();
-
- /* Now all released threads are blocked here, waiting for us.
- Collect them all (and win fabulous prizes!) :-)
- */
- l.Leave();
- for ( i=0; i<num_waiting; ++i )
- wait_done.wait(INFINITE);
- }
- }
+ CONDITION_VARIABLE cond;
- inline void notify()
- {
- /* If there are waiting threads not already signalled, then
- signal the condition and wait for the thread to respond.
- */
- CSingleLock l(lock);
- if ( waiting > signals )
- {
- ++signals;
- wait_sem.post();
- l.Leave();
- wait_done.wait(INFINITE);
- }
- }
- };
-
- /**
- * This is condition variable implementation that uses the Vista (or later)
- * windows api but it is safe to compile, link, and load on Xp.
- */
- class ConditionVariableVista : public NonCopyable
+ // SleepConditionVarialbeCS requires the condition variable be entered
+ // only once.
+ struct AlmostExit
{
- friend class ConditionVariable;
-
- CONDITION_VARIABLE cond;
-
- typedef VOID (WINAPI *TakesCV)(PCONDITION_VARIABLE);
- typedef BOOL (WINAPI *SleepCVCS)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD);
-
- static bool setConditionVarFuncs();
- static TakesCV InitializeConditionVariableProc;
- static SleepCVCS SleepConditionVariableCSProc;
- static TakesCV WakeConditionVariableProc;
- static TakesCV WakeAllConditionVariableProc;
-
- inline ConditionVariableVista() { }
-
- inline void Init() { (*InitializeConditionVariableProc)(&cond); }
-
- // apparently, windows condition variables do not need to be deleted
- inline ~ConditionVariableVista() { }
-
- inline void wait(CCriticalSection& lock)
- {
- // even the windows implementation is capable of spontaneous wakes
- (*SleepConditionVariableCSProc)(&cond,&lock.get_underlying().mutex,INFINITE);
- }
-
- inline bool wait(CCriticalSection& lock, unsigned long milliseconds)
- {
- return (*SleepConditionVariableCSProc)(&cond,&lock.get_underlying().mutex,milliseconds) ? true : false;
- }
-
- inline void wait(CSingleLock& lock) { wait(lock.get_underlying()); }
- inline bool wait(CSingleLock& lock, unsigned long milliseconds) { return wait(lock.get_underlying(), milliseconds); }
- inline void notifyAll() { (*WakeAllConditionVariableProc)(&cond); }
- inline void notify() { (*WakeConditionVariableProc)(&cond); }
+ unsigned int count;
+ CCriticalSection& cc;
+ inline AlmostExit(CCriticalSection& pcc) : count(pcc.exit(1)), cc(pcc) { cc.count = 0; }
+ inline ~AlmostExit() { cc.count = 1; cc.restore(count); }
};
- }
-#define XBMC_CV(func) if (isVista) vistaimpl. func ;else xpimpl. func
-#define XBMC_RCV(func) (isVista ? vistaimpl. func : xpimpl. func )
- class ConditionVariable : public NonCopyable
- {
- // stupid hack for statics
- static bool isIsVistaSet;
- static bool isVista;
- static bool getIsVista();
- intern::ConditionVariableXp xpimpl;
- intern::ConditionVariableVista vistaimpl;
public:
- inline ConditionVariable()
- {
- if (isIsVistaSet ? isVista : getIsVista())
- vistaimpl.Init();
- else
- xpimpl.Init();
- }
+ inline ConditionVariable() { InitializeConditionVariable(&cond); }
- inline void wait(CCriticalSection& lock)
- {
- int count = lock.count;
- lock.count = 0;
- XBMC_CV(wait(lock));
- lock.count = count;
+ // apparently, windows condition variables do not need to be deleted
+ inline ~ConditionVariable() { }
+
+ inline void wait(CCriticalSection& lock)
+ {
+ AlmostExit ae(lock);
+ // even the windows implementation is capable of spontaneous wakes
+ SleepConditionVariableCS(&cond,&lock.get_underlying().mutex,INFINITE);
}
- inline bool wait(CCriticalSection& lock, unsigned long milliseconds)
- {
- int count = lock.count;
- lock.count = 0;
- bool res = XBMC_RCV(wait(lock, milliseconds));
- lock.count = count;
- return res;
+ inline bool wait(CCriticalSection& lock, unsigned long milliseconds)
+ {
+ AlmostExit ae(lock);
+ return SleepConditionVariableCS(&cond,&lock.get_underlying().mutex,milliseconds) ? true : false;
}
inline void wait(CSingleLock& lock) { wait(lock.get_underlying()); }
inline bool wait(CSingleLock& lock, unsigned long milliseconds) { return wait(lock.get_underlying(), milliseconds); }
-
-
- inline void notifyAll() { XBMC_CV(notifyAll()); }
- inline void notify() { XBMC_CV(notify()); }
+ inline void notifyAll() { WakeAllConditionVariable(&cond); }
+ inline void notify() { WakeConditionVariable(&cond); }
};
}
View
11 xbmc/threads/platform/win/CriticalSection.h
@@ -27,12 +27,8 @@
namespace XbmcThreads
{
- namespace intern
- {
- // forward declare in preparation for the friend declaration
- class ConditionVariableVista;
- class ConditionVariableXp;
- }
+ // forward declare in preparation for the friend declaration
+ class ConditionVariable;
namespace windows
{
@@ -41,8 +37,7 @@ namespace XbmcThreads
CRITICAL_SECTION mutex;
// needs acces to 'mutex'
- friend class XbmcThreads::intern::ConditionVariableVista;
- friend class XbmcThreads::intern::ConditionVariableXp;
+ friend class XbmcThreads::ConditionVariable;
public:
inline RecursiveMutex()
{
View
68 xbmc/threads/platform/win/Implementation.cpp
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2005-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; 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, 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 XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "threads/Condition.h"
-
-namespace XbmcThreads
-{
-
- namespace intern
- {
- ConditionVariableVista::TakesCV ConditionVariableVista::InitializeConditionVariableProc;
- ConditionVariableVista::SleepCVCS ConditionVariableVista::SleepConditionVariableCSProc;
- ConditionVariableVista::TakesCV ConditionVariableVista::WakeConditionVariableProc;
- ConditionVariableVista::TakesCV ConditionVariableVista::WakeAllConditionVariableProc;
-
- bool ConditionVariableVista::setConditionVarFuncs()
- {
- HMODULE mod = GetModuleHandle("Kernel32");
-
- if (mod == NULL)
- return false;
-
- InitializeConditionVariableProc = (TakesCV)GetProcAddress(mod,"InitializeConditionVariable");
- if (InitializeConditionVariableProc == NULL)
- return false;
-
- SleepConditionVariableCSProc = (SleepCVCS)GetProcAddress(mod,"SleepConditionVariableCS");
- WakeAllConditionVariableProc = (TakesCV)GetProcAddress(mod,"WakeAllConditionVariable");
- WakeConditionVariableProc = (TakesCV)GetProcAddress(mod,"WakeConditionVariable");
-
- return SleepConditionVariableCSProc != NULL &&
- WakeAllConditionVariableProc != NULL &&
- WakeConditionVariableProc != NULL;
- }
- }
-
- bool ConditionVariable::getIsVista()
- {
- if (!isIsVistaSet)
- {
- isVista = intern::ConditionVariableVista::setConditionVarFuncs();
- isIsVistaSet = true;
- }
-
- return isVista;
- }
-
- bool ConditionVariable::isVista = getIsVista();
- // bss segment nulled out by loader.
- bool ConditionVariable::isIsVistaSet;
-}

2 comments on commit bcf99dc

@MartijnKaijser

minimum installer requirements 6f165fd or do you mean something else?

edit:
gracefully shutting down when trying to run on XP should still be added. but for now we already prevent from installing in the first place

@MartijnKaijser

@Skixbmc
see #3173

Please sign in to comment.
Something went wrong with that request. Please try again.