diff options
Diffstat (limited to 'src/MTS_Lock.cpp')
-rw-r--r-- | src/MTS_Lock.cpp | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/MTS_Lock.cpp b/src/MTS_Lock.cpp new file mode 100644 index 0000000..dc2e7c0 --- /dev/null +++ b/src/MTS_Lock.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts. + * + * libmts is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * libmts 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libmts. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <mts/MTS_Lock.h> +#include <mts/MTS_Logger.h> +#include <cassert> +#include <stdexcept> + +using namespace MTS; + +Lock::Lock() +: m_bLocked(false) { +#ifdef WIN32 + m_apMutex.reset(CreateMutex(NULL, FALSE, NULL)); + if (m_apMutex.get() == NULL) { + throw std::bad_alloc(); + } +#else + m_apMutexAttr.reset(new pthread_mutexattr_t()); + int result = pthread_mutexattr_init(m_apMutexAttr.get()); + if (result != 0) { + throw std::runtime_error("failed to initialize mutex attributes"); + } + result = pthread_mutexattr_settype(m_apMutexAttr.get(), + PTHREAD_MUTEX_RECURSIVE); + if (result != 0) { + throw std::runtime_error("failed to set mutex recursive"); + } + m_apMutex.reset(new pthread_mutex_t()); + result = pthread_mutex_init(m_apMutex.get(), m_apMutexAttr.get()); + if (result != 0) { + throw std::runtime_error("failed to initialize mutex"); + } +#endif + +} + +Lock::~Lock() { + if (isLocked()) { + unlock(); + } +#ifdef WIN32 + const BOOL ok = CloseHandle(m_apMutex.release()); + assert(ok); +#else + if (!m_apMutex.isNull()) { + const int result = pthread_mutex_destroy(m_apMutex.get()); + if (result != 0) { + printWarning("Lock| Failed to destroy mutex"); + } + assert(result == 0); + } + if (!m_apMutexAttr.isNull()) { + const int result = pthread_mutexattr_destroy(m_apMutexAttr.get()); + if (result != 0) { + printWarning("Lock| Failed to destroy mutex attributes"); + } + assert(result == 0); + } +#endif +} + +void Lock::lock() { +#ifdef WIN32 + const DWORD waitResult = WaitForSingleObject(m_apMutex.get(), INFINITE); + assert(waitResult == WAIT_OBJECT_0); +#else + const int result = pthread_mutex_lock(m_apMutex.get()); + if (result != 0) { + printWarning("Lock| Failed to lock mutex"); + } + assert(result == 0); +#endif + m_bLocked = true; +} + +void Lock::unlock() { + m_bLocked = false; +#ifdef WIN32 + const BOOL ok = ReleaseMutex(m_apMutex.get()); + assert(ok); +#else + const int result = pthread_mutex_unlock(m_apMutex.get()); + if (result != 0) { + printWarning("Lock| Failed to unlock mutex"); + } + assert(result == 0); +#endif +} + +bool Lock::isLocked() const { + return m_bLocked; +} + +Condition* Lock::createCondition() { + return new Condition(this); +} |