|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tthread.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tthreadP.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "boost/thread/thread.hpp"
|
|
Toshihiro Shimizu |
890ddd |
#include "boost/thread/condition.hpp"
|
|
Toshihiro Shimizu |
890ddd |
#include "boost/thread/tss.hpp"
|
|
Toshihiro Shimizu |
890ddd |
#include "boost/thread/xtime.hpp"
|
|
Toshihiro Shimizu |
890ddd |
#include <queue></queue>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Toshihiro Shimizu |
890ddd |
#include <windows.h></windows.h>
|
|
Toshihiro Shimizu |
890ddd |
#define WM_THREAD_NOTIFICATION (WM_USER + 10)
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DEFINE_CLASS_CODE(TThread::Runnable, 21)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Toshihiro Shimizu |
890ddd |
HWND MainHandle;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
Display *TheDisplay;
|
|
Toshihiro Shimizu |
890ddd |
Window TheMainWindow;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class Thread {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Thread();
|
|
Shinya Kitaoka |
120a6e |
Thread(const TThread::RunnableP &runnable);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
~Thread();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void join();
|
|
Shinya Kitaoka |
120a6e |
void cancel();
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
e280ae |
#if defined(_MSC_VER) && (_MSC_VER == 1200)
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(disable : 4290)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
static void milestone() throw(TThread::Interrupt);
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
e280ae |
#if defined(_MSC_VER) && (_MSC_VER == 1200)
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(default : 4290)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class Imp;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
friend class ThreadGroup;
|
|
Shinya Kitaoka |
120a6e |
Imp *m_imp;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class ThreadGroup {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ThreadGroup();
|
|
Shinya Kitaoka |
120a6e |
~ThreadGroup();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void add(Thread *thread);
|
|
Shinya Kitaoka |
120a6e |
void joinAll();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
class Imp;
|
|
Shinya Kitaoka |
120a6e |
Imp *m_imp;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
class QueueT {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
QueueT(int slotCount)
|
|
Shinya Kitaoka |
120a6e |
: m_items()
|
|
Shinya Kitaoka |
120a6e |
, m_slotCount(slotCount)
|
|
Shinya Kitaoka |
120a6e |
, m_notEmpty()
|
|
Shinya Kitaoka |
120a6e |
, m_notFull()
|
|
Shinya Kitaoka |
120a6e |
, m_mutex() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~QueueT() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void put(const T &item) {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
while (m_items.size() == m_slotCount) m_notFull.wait(sl);
|
|
Shinya Kitaoka |
120a6e |
m_items.push(item);
|
|
Shinya Kitaoka |
120a6e |
m_notEmpty.notify_one();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T get() {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (m_items.size() == 0) m_notEmpty.wait(sl);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_notFull.notify_one();
|
|
Shinya Kitaoka |
120a6e |
T item = m_items.front();
|
|
Shinya Kitaoka |
120a6e |
m_items.pop();
|
|
Shinya Kitaoka |
120a6e |
return item;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int size() {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
int size = m_items.size();
|
|
Shinya Kitaoka |
120a6e |
return size;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
std::queue<t> m_items;</t>
|
|
Shinya Kitaoka |
120a6e |
TThread::Condition m_notEmpty;
|
|
Shinya Kitaoka |
120a6e |
TThread::Condition m_notFull;
|
|
Shinya Kitaoka |
120a6e |
TThread::Mutex m_mutex;
|
|
Shinya Kitaoka |
120a6e |
int m_slotCount;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // anonymous namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::setMainThreadId(TThread::ThreadInfo *info) {
|
|
Shinya Kitaoka |
120a6e |
assert(info);
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
MainHandle = info->mainHandle;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
TheDisplay = info->dpy;
|
|
Shinya Kitaoka |
120a6e |
TheMainWindow = info->win;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
ULONG TThread::getMainShellHandle() { return ULONG(MainHandle); }
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class BoostRunnable {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
BoostRunnable(const TThread::RunnableP &runnable, Thread::Imp *threadImp)
|
|
Shinya Kitaoka |
120a6e |
: m_runnable(runnable), m_threadImp(threadImp) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void operator()();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::RunnableP m_runnable;
|
|
Shinya Kitaoka |
120a6e |
Thread::Imp *m_threadImp;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class Thread::Imp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Imp() : m_boostThread(0), m_isCanceled(false), m_stateMutex() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Imp(const TThread::RunnableP &runnable)
|
|
Shinya Kitaoka |
120a6e |
: m_isCanceled(false), m_stateMutex() {
|
|
Shinya Kitaoka |
120a6e |
m_boostThread = new boost::thread(BoostRunnable(runnable, this));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~Imp() {
|
|
Shinya Kitaoka |
120a6e |
if (m_boostThread) delete m_boostThread;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
boost::thread *m_boostThread;
|
|
Shinya Kitaoka |
120a6e |
boost::mutex m_stateMutex;
|
|
Shinya Kitaoka |
120a6e |
bool m_isCanceled;
|
|
Shinya Kitaoka |
120a6e |
long m_kkkk;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
enum State { Running, Canceled };
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
static boost::mutex m_mutex;
|
|
Shinya Kitaoka |
120a6e |
static std::map<long, state=""> m_state;</long,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
class Key {
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
Key(long id) : m_id(id) {}
|
|
Shinya Kitaoka |
120a6e |
long m_id;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
static boost::thread_specific_ptr<key> m_key;</key>
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
boost::mutex Thread::Imp::m_mutex;
|
|
Toshihiro Shimizu |
890ddd |
std::map<long, thread::imp::state=""> Thread::Imp::m_state;</long,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
boost::thread_specific_ptr<thread::imp::key> Thread::Imp::m_key;</thread::imp::key>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void BoostRunnable::operator()() {
|
|
Shinya Kitaoka |
120a6e |
Thread::Imp::m_key.reset(new Thread::Imp::Key(reinterpret_cast<long>(this)));</long>
|
|
Shinya Kitaoka |
120a6e |
m_threadImp->m_kkkk = reinterpret_cast<long>(this);</long>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
boost::mutex::scoped_lock sl(Thread::Imp::m_mutex);
|
|
Shinya Kitaoka |
120a6e |
Thread::Imp::m_state[m_threadImp->m_kkkk] = Thread::Imp::Running;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(m_runnable);
|
|
Shinya Kitaoka |
120a6e |
m_runnable->run();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
boost::mutex::scoped_lock sl(Thread::Imp::m_mutex);
|
|
Shinya Kitaoka |
120a6e |
Thread::Imp::m_state.erase(reinterpret_cast<long>(this));</long>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Thread::Thread() : m_imp(new Thread::Imp) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Thread::Thread(const TThread::RunnableP &runnable) : m_imp(new Imp(runnable)) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Thread::~Thread() { delete m_imp; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Thread::join() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp->m_boostThread);
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_boostThread->join();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Thread::cancel() {
|
|
Shinya Kitaoka |
120a6e |
boost::mutex::scoped_lock sl(Thread::Imp::m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::map<long, thread::imp::state="">::iterator it =</long,>
|
|
Shinya Kitaoka |
120a6e |
Thread::Imp::m_state.find(m_imp->m_kkkk);
|
|
Shinya Kitaoka |
120a6e |
if (it != Thread::Imp::m_state.end())
|
|
Shinya Kitaoka |
120a6e |
Thread::Imp::m_state[m_imp->m_kkkk] = Thread::Imp::Canceled;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// static member function
|
|
|
e280ae |
#if defined(_MSC_VER) && (_MSC_VER == 1200)
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(disable : 4290)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Thread::milestone() throw(TThread::Interrupt) {
|
|
Shinya Kitaoka |
120a6e |
boost::mutex::scoped_lock sl(Thread::Imp::m_mutex);
|
|
Shinya Kitaoka |
120a6e |
Thread::Imp::Key key = *Thread::Imp::m_key.get();
|
|
Shinya Kitaoka |
120a6e |
Thread::Imp::m_state.find(key.m_id);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (Thread::Imp::m_state[key.m_id]) throw TThread::Interrupt();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
e280ae |
#if defined(_MSC_VER) && (_MSC_VER == 1200)
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(default : 4290)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class ThreadGroup::Imp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Imp() : m_boostThreadGroup() {}
|
|
Shinya Kitaoka |
120a6e |
~Imp() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
boost::thread_group m_boostThreadGroup;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ThreadGroup::ThreadGroup() : m_imp(new Imp) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ThreadGroup::~ThreadGroup() { delete m_imp; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ThreadGroup::add(Thread *thread) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_boostThreadGroup.add_thread(thread->m_imp->m_boostThread);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ThreadGroup::joinAll() { m_imp->m_boostThreadGroup.join_all(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
e280ae |
#if defined(_MSC_VER) && (_MSC_VER == 1200)
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(disable : 4290)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::milestone() throw(TThread::Interrupt) { Thread::milestone(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
e280ae |
#if defined(_MSC_VER) && (_MSC_VER == 1200)
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(default : 4290)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TThread::Mutex::Imp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
boost::mutex m_mutex;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Imp() : m_mutex() {}
|
|
Shinya Kitaoka |
120a6e |
~Imp() {}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::Mutex::Mutex() : m_imp(new Imp) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::Mutex::~Mutex() { delete m_imp; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TThread::ScopedLock::Imp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
boost::mutex::scoped_lock *m_sl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Imp(boost::mutex &mutex) : m_sl(new boost::mutex::scoped_lock(mutex)) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
~Imp() {
|
|
Shinya Kitaoka |
120a6e |
m_sl->unlock();
|
|
Shinya Kitaoka |
120a6e |
delete m_sl;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock::ScopedLock(Mutex &mutex)
|
|
Shinya Kitaoka |
120a6e |
: m_imp(new Imp(mutex.m_imp->m_mutex)) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock::~ScopedLock() { delete m_imp; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TThread::Condition::Imp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
boost::condition m_condition;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Imp() : m_condition() {}
|
|
Shinya Kitaoka |
120a6e |
~Imp() {}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::Condition::Condition() : m_imp(new Imp()) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::Condition::~Condition() { delete m_imp; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Condition::wait(ScopedLock &lock) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_condition.wait(*(lock.m_imp->m_sl));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TThread::Condition::wait(ScopedLock &lock, long timeout) {
|
|
Shinya Kitaoka |
120a6e |
boost::xtime xt;
|
|
Shinya Kitaoka |
120a6e |
boost::xtime_get(&xt, boost::TIME_UTC);
|
|
Shinya Kitaoka |
120a6e |
xt.nsec += timeout * 1000;
|
|
Shinya Kitaoka |
120a6e |
xt.sec += timeout / 1000;
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_condition.timed_wait(*(lock.m_imp->m_sl), xt);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Condition::notifyOne() { m_imp->m_condition.notify_one(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Condition::notifyAll() { m_imp->m_condition.notify_all(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::Msg::Msg() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Msg::send() {
|
|
Shinya Kitaoka |
120a6e |
Msg *msg = clone();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
Non viene utilizzato PostThreadMessage perche' se l'applicazione
|
|
Shinya Kitaoka |
120a6e |
si trova in un modal loop (esempio MessageBox) oppure si sta
|
|
Toshihiro Shimizu |
890ddd |
facendo move o resize di una finestra i messaggi non giungono al
|
|
Toshihiro Shimizu |
890ddd |
message loop.
|
|
Shinya Kitaoka |
120a6e |
http://support.microsoft.com/default.aspx?scid=KB;EN-US;q183116&
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
BOOL rc = PostThreadMessage(
|
|
Shinya Kitaoka |
120a6e |
getMainThreadId(), // thread identifier
|
|
Shinya Kitaoka |
120a6e |
WM_THREAD_NOTIFICATION, // message
|
|
Shinya Kitaoka |
120a6e |
WPARAM(msg), // first message parameter
|
|
Shinya Kitaoka |
120a6e |
0); // second message parameter
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
PostMessage(HWND(getMainShellHandle()), WM_THREAD_NOTIFICATION, WPARAM(msg),
|
|
Shinya Kitaoka |
120a6e |
0);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
XClientMessageEvent clientMsg;
|
|
Shinya Kitaoka |
120a6e |
clientMsg.type = ClientMessage;
|
|
Shinya Kitaoka |
120a6e |
clientMsg.window = TheMainWindow;
|
|
Shinya Kitaoka |
120a6e |
clientMsg.format = 32;
|
|
Shinya Kitaoka |
120a6e |
clientMsg.message_type = Msg::MsgId();
|
|
Shinya Kitaoka |
120a6e |
clientMsg.data.l[0] = (long)msg;
|
|
Shinya Kitaoka |
120a6e |
// Status status =
|
|
Shinya Kitaoka |
120a6e |
XSendEvent(TheDisplay, TheMainWindow, 0, NoEventMask, (XEvent *)&clientMsg);
|
|
Shinya Kitaoka |
120a6e |
XFlush(TheDisplay);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// statica
|
|
Shinya Kitaoka |
120a6e |
UINT TThread::Msg::MsgId() {
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
return WM_THREAD_NOTIFICATION;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
static Atom atom = 0;
|
|
Shinya Kitaoka |
120a6e |
if (!atom) {
|
|
Shinya Kitaoka |
120a6e |
atom = XInternAtom(TheDisplay, "ThreadMessage", false);
|
|
Shinya Kitaoka |
120a6e |
assert(atom);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return atom;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TThread::Executor::Imp : public TSmartObject {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
typedef TSmartPointerT<tthread::executor::imp> ImpP;</tthread::executor::imp>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//---------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class Worker : public Runnable {
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
Worker(ImpP owner) : Runnable(), m_owner(owner) {}
|
|
Shinya Kitaoka |
120a6e |
~Worker() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void run();
|
|
Shinya Kitaoka |
120a6e |
void doCleanup();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ImpP m_owner;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//---------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool m_suspend;
|
|
Shinya Kitaoka |
120a6e |
bool m_threadHasToDie;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UINT m_threadCount;
|
|
Shinya Kitaoka |
120a6e |
Mutex m_mutex;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Condition m_cond;
|
|
Shinya Kitaoka |
120a6e |
Condition m_taskQueueEmpty;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//------
|
|
Shinya Kitaoka |
120a6e |
Condition m_taskQueueNotEmpty;
|
|
Shinya Kitaoka |
120a6e |
//------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::queue<tthread::runnablep> m_tasks;</tthread::runnablep>
|
|
Shinya Kitaoka |
120a6e |
std::map<long, *="" thread=""> m_workerThreads;</long,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Imp(int threadsCount, bool suspend)
|
|
Shinya Kitaoka |
120a6e |
: TSmartObject()
|
|
Shinya Kitaoka |
120a6e |
, m_suspend(suspend)
|
|
Shinya Kitaoka |
120a6e |
, m_threadHasToDie(false)
|
|
Shinya Kitaoka |
120a6e |
, m_threadCount(threadsCount)
|
|
Shinya Kitaoka |
120a6e |
, m_tasks()
|
|
Shinya Kitaoka |
120a6e |
, m_workerThreads()
|
|
Shinya Kitaoka |
120a6e |
, m_mutex()
|
|
Shinya Kitaoka |
120a6e |
, m_cond(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
~Imp() {}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::Executor::Executor(int threadsCount, bool suspend)
|
|
Shinya Kitaoka |
120a6e |
: m_imp(new Imp(threadsCount, suspend)) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->addRef();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::Executor::~Executor() {
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_suspend) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_threadHasToDie = true;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_taskQueueNotEmpty.notifyAll();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->release();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Executor::Imp::Worker::run() {
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
while (true) {
|
|
Shinya Kitaoka |
120a6e |
// check if thread has been canceled
|
|
Shinya Kitaoka |
120a6e |
Thread::milestone();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// get the next task
|
|
Shinya Kitaoka |
120a6e |
RunnableP task = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
ScopedLock sl(m_owner->m_mutex);
|
|
Shinya Kitaoka |
120a6e |
if (m_owner->m_tasks.empty()) {
|
|
Shinya Kitaoka |
120a6e |
// la lista di task e' stata esaurita
|
|
Shinya Kitaoka |
120a6e |
if (m_owner->m_suspend) {
|
|
Shinya Kitaoka |
120a6e |
// il thread deve sospendersi
|
|
Shinya Kitaoka |
120a6e |
m_owner->m_taskQueueNotEmpty.wait(sl);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// a questo punto il thread e' stato risvegliato
|
|
Shinya Kitaoka |
120a6e |
if (m_owner->m_threadHasToDie) {
|
|
Shinya Kitaoka |
120a6e |
doCleanup();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// il thread sta per morire -> bisogna eliminarlo dalla lista dei
|
|
Shinya Kitaoka |
120a6e |
// worker thread
|
|
Shinya Kitaoka |
120a6e |
doCleanup();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_owner->m_tasks.empty()) {
|
|
Shinya Kitaoka |
120a6e |
task = m_owner->m_tasks.front();
|
|
Shinya Kitaoka |
120a6e |
m_owner->m_tasks.pop();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (task) task->run();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// check if thread has been canceled
|
|
Shinya Kitaoka |
120a6e |
Thread::milestone();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} catch (TThread::Interrupt &) {
|
|
Shinya Kitaoka |
120a6e |
// m_owner->m_cond.notifyOne();
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
// eccezione non prevista --> bisogna eliminare il thread
|
|
Shinya Kitaoka |
120a6e |
// dalla lista dei worker thread
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ScopedLock sl(m_owner->m_mutex);
|
|
Shinya Kitaoka |
120a6e |
doCleanup();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Executor::Imp::Worker::doCleanup() {
|
|
Shinya Kitaoka |
120a6e |
std::map<long, *="" thread="">::iterator it =</long,>
|
|
Shinya Kitaoka |
120a6e |
m_owner->m_workerThreads.find(reinterpret_cast<long>(this));</long>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (it != m_owner->m_workerThreads.end()) {
|
|
Shinya Kitaoka |
120a6e |
Thread *thread = it->second;
|
|
Shinya Kitaoka |
120a6e |
delete thread;
|
|
Shinya Kitaoka |
120a6e |
m_owner->m_workerThreads.erase(it);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_owner->m_workerThreads.size() == 0)
|
|
Shinya Kitaoka |
120a6e |
m_owner->m_taskQueueEmpty.notifyAll();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Executor::addTask(const RunnableP &task) {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_tasks.push(task);
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_workerThreads.size() < m_imp->m_threadCount) {
|
|
Shinya Kitaoka |
120a6e |
TThread::Executor::Imp::Worker *worker =
|
|
Shinya Kitaoka |
120a6e |
new TThread::Executor::Imp::Worker(m_imp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_workerThreads[reinterpret_cast<long>(worker)] = new Thread(worker);</long>
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_suspend)
|
|
Shinya Kitaoka |
120a6e |
// risveglia uno dei thread in attesa
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_taskQueueNotEmpty.notifyOne();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Executor::clear() {
|
|
Shinya Kitaoka |
120a6e |
ScopedLock sl(m_imp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (!m_imp->m_tasks.empty()) m_imp->m_tasks.pop();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Executor::cancel() {
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
ScopedLock sl(m_imp->m_mutex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (!m_imp->m_tasks.empty()) m_imp->m_tasks.pop();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (true) {
|
|
Shinya Kitaoka |
120a6e |
Thread *thread = 0;
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
ScopedLock sl(m_imp->m_mutex);
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_workerThreads.empty())
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
std::map<long, *="" thread="">::iterator it = m_imp->m_workerThreads.begin();</long,>
|
|
Shinya Kitaoka |
120a6e |
thread = it->second;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_workerThreads.erase(it);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (thread) thread->cancel();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TThread::Executor::wait() {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (m_imp->m_workerThreads.size()) m_imp->m_taskQueueEmpty.wait(sl);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TThread::Executor::wait(long timeout) {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool expired = false;
|
|
Shinya Kitaoka |
120a6e |
while (m_imp->m_workerThreads.size())
|
|
Shinya Kitaoka |
120a6e |
expired = m_imp->m_taskQueueEmpty.wait(sl, timeout);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return expired;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TThread::Executor::getThreadCount() {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_workerThreads.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TThread::Executor::getTaskCount() {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_tasks.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|