fix concurrent

git-svn-id: svn://db.shs.com.ru/pip@884 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
2020-02-25 15:58:02 +00:00
parent f8f627360a
commit 92ac2b12cf
7 changed files with 408 additions and 467 deletions

View File

@@ -1,54 +1,55 @@
//
// Created by fomenko on 23.09.2019.
//
#include "executor.h"
PIThreadPoolExecutor::PIThreadPoolExecutor(size_t corePoolSize, PIBlockingDequeue<std::function<void()>> *taskQueue_,
PIThreadFactory *threadFactory) : isShutdown_(false), taskQueue(taskQueue_), threadFactory(threadFactory) {
for (size_t i = 0; i < corePoolSize; ++i) {
AbstractThread* thread = threadFactory->newThread([&, i](){
auto runnable = taskQueue->poll(100, std::function<void()>());
if (runnable) {
runnable();
}
if (isShutdown_ && taskQueue->size() == 0) threadPool[i]->stop();
});
threadPool.push_back(thread);
thread->start();
}
PIThreadPoolExecutor::PIThreadPoolExecutor(size_t corePoolSize, PIBlockingDequeue<std::function<void()>> *taskQueue_) : isShutdown_(false), taskQueue(taskQueue_) {
for (size_t i = 0; i < corePoolSize; ++i) {
PIThread * thread = new PIThread([&, i](){
auto runnable = taskQueue->poll(100, std::function<void()>());
if (runnable) {
runnable();
}
if (isShutdown_ && taskQueue->size() == 0) threadPool[i]->stop();
});
threadPool.push_back(thread);
thread->start();
}
}
bool PIThreadPoolExecutor::awaitTermination(int timeoutMs) {
PITimeMeasurer measurer;
for (size_t i = 0; i < threadPool.size(); ++i) {
int dif = timeoutMs - (int)measurer.elapsed_m();
if (dif < 0) return false;
if (!threadPool[i]->waitForFinish(dif)) return false;
}
return true;
PITimeMeasurer measurer;
for (size_t i = 0; i < threadPool.size(); ++i) {
int dif = timeoutMs - (int)measurer.elapsed_m();
if (dif < 0) return false;
if (!threadPool[i]->waitForFinish(dif)) return false;
}
return true;
}
void PIThreadPoolExecutor::shutdownNow() {
isShutdown_ = true;
for (size_t i = 0; i < threadPool.size(); ++i) threadPool[i]->stop();
isShutdown_ = true;
for (size_t i = 0; i < threadPool.size(); ++i) threadPool[i]->stop();
}
PIThreadPoolExecutor::~PIThreadPoolExecutor() {
shutdownNow();
while (threadPool.size() > 0) delete threadPool.take_back();
delete threadFactory;
delete taskQueue;
shutdownNow();
while (threadPool.size() > 0) delete threadPool.take_back();
delete taskQueue;
}
void PIThreadPoolExecutor::execute(const std::function<void()> &runnable) {
if (!isShutdown_) taskQueue->offer(runnable);
if (!isShutdown_) taskQueue->offer(runnable);
}
volatile bool PIThreadPoolExecutor::isShutdown() const {
return isShutdown_;
return isShutdown_;
}
void PIThreadPoolExecutor::shutdown() {
isShutdown_ = true;
isShutdown_ = true;
}

View File

@@ -1,7 +1,3 @@
//
// Created by fomenko on 25.09.2019.
//
#include "piconditionlock.h"
#ifdef WINDOWS
#include "synchapi.h"
@@ -9,70 +5,82 @@
#include "pthread.h"
#endif
PRIVATE_DEFINITION_START(PIConditionLock)
#ifdef WINDOWS
CRITICAL_SECTION
CRITICAL_SECTION
#else
pthread_mutex_t
pthread_mutex_t
#endif
nativeHandle;
nativeHandle;
PRIVATE_DEFINITION_END(PIConditionLock)
#ifdef WINDOWS
PIConditionLock::PIConditionLock() {
InitializeCriticalSection(&PRIVATE->nativeHandle);
InitializeCriticalSection(&PRIVATE->nativeHandle);
}
PIConditionLock::~PIConditionLock() {
DeleteCriticalSection(&PRIVATE->nativeHandle);
DeleteCriticalSection(&PRIVATE->nativeHandle);
}
void PIConditionLock::lock() {
EnterCriticalSection(&PRIVATE->nativeHandle);
EnterCriticalSection(&PRIVATE->nativeHandle);
}
void PIConditionLock::unlock() {
LeaveCriticalSection(&PRIVATE->nativeHandle);
LeaveCriticalSection(&PRIVATE->nativeHandle);
}
void *PIConditionLock::handle() {
return &PRIVATE->nativeHandle;
return &PRIVATE->nativeHandle;
}
bool PIConditionLock::tryLock() {
return TryEnterCriticalSection(&PRIVATE->nativeHandle) != 0;
return TryEnterCriticalSection(&PRIVATE->nativeHandle) != 0;
}
#else
PIConditionLock::PIConditionLock() {
pthread_mutexattr_t attr;
memset(&attr, 0, sizeof(attr));
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle));
pthread_mutex_init(&(PRIVATE->nativeHandle), &attr);
pthread_mutexattr_destroy(&attr);
pthread_mutexattr_t attr;
memset(&attr, 0, sizeof(attr));
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle));
pthread_mutex_init(&(PRIVATE->nativeHandle), &attr);
pthread_mutexattr_destroy(&attr);
}
PIConditionLock::~PIConditionLock() {
pthread_mutex_destroy(&(PRIVATE->nativeHandle));
pthread_mutex_destroy(&(PRIVATE->nativeHandle));
}
void PIConditionLock::lock() {
pthread_mutex_lock(&(PRIVATE->nativeHandle));
pthread_mutex_lock(&(PRIVATE->nativeHandle));
}
void PIConditionLock::unlock() {
pthread_mutex_unlock(&(PRIVATE->nativeHandle));
pthread_mutex_unlock(&(PRIVATE->nativeHandle));
}
void *PIConditionLock::handle() {
return &PRIVATE->nativeHandle;
return &PRIVATE->nativeHandle;
}
bool PIConditionLock::tryLock() {
return (pthread_mutex_trylock(&(PRIVATE->nativeHandle)) == 0);;
return (pthread_mutex_trylock(&(PRIVATE->nativeHandle)) == 0);
}
#endif

