diff --git a/src/threadpoolman.cpp b/src/threadpoolman.cpp index ebce944..db4f47d 100644 --- a/src/threadpoolman.cpp +++ b/src/threadpoolman.cpp @@ -75,11 +75,11 @@ void* ThreadPoolMan::Worker(void* arg) } S3FS_PRN_INFO3("Start worker thread in ThreadPoolMan."); - while(!psingleton->is_exit){ + while(!psingleton->IsExit()){ // wait psingleton->thpoolman_sem.wait(); - if(psingleton->is_exit){ + if(psingleton->IsExit()){ break; } @@ -119,7 +119,7 @@ void* ThreadPoolMan::Worker(void* arg) //------------------------------------------------ // ThreadPoolMan methods //------------------------------------------------ -ThreadPoolMan::ThreadPoolMan(int count) : is_exit(false), thpoolman_sem(0) +ThreadPoolMan::ThreadPoolMan(int count) : is_exit(false), thpoolman_sem(0), is_lock_init(false), is_exit_flag_init(false) { if(count < 1){ S3FS_PRN_CRIT("Failed to creating singleton for Thread Manager, because thread count(%d) is under 1.", count); @@ -130,12 +130,12 @@ ThreadPoolMan::ThreadPoolMan(int count) : is_exit(false), thpoolman_sem(0) abort(); } - is_lock_init = false; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); #if S3FS_PTHREAD_ERRORCHECK pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); #endif + int result; if(0 != (result = pthread_mutex_init(&thread_list_lock, &attr))){ S3FS_PRN_CRIT("failed to init thread_list_lock: %d", result); @@ -143,6 +143,12 @@ ThreadPoolMan::ThreadPoolMan(int count) : is_exit(false), thpoolman_sem(0) } is_lock_init = true; + if(0 != (result = pthread_mutex_init(&thread_exit_flag_lock, &attr))){ + S3FS_PRN_CRIT("failed to init thread_exit_flag_lock: %d", result); + abort(); + } + is_exit_flag_init = true; + // create threads if(!StartThreads(count)){ S3FS_PRN_ERR("Failed starting threads at initializing."); @@ -155,13 +161,33 @@ ThreadPoolMan::~ThreadPoolMan() StopThreads(); if(is_lock_init){ - int result; - if(0 != (result = pthread_mutex_destroy(&thread_list_lock))){ - S3FS_PRN_CRIT("failed to destroy thread_list_lock: %d", result); - abort(); - } - is_lock_init = false; + int result; + if(0 != (result = pthread_mutex_destroy(&thread_list_lock))){ + S3FS_PRN_CRIT("failed to destroy thread_list_lock: %d", result); + abort(); + } + is_lock_init = false; } + if(is_exit_flag_init ){ + int result; + if(0 != (result = pthread_mutex_destroy(&thread_exit_flag_lock))){ + S3FS_PRN_CRIT("failed to destroy thread_exit_flag_lock: %d", result); + abort(); + } + is_exit_flag_init = false; + } +} + +bool ThreadPoolMan::IsExit() +{ + AutoLock auto_lock(&thread_exit_flag_lock); + return is_exit; +} + +void ThreadPoolMan::SetExitFlag(bool exit_flag) +{ + AutoLock auto_lock(&thread_exit_flag_lock); + is_exit = exit_flag; } bool ThreadPoolMan::StopThreads() @@ -172,7 +198,7 @@ bool ThreadPoolMan::StopThreads() } // all threads to exit - is_exit = true; + SetExitFlag(true); for(uint waitcnt = thread_list.size(); 0 < waitcnt; --waitcnt){ thpoolman_sem.post(); } @@ -216,7 +242,7 @@ bool ThreadPoolMan::StartThreads(int count) } // create all threads - is_exit = false; + SetExitFlag(false); for(int cnt = 0; cnt < count; ++cnt){ // run thread pthread_t thread; diff --git a/src/threadpoolman.h b/src/threadpoolman.h index 5066532..fdd3a3d 100644 --- a/src/threadpoolman.h +++ b/src/threadpoolman.h @@ -60,7 +60,7 @@ class ThreadPoolMan private: static ThreadPoolMan* singleton; - volatile bool is_exit; + bool is_exit; Semaphore thpoolman_sem; bool is_lock_init; @@ -69,12 +69,18 @@ class ThreadPoolMan thpoolman_params_t instruction_list; + bool is_exit_flag_init; + pthread_mutex_t thread_exit_flag_lock; + private: static void* Worker(void* arg); explicit ThreadPoolMan(int count = 1); ~ThreadPoolMan(); + bool IsExit(); + void SetExitFlag(bool exit_flag); + bool StopThreads(); bool StartThreads(int count); bool SetInstruction(thpoolman_param* pparam);