1616 along with this program. If not, see <http://www.gnu.org/licenses/>.
1717*/
1818#include " threadpool.h"
19+
1920#include < iostream>
21+
22+ #include < cassert>
2023#include < stdlib.h>
2124#include < errno.h>
2225
@@ -26,6 +29,8 @@ class ScopedMutex {
2629public:
2730 explicit ScopedMutex (pthread_mutex_t * const mutex):_mutex(mutex)
2831 {
32+ assert (mutex);
33+
2934 int ret = pthread_mutex_lock (_mutex);
3035 switch (ret) {
3136 case 0 :
@@ -61,11 +66,16 @@ class ScopedMutex {
6166 pthread_mutex_t * const _mutex;
6267};
6368
69+ const struct timespec ThreadPool::DESTROY_TIMEOUT = { 10 , 0 };
6470
6571ThreadPool::ThreadPool (unsigned int num_thread)
6672:_thread_pool(num_thread)
6773,_work()
6874{
75+ if (0 == num_thread) {
76+ throw Error (" zero thread?" );
77+ }
78+
6979 init_sem (&_available_work);
7080 init_mutex (&_work_mutex);
7181
@@ -76,12 +86,33 @@ ThreadPool::ThreadPool(unsigned int num_thread)
7686
7787ThreadPool::~ThreadPool ()
7888{
79- // TODO: do cleanup
89+ int ret = 0 ;
90+ // make sure all thread finish its jobs.
91+ for (unsigned int i = 0 ; i < _thread_pool.size (); ++i) {
92+ ret = sem_timedwait (&_available_work, &DESTROY_TIMEOUT);
93+ if (0 != ret) {
94+ std::cerr << " Timeout, stop ThreadPool with work" << std::endl;
95+ break ;
96+ }
97+ }
98+ ret = sem_destroy (&_available_work);
99+ if (0 != ret) {
100+ std::cerr << errno << " returned by sem_destory(). Ignore" << std::endl;
101+ }
102+
103+ ret = pthread_mutex_destroy (&_work_mutex);
104+ if (0 != ret) {
105+ std::cerr << ret << " returned by pthread_mutex_destroy(). Ignore" << std::endl;
106+ }
80107}
81108
82109
83110void ThreadPool::assign_work (WorkerThread *workerThread)
84111{
112+ if (!workerThread) {
113+ throw Error (" null?" );
114+ }
115+
85116 ScopedMutex mutex (&_work_mutex);
86117 _work.push_back (workerThread);
87118 post_sem (&_available_work);
0 commit comments