Files
pip/lib/main/thread/pimutex.cpp
Ivan Pelipenko 42925122cb version 1.22.0
source tree changed
detached PIConsole and PIScreen* in "pip_console" library
2020-06-28 00:18:24 +03:00

144 lines
3.4 KiB
C++

/*
PIP - Platform Independent Primitives
Mutex
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program 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 3 of the License, or
(at your option) any later version.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \class PIMutex
* \brief Mutex
* \details
* \section PIMutex_sec0 Synopsis
* %PIMutex provides synchronization blocks between several threads.
* Using mutex guarantees execution of some code only one of threads.
* Mutex contains logic state and functions to change it: \a lock(),
* \a unlock() and \a tryLock().
*
* \section PIMutex_sec1 Usage
* Block of code that should to be executed only one thread simultaniously
* should to be started with \a lock() and ended with \a unlock().
* \snippet pimutex.cpp main
* "mutex" in this example is one for all threads.
*
* */
#include "pimutex.h"
#include "piincludes_p.h"
#ifdef BLACKBERRY
# include <pthread.h>
#endif
PRIVATE_DEFINITION_START(PIMutex)
#ifdef WINDOWS
HANDLE
#else
pthread_mutex_t
#endif
mutex;
PRIVATE_DEFINITION_END(PIMutex)
PIMutex::PIMutex(): inited_(false) {
//printf("new Mutex %p\n", this);
#ifdef WINDOWS
PRIVATE->mutex = 0;
#endif
init();
}
PIMutex::~PIMutex() {
//printf("del Mutex %p\n", this);
destroy();
}
void PIMutex::lock() {
#ifdef WINDOWS
// std::cout << (ullong)PRIVATE->mutex << "locking..." << std::endl;
// DWORD wr =
WaitForSingleObject(PRIVATE->mutex, INFINITE);
// std::cout << (ullong)PRIVATE->mutex << " lock wr=" << wr << std::endl;
#else
pthread_mutex_lock(&(PRIVATE->mutex));
#endif
locked = true;
}
void PIMutex::unlock() {
#ifdef WINDOWS
// BOOL wr =
// ReleaseMutex(PRIVATE->mutex);
SetEvent(PRIVATE->mutex);
// std::cout << (ullong)PRIVATE->mutex << " unlock wr=" << wr << std::endl;
#else
pthread_mutex_unlock(&(PRIVATE->mutex));
#endif
locked = false;
}
bool PIMutex::tryLock() {
bool ret =
#ifdef WINDOWS
(WaitForSingleObject(PRIVATE->mutex, 0) == WAIT_OBJECT_0);
#else
(pthread_mutex_trylock(&(PRIVATE->mutex)) == 0);
#endif
locked = true;
return ret;
}
bool PIMutex::isLocked() const {
// std::cout << "test " << (ullong)PRIVATE->mutex << std::endl;
return locked;
}
void PIMutex::init() {
if (inited_) destroy();
#ifdef WINDOWS
PRIVATE->mutex = CreateEvent(NULL, FALSE, TRUE, NULL);
// std::cout << "create " << (ullong)PRIVATE->mutex << std::endl;
#else
pthread_mutexattr_t attr;
memset(&attr, 0, sizeof(attr));
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
memset(&(PRIVATE->mutex), 0, sizeof(PRIVATE->mutex));
pthread_mutex_init(&(PRIVATE->mutex), &attr);
pthread_mutexattr_destroy(&attr);
#endif
locked = false;
inited_ = true;
}
void PIMutex::destroy() {
if (inited_) {
#ifdef WINDOWS
// std::cout << "destroy " << (ullong)PRIVATE->mutex << std::endl;
if (PRIVATE->mutex) CloseHandle(PRIVATE->mutex);
PRIVATE->mutex = 0;
#else
pthread_mutex_destroy(&(PRIVATE->mutex));
#endif
}
locked = inited_ = false;
}