annotate 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
rev   line source
cannam@3 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@3 2
cannam@3 3 /*
cannam@3 4 Basic cross-platform mutex abstraction class.
cannam@3 5 This file copyright 2007 Chris Cannam.
cannam@3 6 */
cannam@3 7
cannam@3 8 #include "Mutex.h"
cannam@3 9 #include <iostream>
cannam@3 10
cannam@3 11 #ifndef _WIN32
cannam@3 12 #include <sys/time.h>
cannam@3 13 #include <time.h>
cannam@3 14 #endif
cannam@3 15
cannam@3 16 using std::cerr;
cannam@3 17 using std::endl;
cannam@3 18 using std::string;
cannam@3 19
cannam@3 20 #ifdef _WIN32
cannam@3 21
cannam@3 22 Mutex::Mutex()
cannam@3 23 #ifndef NO_THREAD_CHECKS
cannam@3 24 :
cannam@3 25 m_lockedBy(-1)
cannam@3 26 #endif
cannam@3 27 {
cannam@3 28 m_mutex = CreateMutex(NULL, FALSE, NULL);
cannam@3 29 #ifdef DEBUG_MUTEX
cannam@3 30 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised mutex " << &m_mutex << endl;
cannam@3 31 #endif
cannam@3 32 }
cannam@3 33
cannam@3 34 Mutex::~Mutex()
cannam@3 35 {
cannam@3 36 #ifdef DEBUG_MUTEX
cannam@3 37 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying mutex " << &m_mutex << endl;
cannam@3 38 #endif
cannam@3 39 CloseHandle(m_mutex);
cannam@3 40 }
cannam@3 41
cannam@3 42 void
cannam@3 43 Mutex::lock()
cannam@3 44 {
cannam@3 45 #ifndef NO_THREAD_CHECKS
cannam@3 46 DWORD tid = GetCurrentThreadId();
cannam@3 47 if (m_lockedBy == tid) {
cannam@3 48 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
cannam@3 49 }
cannam@3 50 #endif
cannam@3 51 #ifdef DEBUG_MUTEX
cannam@3 52 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
cannam@3 53 #endif
cannam@3 54 WaitForSingleObject(m_mutex, INFINITE);
cannam@3 55 #ifndef NO_THREAD_CHECKS
cannam@3 56 m_lockedBy = tid;
cannam@3 57 #endif
cannam@3 58 #ifdef DEBUG_MUTEX
cannam@3 59 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
cannam@3 60 #endif
cannam@3 61 }
cannam@3 62
cannam@3 63 void
cannam@3 64 Mutex::unlock()
cannam@3 65 {
cannam@3 66 #ifndef NO_THREAD_CHECKS
cannam@3 67 DWORD tid = GetCurrentThreadId();
cannam@3 68 if (m_lockedBy != tid) {
cannam@3 69 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
cannam@3 70 return;
cannam@3 71 }
cannam@3 72 #endif
cannam@3 73 #ifdef DEBUG_MUTEX
cannam@3 74 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
cannam@3 75 #endif
cannam@3 76 #ifndef NO_THREAD_CHECKS
cannam@3 77 m_lockedBy = -1;
cannam@3 78 #endif
cannam@3 79 ReleaseMutex(m_mutex);
cannam@3 80 }
cannam@3 81
cannam@3 82 bool
cannam@3 83 Mutex::trylock()
cannam@3 84 {
cannam@3 85 #ifndef NO_THREAD_CHECKS
cannam@3 86 DWORD tid = GetCurrentThreadId();
cannam@3 87 #endif
cannam@3 88 DWORD result = WaitForSingleObject(m_mutex, 0);
cannam@3 89 if (result == WAIT_TIMEOUT || result == WAIT_FAILED) {
cannam@3 90 #ifdef DEBUG_MUTEX
cannam@3 91 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
cannam@3 92 #endif
cannam@3 93 return false;
cannam@3 94 } else {
cannam@3 95 #ifndef NO_THREAD_CHECKS
cannam@3 96 m_lockedBy = tid;
cannam@3 97 #endif
cannam@3 98 #ifdef DEBUG_MUTEX
cannam@3 99 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
cannam@3 100 #endif
cannam@3 101 return true;
cannam@3 102 }
cannam@3 103 }
cannam@3 104
cannam@3 105 #else /* !_WIN32 */
cannam@3 106
cannam@3 107 Mutex::Mutex()
cannam@3 108 #ifndef NO_THREAD_CHECKS
cannam@3 109 :
cannam@3 110 m_lockedBy(0),
cannam@3 111 m_locked(false)
cannam@3 112 #endif
cannam@3 113 {
cannam@3 114 pthread_mutex_init(&m_mutex, 0);
cannam@3 115 #ifdef DEBUG_MUTEX
cannam@3 116 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex << endl;
cannam@3 117 #endif
cannam@3 118 }
cannam@3 119
cannam@3 120 Mutex::~Mutex()
cannam@3 121 {
cannam@3 122 #ifdef DEBUG_MUTEX
cannam@3 123 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex << endl;
cannam@3 124 #endif
cannam@3 125 pthread_mutex_destroy(&m_mutex);
cannam@3 126 }
cannam@3 127
cannam@3 128 void
cannam@3 129 Mutex::lock()
cannam@3 130 {
cannam@3 131 #ifndef NO_THREAD_CHECKS
cannam@3 132 pthread_t tid = pthread_self();
cannam@3 133 if (m_locked && m_lockedBy == tid) {
cannam@3 134 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
cannam@3 135 }
cannam@3 136 #endif
cannam@3 137 #ifdef DEBUG_MUTEX
cannam@3 138 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
cannam@3 139 #endif
cannam@3 140 pthread_mutex_lock(&m_mutex);
cannam@3 141 #ifndef NO_THREAD_CHECKS
cannam@3 142 m_lockedBy = tid;
cannam@3 143 m_locked = true;
cannam@3 144 #endif
cannam@3 145 #ifdef DEBUG_MUTEX
cannam@3 146 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
cannam@3 147 #endif
cannam@3 148 }
cannam@3 149
cannam@3 150 void
cannam@3 151 Mutex::unlock()
cannam@3 152 {
cannam@3 153 #ifndef NO_THREAD_CHECKS
cannam@3 154 pthread_t tid = pthread_self();
cannam@3 155 if (!m_locked) {
cannam@3 156 cerr << "ERROR: Mutex " << &m_mutex << " not locked in unlock" << endl;
cannam@3 157 return;
cannam@3 158 } else if (m_lockedBy != tid) {
cannam@3 159 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
cannam@3 160 return;
cannam@3 161 }
cannam@3 162 #endif
cannam@3 163 #ifdef DEBUG_MUTEX
cannam@3 164 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
cannam@3 165 #endif
cannam@3 166 #ifndef NO_THREAD_CHECKS
cannam@3 167 m_locked = false;
cannam@3 168 #endif
cannam@3 169 pthread_mutex_unlock(&m_mutex);
cannam@3 170 }
cannam@3 171
cannam@3 172 bool
cannam@3 173 Mutex::trylock()
cannam@3 174 {
cannam@3 175 #ifndef NO_THREAD_CHECKS
cannam@3 176 pthread_t tid = pthread_self();
cannam@3 177 #endif
cannam@3 178 if (pthread_mutex_trylock(&m_mutex)) {
cannam@3 179 #ifdef DEBUG_MUTEX
cannam@3 180 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
cannam@3 181 #endif
cannam@3 182 return false;
cannam@3 183 } else {
cannam@3 184 #ifndef NO_THREAD_CHECKS
cannam@3 185 m_lockedBy = tid;
cannam@3 186 m_locked = true;
cannam@3 187 #endif
cannam@3 188 #ifdef DEBUG_MUTEX
cannam@3 189 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
cannam@3 190 #endif
cannam@3 191 return true;
cannam@3 192 }
cannam@3 193 }
cannam@3 194
cannam@3 195 #endif
cannam@5 196
cannam@5 197 MutexLocker::MutexLocker(Mutex *mutex) :
cannam@5 198 m_mutex(mutex)
cannam@5 199 {
cannam@5 200 if (m_mutex) {
cannam@5 201 m_mutex->lock();
cannam@5 202 }
cannam@5 203 }
cannam@5 204
cannam@5 205 MutexLocker::~MutexLocker()
cannam@5 206 {
cannam@5 207 if (m_mutex) {
cannam@5 208 m_mutex->unlock();
cannam@5 209 }
cannam@5 210 }
cannam@5 211