/* * 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 . * */ #include #include #include #include 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); }