aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Carroll <thecarrolls@jiminger.com>2011-06-10 20:44:26 -0400
committerJim Carroll <thecarrolls@jiminger.com>2011-06-23 10:15:25 -0400
commit16a725f0c87dc8ad1dc7925e2bc52e7ff0c049a6 (patch)
treea1b6de8d5eecf17304fa232eeb828faab87afa53
parent62171b3f0be07ba706a777c9c3f64fd3c06f711d (diff)
Removed emu_* threading code which wasn't being used anyway.
Moved the mutex and guard classes to boost.
-rw-r--r--configure.in2
-rw-r--r--xbmc/cores/DllLoader/exports/emu_kernel32.cpp141
-rw-r--r--xbmc/cores/DllLoader/exports/emu_kernel32.h9
-rw-r--r--xbmc/cores/DllLoader/exports/emu_msvcrt.cpp16
-rw-r--r--xbmc/linux/Makefile.in1
-rw-r--r--xbmc/threads/CriticalSection.cpp49
-rw-r--r--xbmc/threads/CriticalSection.h104
-rw-r--r--xbmc/threads/Makefile5
-rw-r--r--xbmc/threads/SharedSection.cpp187
-rw-r--r--xbmc/threads/SharedSection.h81
-rw-r--r--xbmc/threads/SingleLock.cpp112
-rw-r--r--xbmc/threads/SingleLock.h69
12 files changed, 137 insertions, 639 deletions
diff --git a/configure.in b/configure.in
index 68fbc7d2b5..c0920a0fb5 100644
--- a/configure.in
+++ b/configure.in
@@ -532,6 +532,7 @@ AC_CHECK_HEADER([sys/inotify.h], AC_DEFINE([HAVE_INOTIFY],[1],[Define if we have
# Checks for boost headers using CXX instead of CC
AC_LANG_PUSH([C++])
AC_CHECK_HEADER([boost/shared_ptr.hpp],, AC_MSG_ERROR($missing_library))
+AC_CHECK_HEADER([boost/thread.hpp],, AC_MSG_ERROR($missing_library))
AC_LANG_POP([C++])
# Checks for platforms libraries.
@@ -604,6 +605,7 @@ AC_CHECK_LIB([ssh], [sftp_tell64],, AC_MSG_RESULT([Could not find suitab
AC_CHECK_LIB([smbclient], [main],, AC_MSG_ERROR($missing_library))
AC_CHECK_LIB([bluetooth], [hci_devid],, AC_MSG_RESULT([Could not find suitable version of libbluetooth]))
AC_CHECK_LIB([yajl], [main],, AC_MSG_ERROR($missing_library))
+AC_CHECK_LIB([boost_thread],[main],, AC_MSG_ERROR($missing_library))
PKG_CHECK_MODULES([FONTCONFIG], [fontconfig],
[INCLUDES="$INCLUDES $FONTCONFIG_CFLAGS"; LIBS="$LIBS $FONTCONFIG_LIBS"],
AC_MSG_ERROR($missing_library))
diff --git a/xbmc/cores/DllLoader/exports/emu_kernel32.cpp b/xbmc/cores/DllLoader/exports/emu_kernel32.cpp
index 0a0bb81055..f9a9cc0c1a 100644
--- a/xbmc/cores/DllLoader/exports/emu_kernel32.cpp
+++ b/xbmc/cores/DllLoader/exports/emu_kernel32.cpp
@@ -226,93 +226,11 @@ struct SThreadWrapper
PCHAR lpDLL;
};
-#ifdef _DEBUG
-#define MS_VC_EXCEPTION 0x406d1388
-typedef struct tagTHREADNAME_INFO
-{
- DWORD dwType; // must be 0x1000
- LPCSTR szName; // pointer to name (in same addr space)
- DWORD dwThreadID; // thread ID (-1 caller thread)
- DWORD dwFlags; // reserved for future use, most be zero
-} THREADNAME_INFO;
-#endif
-
-#ifdef _LINUX
-int dllThreadWrapper(LPVOID lpThreadParameter)
-#else
-unsigned int __stdcall dllThreadWrapper(LPVOID lpThreadParameter)
-#endif
-{
- SThreadWrapper *param = (SThreadWrapper*)lpThreadParameter;
- DWORD result;
-
-#if defined(_DEBUG) && !defined(_LINUX)
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = "DLL";
- info.dwThreadID = ::GetCurrentThreadId();
- info.dwFlags = 0;
- __try
- {
- RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info);
- }
- __except (EXCEPTION_CONTINUE_EXECUTION)
- {
- }
-#endif
-
- __try
- {
- result = param->lpStartAddress(param->lpParameter);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- CLog::Log(LOGERROR, "DLL:%s - Unhandled exception in thread created by dll", param->lpDLL );
- result = 0;
- }
-
- delete param;
- return result;
-
-}
-
-extern "C" HANDLE WINAPI dllCreateThread(
- LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
- DWORD dwStackSize, // initial stack size
- LPTHREAD_START_ROUTINE lpStartAddress, // thread function
- LPVOID lpParameter, // thread argument
- DWORD dwCreationFlags, // creation option
- LPDWORD lpThreadId // thread identifier
-)
-{
- uintptr_t loc = (uintptr_t)_ReturnAddress();
-
- SThreadWrapper *param = new SThreadWrapper;
- param->lpStartAddress = lpStartAddress;
- param->lpParameter = lpParameter;
- param->lpDLL = tracker_getdllname(loc);
-
- return (HANDLE)_beginthreadex(lpThreadAttributes, dwStackSize, dllThreadWrapper, param, dwCreationFlags, (unsigned int *)lpThreadId);
-}
-
-
-extern "C" BOOL WINAPI dllTerminateThread(HANDLE tHread, DWORD dwExitCode)
-{
- not_implement("kernel32.dll fake function TerminateThread called\n"); //warning
- return TRUE;
-}
-
extern "C" void WINAPI dllSleep(DWORD dwTime)
{
return ::Sleep(dwTime);
}
-extern "C" HANDLE WINAPI dllGetCurrentThread(void)
-{
- HANDLE retval = GetCurrentThread();
- return retval;
-}
-
extern "C" DWORD WINAPI dllGetCurrentProcessId(void)
{
#ifdef _LINUX
@@ -414,65 +332,6 @@ extern "C" UINT WINAPI dllGetPrivateProfileIntA(
return nDefault;
}
-//globals for memory leak hack, no need for well-behaved dlls call init/del in pair
-//We can free the sections if applications does not call deletecriticalsection
-//need to initialize the list head NULL at mplayer_open_file, and free memory at close file.
-std::map<LPCRITICAL_SECTION, LPCRITICAL_SECTION> g_mapCriticalSection;
-
-extern "C" void WINAPI dllDeleteCriticalSection(LPCRITICAL_SECTION cs)
-{
-#ifdef API_DEBUG
- CLog::Log(LOGDEBUG, "DeleteCriticalSection(0x%x)", cs);
-#endif
- if (g_mapCriticalSection.find(cs) != g_mapCriticalSection.end())
- {
- LPCRITICAL_SECTION cs_new = g_mapCriticalSection[cs];
- DeleteCriticalSection(cs_new);
- delete cs_new;
- g_mapCriticalSection.erase(cs);
- }
-}
-
-extern "C" void WINAPI dllInitializeCriticalSection(LPCRITICAL_SECTION cs)
-{
-#ifdef API_DEBUG
- CLog::Log(LOGDEBUG, "InitializeCriticalSection(0x%x)", cs);
-#endif
- LPCRITICAL_SECTION cs_new = new CRITICAL_SECTION;
- memset(cs_new, 0, sizeof(CRITICAL_SECTION));
- InitializeCriticalSection(cs_new);
-
- // just take the first member of the CRITICAL_SECTION to save ourdata in, this will be used to
- // get fast access to the new critial section in dllLeaveCriticalSection and dllEnterCriticalSection
- ((LPCRITICAL_SECTION*)cs)[0] = cs_new;
- g_mapCriticalSection[cs] = cs_new;
-}
-
-extern "C" void WINAPI dllLeaveCriticalSection(LPCRITICAL_SECTION cs)
-{
-#ifdef API_DEBUG
- CLog::Log(LOGDEBUG, "LeaveCriticalSection(0x%x) %p\n", ((LPCRITICAL_SECTION*)cs)[0]);
-#endif
- LeaveCriticalSection(((LPCRITICAL_SECTION*)cs)[0]);
-}
-
-extern "C" void WINAPI dllEnterCriticalSection(LPCRITICAL_SECTION cs)
-{
-#ifdef API_DEBUG
- CLog::Log(LOGDEBUG, "EnterCriticalSection(0x%x) %p\n", cs, ((LPCRITICAL_SECTION*)cs)[0]);
-#endif
-#ifndef _LINUX
- if (!(LPCRITICAL_SECTION)cs->OwningThread)
- {
-#ifdef API_DEBUG
- CLog::Log(LOGDEBUG, "entered uninitialized critisec!\n");
-#endif
- dllInitializeCriticalSection(cs);
- }
-#endif
- EnterCriticalSection(((LPCRITICAL_SECTION*)cs)[0]);
-}
-
extern "C" DWORD WINAPI dllGetVersion()
{
#ifdef API_DEBUG
diff --git a/xbmc/cores/DllLoader/exports/emu_kernel32.h b/xbmc/cores/DllLoader/exports/emu_kernel32.h
index 459cf47fef..a1639a9df6 100644
--- a/xbmc/cores/DllLoader/exports/emu_kernel32.h
+++ b/xbmc/cores/DllLoader/exports/emu_kernel32.h
@@ -598,10 +598,6 @@ extern "C" BOOL WINAPI dllFindClose(HANDLE hFile);
extern "C" UINT WINAPI dllGetAtomNameA( ATOM nAtom, LPTSTR lpBuffer, int nSize);
extern "C" ATOM WINAPI dllFindAtomA( LPCTSTR lpString);
extern "C" ATOM WINAPI dllAddAtomA( LPCTSTR lpString);
-extern "C" HANDLE WINAPI dllCreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
-extern "C" BOOL WINAPI dllTerminateThread(HANDLE tHread, DWORD dwExitCode);
-extern "C" HANDLE WINAPI dllGetCurrentThread(void);
-extern "C" DWORD WINAPI dllGetCurrentThreadId(VOID);
extern "C" DWORD WINAPI dllGetCurrentProcessId(void);
extern "C" BOOL WINAPI dllDisableThreadLibraryCalls(HMODULE);
@@ -621,11 +617,6 @@ extern "C" void WINAPI dllGetSystemInfo(LPSYSTEM_INFO lpSystemInfo);
extern "C" UINT WINAPI dllGetPrivateProfileIntA(LPCSTR lpAppName, LPCSTR lpKeyName,
INT nDefault, LPCSTR lpFileName);
-extern "C" void WINAPI dllDeleteCriticalSection(LPCRITICAL_SECTION cs);
-extern "C" void WINAPI dllInitializeCriticalSection(LPCRITICAL_SECTION cs);
-extern "C" void WINAPI dllLeaveCriticalSection(LPCRITICAL_SECTION cs);
-extern "C" void WINAPI dllEnterCriticalSection(LPCRITICAL_SECTION cs);
-
extern "C" BOOL WINAPI dllGetVersionExA(LPOSVERSIONINFO lpVersionInfo);
extern "C" BOOL WINAPI dllGetVersionExW(LPOSVERSIONINFOW lpVersionInfo);
extern "C" DWORD WINAPI dllGetVersion();
diff --git a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
index 204675d58d..aea6f1e47d 100644
--- a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
+++ b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
@@ -1705,22 +1705,6 @@ extern "C"
return 0;
}
- uintptr_t dll_beginthread(
- void( *start_address )( void * ),
- unsigned stack_size,
- void *arglist
- )
- {
- return _beginthread(start_address, stack_size, arglist);
- }
-
- HANDLE dll_beginthreadex(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize,
- LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags,
- LPDWORD lpThreadId)
- {
- return dllCreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
- }
-
//SLOW CODE SHOULD BE REVISED
int dll_stat(const char *path, struct stat *buffer)
{
diff --git a/xbmc/linux/Makefile.in b/xbmc/linux/Makefile.in
index 8dae7d43cf..c3a5877fdd 100644
--- a/xbmc/linux/Makefile.in
+++ b/xbmc/linux/Makefile.in
@@ -10,7 +10,6 @@ SRCS=ConvUtils.cpp \
LinuxResourceCounter.cpp \
LinuxTimezone.cpp \
PosixMountProvider.cpp \
- XCriticalSection.cpp \
XEventUtils.cpp \
XFileUtils.cpp \
XHandle.cpp \
diff --git a/xbmc/threads/CriticalSection.cpp b/xbmc/threads/CriticalSection.cpp
deleted file mode 100644
index 5e5374e2d7..0000000000
--- a/xbmc/threads/CriticalSection.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-* XBMC Media Center
-* Copyright (c) 2002 Frodo
-* Portions Copyright (c) by the authors of ffmpeg and xvid
-*
-* 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "CriticalSection.h"
-
-//////////////////////////////////////////////////////////////////////
-CCriticalSection::CCriticalSection()
-{
- m_criticalSection.Initialize();
-}
-
-//////////////////////////////////////////////////////////////////////
-CCriticalSection::~CCriticalSection()
-{
- m_criticalSection.Destroy();
-}
-
-// The C API.
-void InitializeCriticalSection(CCriticalSection* section) { section->getCriticalSection().Initialize(); }
-void DeleteCriticalSection(CCriticalSection* section) { section->getCriticalSection().Destroy(); }
-BOOL OwningCriticalSection(CCriticalSection* section) { return section->getCriticalSection().Owning(); }
-DWORD ExitCriticalSection(CCriticalSection* section) { return section->getCriticalSection().Exit(); }
-void RestoreCriticalSection(CCriticalSection* section, DWORD count) { return section->getCriticalSection().Restore(count); }
-void EnterCriticalSection(CCriticalSection* section) { section->getCriticalSection().Enter(); }
-void LeaveCriticalSection(CCriticalSection* section) { section->getCriticalSection().Leave(); }
-
-void EnterCriticalSection(CCriticalSection& section) { section.getCriticalSection().Enter(); }
-void LeaveCriticalSection(CCriticalSection& section) { section.getCriticalSection().Leave(); }
-BOOL OwningCriticalSection(CCriticalSection& section) { return section.getCriticalSection().Owning(); }
-DWORD ExitCriticalSection(CCriticalSection& section) { return section.getCriticalSection().Exit(); }
-void RestoreCriticalSection(CCriticalSection& section, DWORD count) { return section.getCriticalSection().Restore(count); }
-
diff --git a/xbmc/threads/CriticalSection.h b/xbmc/threads/CriticalSection.h
index a574b85cc3..da7c8867ae 100644
--- a/xbmc/threads/CriticalSection.h
+++ b/xbmc/threads/CriticalSection.h
@@ -3,19 +3,8 @@
// CriticalSection.h: interface for the CCriticalSection class.
//
//////////////////////////////////////////////////////////////////////
-#ifndef _CRITICAL_SECTION_H_
-#define _CRITICAL_SECTION_H_
-#if _MSC_VER > 1000
#pragma once
-#endif // _MSC_VER > 1000
-#ifdef _LINUX
-#include "PlatformDefs.h"
-#include "linux/XSyncUtils.h"
-#include "XCriticalSection.h"
-#else
-#include "win32/XCriticalSection.h"
-#endif
/*
* Copyright (C) 2005-2008 Team XBMC
@@ -38,37 +27,78 @@
*
*/
-class CCriticalSection
+#include <boost/thread/recursive_mutex.hpp>
+
+/**
+ * Because there are several different Lockable schemes we use, this
+ * template extends the boost behavior and adds some xbmc assumptions
+ * mainly that a CriticalSection (or SharedSection) is "exitable."
+ *
+ * "Exitable" specifially means that, no matter how deep the recursion
+ * on the mutex/critical section, we can exit from it and then restore
+ * the state.
+ *
+ * This requires us to extend boost so that we can keep track of the
+ * number of locks that have been recursively acquired so that we can
+ * undo it, and then restore that (See class CSingleExit).
+ *
+ * This implements boost's "Lockable concept" which simply means that
+ * it has the three methods:
+ *
+ * lock();
+ * try_lock();
+ * unlock();
+ */
+template<class L> class CountingLockable
{
+protected:
+ L m;
+ unsigned int count;
+
public:
- // Constructor/destructor.
- CCriticalSection();
- virtual ~CCriticalSection();
+ inline CountingLockable() : count(0) {}
- XCriticalSection& getCriticalSection() { return m_criticalSection; }
+ // boost::thread Lockable concept
+ inline void lock() { m.lock(); count++; }
+ inline bool try_lock() { return m.try_lock() ? count++, true : false; }
+ inline void unlock() { count--; m.unlock(); }
-private:
- XCriticalSection m_criticalSection;
+ /**
+ * This implements the "exitable" behavior mentioned above.
+ */
+ inline unsigned int exit()
+ {
+ // it's possibe we don't actually own the lock
+ // so we will try it.
+ unsigned int ret = count;
+ if (try_lock())
+ {
+ unlock(); // unlock the try_lock
+ for (unsigned int i = 0; i < ret; i++)
+ unlock();
+ }
+ else
+ ret = 0;
- //don't allow copying a CCriticalSection
- CCriticalSection(const CCriticalSection& section) {}
- CCriticalSection& operator=(const CCriticalSection& section) {return *this;}
-};
+ return ret;
+ }
-// The CCritical section overloads.
-void InitializeCriticalSection(CCriticalSection* section);
-void DeleteCriticalSection(CCriticalSection* section);
-BOOL OwningCriticalSection(CCriticalSection* section);
-DWORD ExitCriticalSection(CCriticalSection* section);
-void RestoreCriticalSection(CCriticalSection* section, DWORD count);
-void EnterCriticalSection(CCriticalSection* section);
-void LeaveCriticalSection(CCriticalSection* section);
+ /**
+ * Restore a previous exit to the provided level.
+ */
+ inline void restore(unsigned int restoreCount)
+ {
+ for (unsigned int i = 0; i < restoreCount; i++)
+ lock();
+ }
+};
-// And a few special ones.
-void EnterCriticalSection(CCriticalSection& section);
-void LeaveCriticalSection(CCriticalSection& section);
-BOOL OwningCriticalSection(CCriticalSection& section);
-DWORD ExitCriticalSection(CCriticalSection& section);
-void RestoreCriticalSection(CCriticalSection& section, DWORD count);
+/**
+ * A CCriticalSection is a CountingLockable whose implementation is a boost
+ * recursive_mutex.
+ *
+ * This is not a typedef because of a number of "class CCriticalSection;"
+ * forward declarations in the code that break when it's done that way.
+ */
+class CCriticalSection : public CountingLockable<boost::recursive_mutex> {};
-#endif
diff --git a/xbmc/threads/Makefile b/xbmc/threads/Makefile
index 7c6a22d4e8..bf64ddb51a 100644
--- a/xbmc/threads/Makefile
+++ b/xbmc/threads/Makefile
@@ -1,11 +1,8 @@
SRCS=Atomics.cpp \
- CriticalSection.cpp \
Event.cpp \
- LockFree.cpp \
Mutex.cpp \
+ LockFree.cpp \
Semaphore.cpp \
- SharedSection.cpp \
- SingleLock.cpp \
Thread.cpp \
XBMC_mutex.cpp \
diff --git a/xbmc/threads/SharedSection.cpp b/xbmc/threads/SharedSection.cpp
deleted file mode 100644
index b82b4d1e44..0000000000
--- a/xbmc/threads/SharedSection.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2005-2008 Team XBMC
- * http://www.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, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "SharedSection.h"
-
-#define MAXSHAREDACCESSES 5000
-
-CSharedSection::CSharedSection()
-{
- m_sharedLock = 0;
- m_exclusive = false;
- InitializeCriticalSection(&m_critSection);
- m_eventFree = CreateEvent(NULL, TRUE, FALSE, NULL);
-}
-
-CSharedSection::~CSharedSection()
-{
- DeleteCriticalSection(&m_critSection);
- CloseHandle(m_eventFree);
-}
-
-void CSharedSection::EnterShared()
-{
- EnterCriticalSection(&m_critSection);
- ResetEvent(m_eventFree);
- m_sharedLock++;
- LeaveCriticalSection(&m_critSection);
-}
-
-void CSharedSection::LeaveShared()
-{
- EnterCriticalSection(&m_critSection);
- m_sharedLock--;
- if (m_sharedLock == 0)
- {
- LeaveCriticalSection(&m_critSection);
- SetEvent(m_eventFree);
- return;
- }
- LeaveCriticalSection(&m_critSection);
-}
-
-void CSharedSection::EnterExclusive()
-{
- EnterCriticalSection(&m_critSection);
- while( m_sharedLock != 0 )
- {
- LeaveCriticalSection(&m_critSection);
- WaitForSingleObject(m_eventFree, INFINITE);
- EnterCriticalSection(&m_critSection);
- }
-
- m_exclusive = true;
-}
-
-void CSharedSection::LeaveExclusive()
-{
- m_exclusive = false;
- LeaveCriticalSection(&m_critSection);
-}
-
-//////////////////////////////////////////////////////////////////////
-// SharedLock
-//////////////////////////////////////////////////////////////////////
-
-CSharedLock::CSharedLock(CSharedSection& cs)
- : m_cs( cs )
- , m_bIsOwner( false )
-{
- Enter();
-}
-
-CSharedLock::CSharedLock(const CSharedSection& cs)
- : m_cs( const_cast<CSharedSection&>(cs) )
- , m_bIsOwner( false )
-{
- Enter();
-}
-
-CSharedLock::~CSharedLock()
-{
- Leave();
-}
-
-bool CSharedLock::IsOwner() const
-{
- return m_bIsOwner;
-}
-
-bool CSharedLock::Enter()
-{
- // Test if we already own the critical section
- if ( true == m_bIsOwner )
- {
- return true;
- }
-
- // Blocking call
- m_cs.EnterShared();
- m_bIsOwner = true;
-
- return m_bIsOwner;
-}
-
-void CSharedLock::Leave()
-{
- if ( false == m_bIsOwner )
- {
- return ;
- }
-
- m_cs.LeaveShared();
- m_bIsOwner = false;
-}
-
-//////////////////////////////////////////////////////////////////////
-// ExclusiveLock
-//////////////////////////////////////////////////////////////////////
-
-CExclusiveLock::CExclusiveLock(CSharedSection& cs)
- : m_cs( cs )
- , m_bIsOwner( false )
-{
- Enter();
-}
-
-CExclusiveLock::CExclusiveLock(const CSharedSection& cs)
- : m_cs( const_cast<CSharedSection&>(cs) )
- , m_bIsOwner( false )
-{
- Enter();
-}
-
-CExclusiveLock::~CExclusiveLock()
-{
- Leave();
-}
-
-bool CExclusiveLock::IsOwner() const
-{
- return m_bIsOwner;
-}
-
-bool CExclusiveLock::Enter()
-{
- // Test if we already own the critical section
- if ( true == m_bIsOwner )
- {
- return true;
- }
-
- // Blocking call
- m_cs.EnterExclusive();
- m_bIsOwner = true;
-
- return m_bIsOwner;
-}
-
-void CExclusiveLock::Leave()
-{
- if ( false == m_bIsOwner )
- {
- return ;
- }
-
- m_cs.LeaveExclusive();
- m_bIsOwner = false;
-}
-
diff --git a/xbmc/threads/SharedSection.h b/xbmc/threads/SharedSection.h
index 1d7cd03dc0..ef7e44e441 100644
--- a/xbmc/threads/SharedSection.h
+++ b/xbmc/threads/SharedSection.h
@@ -21,71 +21,48 @@
*
*/
-#include "system.h" // for HANDLE, CRITICALSECTION
+#include "threads/CriticalSection.h"
+#include <boost/thread/shared_mutex.hpp>
-class CSharedSection
+/**
+ * A CSharedSection is a CountingLockable whose implementation is a boost
+ * shared_mutex.
+ *
+ * It implemented boost's shared Locakable concept which requires the
+ * additional implementation of:
+ *
+ * lock_shared()
+ * try_lock_shared()
+ * unlock_shared()
+ */
+class CSharedSection : public CountingLockable<boost::shared_mutex>
{
-
public:
- CSharedSection();
- CSharedSection(const CSharedSection& src);
- CSharedSection& operator=(const CSharedSection& src);
- virtual ~CSharedSection();
-
- void EnterExclusive();
- void LeaveExclusive();
-
- void EnterShared();
- void LeaveShared();
-private:
-
- CRITICAL_SECTION m_critSection;
-
- HANDLE m_eventFree;
- bool m_exclusive;
- long m_sharedLock;
+ inline void lock_shared() { m.lock_shared(); }
+ inline bool try_lock_shared() { return m.try_lock_shared(); }
+ inline void unlock_shared() { return m.unlock_shared(); }
};
-class CSharedLock
+class CSharedLock : public boost::shared_lock<CSharedSection>
{
public:
- CSharedLock(CSharedSection& cs);
- CSharedLock(const CSharedSection& cs);
- virtual ~CSharedLock();
-
- bool IsOwner() const;
- bool Enter();
- void Leave();
+ inline CSharedLock(CSharedSection& cs) : boost::shared_lock<CSharedSection>(cs) {}
+ inline CSharedLock(const CSharedSection& cs) : boost::shared_lock<CSharedSection>((CSharedSection&)cs) {}
-protected:
- CSharedLock(const CSharedLock& src);
- CSharedLock& operator=(const CSharedLock& src);
-
- // Reference to critical section object
- CSharedSection& m_cs;
- // Ownership flag
- bool m_bIsOwner;
+ inline bool IsOwner() const { return owns_lock(); }
+ inline void Enter() { lock(); }
+ inline void Leave() { unlock(); }
};
-class CExclusiveLock
+class CExclusiveLock : public boost::unique_lock<CSharedSection>
{
public:
- CExclusiveLock(CSharedSection& cs);
- CExclusiveLock(const CSharedSection& cs);
- virtual ~CExclusiveLock();
-
- bool IsOwner() const;
- bool Enter();
- void Leave();
-
-protected:
- CExclusiveLock(const CExclusiveLock& src);
- CExclusiveLock& operator=(const CExclusiveLock& src);
+ inline CExclusiveLock(CSharedSection& cs) : boost::unique_lock<CSharedSection>(cs) {}
+ inline CExclusiveLock(const CSharedSection& cs) : boost::unique_lock<CSharedSection> ((CSharedSection&)cs) {}
- // Reference to critical section object
- CSharedSection& m_cs;
- // Ownership flag
- bool m_bIsOwner;
+ inline bool IsOwner() const { return owns_lock(); }
+ inline void Leave() { unlock(); }
+ inline void Enter() { lock(); }
};
diff --git a/xbmc/threads/SingleLock.cpp b/xbmc/threads/SingleLock.cpp
deleted file mode 100644
index d07f8b8718..0000000000
--- a/xbmc/threads/SingleLock.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * XBMC Media Center
- * Copyright (c) 2002 Frodo
- * Portions Copyright (c) by the authors of ffmpeg and xvid
- *
- * 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "SingleLock.h"
-
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CSingleLock::CSingleLock(CCriticalSection& cs)
- : m_cs( cs )
- , m_bIsOwner( false )
-{
- Enter();
-}
-
-CSingleLock::CSingleLock(const CCriticalSection& cs)
- : m_cs( const_cast<CCriticalSection&>(cs) )
- , m_bIsOwner( false )
-{
- Enter();
-}
-
-CSingleLock::~CSingleLock()
-{
- Leave();
-}
-
-bool CSingleLock::IsOwner() const
-{
- return m_bIsOwner;
-}
-
-bool CSingleLock::Enter()
-{
- // Test if we already own the critical section
- if ( true == m_bIsOwner )
- {
- return true;
- }
-
- // Blocking call
- ::EnterCriticalSection( m_cs );
- m_bIsOwner = true;
-
- return m_bIsOwner;
-}
-
-void CSingleLock::Leave()
-{
- if ( false == m_bIsOwner )
- {
- return ;
- }
-
- ::LeaveCriticalSection( m_cs );
- m_bIsOwner = false;
-}
-
-CSingleExit::CSingleExit(CCriticalSection& cs)
- : m_cs( cs )
- , m_count(0)
-{
- Exit();
-}
-
- CSingleExit::CSingleExit(const CCriticalSection& cs)
- : m_cs(const_cast<CCriticalSection&>(cs))
- , m_count(0)
-{
- Exit();
-}
-
-CSingleExit::~CSingleExit()
-{
- Restore();
-}
-
-void CSingleExit::Exit()
-{
- if(m_count == 0)
- m_count = ::ExitCriticalSection(m_cs);
-}
-
-void CSingleExit::Restore()
-{
- if(m_count)
- {
- RestoreCriticalSection(m_cs, m_count);
- m_count = 0;
- }
-}
-
-
diff --git a/xbmc/threads/SingleLock.h b/xbmc/threads/SingleLock.h
index f222f2bf3f..cda2558909 100644
--- a/xbmc/threads/SingleLock.h
+++ b/xbmc/threads/SingleLock.h
@@ -2,13 +2,6 @@
//
//////////////////////////////////////////////////////////////////////
-#if !defined(AFX_SINGLELOCK_H__50A43114_6A71_4FBD_BF51_D1F2DD3A60FA__INCLUDED_)
-#define AFX_SINGLELOCK_H__50A43114_6A71_4FBD_BF51_D1F2DD3A60FA__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
/*
* XBMC Media Center
* Copyright (c) 2002 Frodo
@@ -29,40 +22,54 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#pragma once
+
+#include <boost/thread/locks.hpp>
#include "CriticalSection.h"
-class CSingleLock
+
+/**
+ * This implements a "guard" pattern for a CCriticalSection that
+ * borrows most of it's functionality from boost's unique_lock.
+ */
+class CSingleLock : public boost::unique_lock<CCriticalSection>
{
public:
- CSingleLock(CCriticalSection& cs);
- CSingleLock(const CCriticalSection& cs);
- virtual ~CSingleLock();
+ inline CSingleLock(CCriticalSection& cs) : boost::unique_lock<CCriticalSection>(cs) {}
+ inline CSingleLock(const CCriticalSection& cs) : boost::unique_lock<CCriticalSection> ((CCriticalSection&)cs) {}
- bool IsOwner() const;
- bool Enter();
- void Leave();
+ inline void Leave() { unlock(); }
+ inline void Enter() { lock(); }
+protected:
+ inline CSingleLock(CCriticalSection& cs, bool dicrim) : boost::unique_lock<CCriticalSection>(cs,boost::try_to_lock) {}
+};
-private:
- CSingleLock(const CSingleLock& src);
- CSingleLock& operator=(const CSingleLock& src);
+/**
+ * This implements a "guard" pattern for a CCriticalSection that
+ * works like a CSingleLock but only "try"s the lock and so
+ * it's possible it doesn't actually get it..
+ */
+class CSingleTryLock : public CSingleLock
+{
+public:
+ CSingleTryLock(CCriticalSection& cs) : CSingleLock(cs,true) {}
- // Reference to critical section object
- CCriticalSection& m_cs;
- // Ownership flag
- bool m_bIsOwner;
+ inline bool IsOwner() const { return owns_lock(); }
};
+/**
+ * This implements a "guard" pattern for exiting all locks
+ * currently being held by the current thread and restoring
+ * those locks on destruction.
+ *
+ * This class can be used on a CCriticalSection that isn't owned
+ * by this thread in which case it will do nothing.
+ */
class CSingleExit
{
+ CCriticalSection& sec;
+ unsigned int count;
public:
- CSingleExit(CCriticalSection& cs);
- CSingleExit(const CCriticalSection& cs);
- virtual ~CSingleExit();
-
- void Exit();
- void Restore();
-
- CCriticalSection& m_cs;
- unsigned int m_count;
+ inline CSingleExit(CCriticalSection& cs) : sec(cs), count(cs.exit()) { }
+ inline ~CSingleExit() { sec.restore(count); }
};
-#endif // !defined(AFX_SINGLELOCK_H__50A43114_6A71_4FBD_BF51_D1F2DD3A60FA__INCLUDED_)