--- /dev/null
+/*
+This file is part of libmspframework
+Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+#ifndef MSP_FRAMEWORK_MUTEX_H_
+#define MSP_FRAMEWORK_MUTEX_H_
+
+#include <msp/refcount.h>
+#include "types.h"
+
+namespace Msp {
+
+class Mutex
+{
+public:
+#ifndef WIN32
+ Mutex() { pthread_mutex_init(&mutex, 0); }
+ int lock() { return pthread_mutex_lock(&mutex); }
+ int trylock() { return pthread_mutex_trylock(&mutex); }
+ int unlock() { return pthread_mutex_unlock(&mutex); }
+ ~Mutex() { pthread_mutex_destroy(&mutex); }
+#else
+ Mutex() { mutex=CreateMutex(0, false, 0); }
+ int lock() { return WaitForSingleObject(mutex, INFINITE)==WAIT_OBJECT_0; }
+ int trylock() { return WaitForSingleObject(mutex, 0)==WAIT_OBJECT_0; }
+ int unlock() { return !ReleaseMutex(mutex); }
+ ~Mutex() { CloseHandle(mutex); }
+#endif
+private:
+ MutexHandle mutex;
+
+ friend class Semaphore;
+};
+
+class MutexLock
+{
+public:
+ MutexLock(Mutex &m): mutex(m) { mutex.lock(); }
+ ~MutexLock() { mutex.unlock(); }
+private:
+ Mutex &mutex;
+};
+
+
+template<typename T>
+class MutexPtr: public RefCount
+{
+public:
+ MutexPtr(T *d, Mutex &m): mutex(m), data(d) { mutex.lock(); }
+ MutexPtr(const MutexPtr<T> &p): RefCount(p), mutex(p.mutex), data(p.data) { }
+ T &operator*() const { return *data; }
+ T *operator->() const { return data; }
+ void clear() { decref(); data=0; }
+ ~MutexPtr() { decref(); }
+protected:
+ Mutex &mutex;
+ T *data;
+
+ bool decref()
+ {
+ if(!RefCount::decref())
+ {
+ mutex.unlock();
+ return false;
+ }
+ return true;
+ }
+};
+
+}
+
+#endif