spectrum2/include/transport/ThreadPool.h
Vladimír Matěna f328e80a97 Fix possible double free in ThreadPool
This makes HTTPRequestTest::GETThreadPool test pass deterministicaly.

Problem was static slot used to cleanup threads. When ThreadPool was instantiated
multiple times, threads were also clened up multiple times resulting in segfault.
2016-09-17 00:45:17 +03:00

74 lines
2 KiB
C++

#pragma once
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/signals2/signal.hpp>
#include <queue>
#include <iostream>
#include "Swiften/EventLoop/EventLoop.h"
namespace Transport {
/*
* Thread serves as a base class for any code that has to be excuted as a thread
* by the ThreadPool class. The run method defines the code that has to be run
* as a theard. For example, code in run could be sendinga request to a server
* waiting for the response and storing the response. When the thread finishes
* execution, the ThreadPool invokes finalize where one could have the code necessary
* to collect all the responses and release any resources.
*
* NOTE: The object of the Thread class must be valid (in scope) throughout the
* execution of the thread.
*/
class Thread
{
int threadID;
public:
Thread() {}
virtual ~Thread() {}
virtual void run() = 0;
virtual void finalize() {}
int getThreadID() {return threadID;}
void setThreadID(int tid) {threadID = tid;}
};
/*
* ThreadPool provides the interface to manage a pool of threads. It schedules jobs
* on free threads and when the thread completes it automatically deletes the object
* corresponding to a Thread. If free threads are not available, the requests are
* added to a queue and scheduled later when threads become available.
*/
class ThreadPool
{
const int MAX_THREADS;
int activeThreads;
std::queue<int> freeThreads;
std::queue<Thread*> requestQueue;
boost::thread **worker;
boost::mutex count_lock;
boost::mutex pool_lock;
boost::mutex criticalregion;
Swift::EventLoop *loop;
boost::signals2::signal < void () > onWorkerAvailable;
public:
ThreadPool(Swift::EventLoop *loop, int maxthreads);
~ThreadPool();
void runAsThread(Thread *t);
int getActiveThreadCount();
void updateActiveThreadCount(int k);
void cleandUp(Thread *, int);
void scheduleFromQueue();
int getFreeThread();
void releaseThread(int i);
void workerBody(Thread *t, int wid);
};
}