View File

@@ -1,8 +1,7 @@
//
// Created by fomenko on 20.09.2019.
//
#include "piplatform.h"
#include "piconditionvar.h"
#include "pithread.h"
#include "pitime.h"
#ifdef WINDOWS
#define _WIN32_WINNT 0x0600
@@ -11,118 +10,113 @@
#include <winbase.h>
#endif
#include "piconditionvar.h"
#include "pithread.h"
#include "pitime.h"
PRIVATE_DEFINITION_START(PIConditionVariable)
#ifdef WINDOWS
CONDITION_VARIABLE nativeHandle;
CONDITION_VARIABLE nativeHandle;
#else
pthread_cond_t nativeHandle;
PIConditionLock* currentLock;
pthread_cond_t nativeHandle;
PIConditionLock* currentLock;
#endif
bool isDestroying;
bool isDestroying;
PRIVATE_DEFINITION_END(PIConditionVariable)
PIConditionVariable::PIConditionVariable() {
#ifdef WINDOWS
InitializeConditionVariable(&PRIVATE->nativeHandle);
InitializeConditionVariable(&PRIVATE->nativeHandle);
#else
PRIVATE->isDestroying = false;
PRIVATE->currentLock = nullptr;
memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle));
pthread_cond_init(&PRIVATE->nativeHandle, NULL);
PRIVATE->isDestroying = false;
PRIVATE->currentLock = nullptr;
memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle));
pthread_cond_init(&PRIVATE->nativeHandle, NULL);
#endif
}
PIConditionVariable::~PIConditionVariable() {
#ifdef WINDOWS
#else
pthread_cond_destroy(&PRIVATE->nativeHandle);
pthread_cond_destroy(&PRIVATE->nativeHandle);
#endif
}
void PIConditionVariable::wait(PIConditionLock& lk) {
#ifdef WINDOWS
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
#else
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
#endif
}
void PIConditionVariable::wait(PIConditionLock& lk, const std::function<bool()>& condition) {
bool isCondition;
while (true) {
isCondition = condition();
if (isCondition) break;
bool isCondition;
while (true) {
isCondition = condition();
if (isCondition) break;
#ifdef WINDOWS
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
#else
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
#endif
if (PRIVATE->isDestroying) return;
}
if (PRIVATE->isDestroying) return;
}
}
bool PIConditionVariable::waitFor(PIConditionLock &lk, int timeoutMs) {
bool isNotTimeout;
bool isNotTimeout;
#ifdef WINDOWS
isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0;
isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0;
#else
timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs * 1000 * 1000};
isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0;
timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs * 1000 * 1000};
isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0;
#endif
if (PRIVATE->isDestroying) return false;
return isNotTimeout;
if (PRIVATE->isDestroying) return false;
return isNotTimeout;
}
bool PIConditionVariable::waitFor(PIConditionLock& lk, int timeoutMs, const std::function<bool()> &condition) {
bool isCondition;
PITimeMeasurer measurer;
while (true) {
isCondition = condition();
if (isCondition) break;
bool isCondition;
PITimeMeasurer measurer;
while (true) {
isCondition = condition();
if (isCondition) break;
#ifdef WINDOWS
WINBOOL isTimeout = SleepConditionVariableCS(
&PRIVATE->nativeHandle,
(PCRITICAL_SECTION)lk.handle(),
timeoutMs - (int)measurer.elapsed_m());
if (isTimeout == 0) return false;
WINBOOL isTimeout = SleepConditionVariableCS(
&PRIVATE->nativeHandle,
(PCRITICAL_SECTION)lk.handle(),
timeoutMs - (int)measurer.elapsed_m());
if (isTimeout == 0) return false;
#else
int timeoutCurr = timeoutMs - (int)measurer.elapsed_m();
timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr * 1000 * 1000};
bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0;
if (isTimeout) return false;
int timeoutCurr = timeoutMs - (int)measurer.elapsed_m();
timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr * 1000 * 1000};
bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0;
if (isTimeout) return false;
#endif
if (PRIVATE->isDestroying) return false;
}
return true;
if (PRIVATE->isDestroying) return false;
}
return true;
}
void PIConditionVariable::notifyOne() {
#ifdef WINDOWS
WakeConditionVariable(&PRIVATE->nativeHandle);
WakeConditionVariable(&PRIVATE->nativeHandle);
#else
pthread_cond_signal(&PRIVATE->nativeHandle);
pthread_cond_signal(&PRIVATE->nativeHandle);
#endif
}
void PIConditionVariable::notifyAll() {
#ifdef WINDOWS
WakeAllConditionVariable(&PRIVATE->nativeHandle);
WakeAllConditionVariable(&PRIVATE->nativeHandle);
#else
pthread_cond_broadcast(&PRIVATE->nativeHandle);
pthread_cond_broadcast(&PRIVATE->nativeHandle);
#endif
}
void StdFunctionThreadFuncAdapter::threadFuncStdFunctionAdapter(void *it) {
auto consumer = (StdFunctionThreadFuncAdapter*)it;
consumer->fun();
}
void StdFunctionThreadFuncAdapter::registerToInvoke(PIThread *thread) {
thread->setData(data());
thread->setSlot((ThreadFunc) threadFunc());
}