Mercurial > hg > vampy
view Mutex.cpp @ 24:7d28bed0864e
* Rearrange Python plugin construction.
Formerly, the PyPluginAdapter has retained a single plugin instance pointer
for each plugin found, and its createPlugin method has simply returned a new
PyPlugin object wrapping the same instance pointer. This has a couple of
negative consequences:
- Because construction of the actual Python instance occurred before the
wrapper was constructed, it was not possible to pass arguments (i.e.
the sample rate) from the wrapper constructor to the Python plugin
instance constructor -- they had to be passed later, to initialise,
disadvantaging those plugins that would like to use the sample rate
for parameter & step/block size calculations etc
- Because there was only a single Python plugin instance, it was not
possible to run more than one instance at once with any isolation
This rework instead stores the Python class pointer (rather than instance
pointer) in the PyPluginAdapter, and each PyPlugin wrapper instance creates
its own Python plugin instance. What could possibly go wrong?
author | cannam |
---|---|
date | Mon, 17 Aug 2009 15:22:06 +0000 |
parents | e1b508f2f914 |
children |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* Basic cross-platform mutex abstraction class. This file copyright 2007 Chris Cannam. */ #include "Mutex.h" #include <iostream> #ifndef _WIN32 #include <sys/time.h> #include <time.h> #endif using std::cerr; using std::endl; using std::string; #ifdef _WIN32 Mutex::Mutex() #ifndef NO_THREAD_CHECKS : m_lockedBy(-1) #endif { m_mutex = CreateMutex(NULL, FALSE, NULL); #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised mutex " << &m_mutex << endl; #endif } Mutex::~Mutex() { #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying mutex " << &m_mutex << endl; #endif CloseHandle(m_mutex); } void Mutex::lock() { #ifndef NO_THREAD_CHECKS DWORD tid = GetCurrentThreadId(); if (m_lockedBy == tid) { cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl; } #endif #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl; #endif WaitForSingleObject(m_mutex, INFINITE); #ifndef NO_THREAD_CHECKS m_lockedBy = tid; #endif #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl; #endif } void Mutex::unlock() { #ifndef NO_THREAD_CHECKS DWORD tid = GetCurrentThreadId(); if (m_lockedBy != tid) { cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl; return; } #endif #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl; #endif #ifndef NO_THREAD_CHECKS m_lockedBy = -1; #endif ReleaseMutex(m_mutex); } bool Mutex::trylock() { #ifndef NO_THREAD_CHECKS DWORD tid = GetCurrentThreadId(); #endif DWORD result = WaitForSingleObject(m_mutex, 0); if (result == WAIT_TIMEOUT || result == WAIT_FAILED) { #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl; #endif return false; } else { #ifndef NO_THREAD_CHECKS m_lockedBy = tid; #endif #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl; #endif return true; } } #else /* !_WIN32 */ Mutex::Mutex() #ifndef NO_THREAD_CHECKS : m_lockedBy(0), m_locked(false) #endif { pthread_mutex_init(&m_mutex, 0); #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex << endl; #endif } Mutex::~Mutex() { #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex << endl; #endif pthread_mutex_destroy(&m_mutex); } void Mutex::lock() { #ifndef NO_THREAD_CHECKS pthread_t tid = pthread_self(); if (m_locked && m_lockedBy == tid) { cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl; } #endif #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl; #endif pthread_mutex_lock(&m_mutex); #ifndef NO_THREAD_CHECKS m_lockedBy = tid; m_locked = true; #endif #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl; #endif } void Mutex::unlock() { #ifndef NO_THREAD_CHECKS pthread_t tid = pthread_self(); if (!m_locked) { cerr << "ERROR: Mutex " << &m_mutex << " not locked in unlock" << endl; return; } else if (m_lockedBy != tid) { cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl; return; } #endif #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl; #endif #ifndef NO_THREAD_CHECKS m_locked = false; #endif pthread_mutex_unlock(&m_mutex); } bool Mutex::trylock() { #ifndef NO_THREAD_CHECKS pthread_t tid = pthread_self(); #endif if (pthread_mutex_trylock(&m_mutex)) { #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl; #endif return false; } else { #ifndef NO_THREAD_CHECKS m_lockedBy = tid; m_locked = true; #endif #ifdef DEBUG_MUTEX cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl; #endif return true; } } #endif MutexLocker::MutexLocker(Mutex *mutex) : m_mutex(mutex) { if (m_mutex) { m_mutex->lock(); } } MutexLocker::~MutexLocker() { if (m_mutex) { m_mutex->unlock(); } }