mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2025-12-16 12:08:36 +00:00
81 lines
1.7 KiB
C++
81 lines
1.7 KiB
C++
#include "base/thread.h"
|
|
#include "base/tick.h"
|
|
|
|
namespace base {
|
|
|
|
pthread_key_t Thread::s_key_;
|
|
|
|
Thread::Thread(SocketServer *ss) : start_routine_(NULL), start_pv_(NULL),
|
|
started_(false), MessageQueue(ss) {
|
|
static bool s_first_thread;
|
|
if (!s_first_thread) {
|
|
pthread_key_create(&s_key_, NULL);
|
|
pthread_setspecific(s_key_, this);
|
|
s_first_thread = true;
|
|
}
|
|
}
|
|
|
|
Thread::~Thread() {
|
|
Stop();
|
|
}
|
|
|
|
void Thread::Start(void (start_routine)(void *), void *start_pv) {
|
|
start_routine_ = start_routine;
|
|
start_pv_ = start_pv;
|
|
pthread_create(&thread_, NULL, PreRun, this);
|
|
}
|
|
|
|
void *Thread::PreRun(void *pv) {
|
|
Thread *thread = (Thread *)pv;
|
|
pthread_setspecific(s_key_, thread);
|
|
thread->started_ = true;
|
|
if (thread->start_routine_ != NULL) {
|
|
thread->start_routine_(thread->start_pv_);
|
|
} else {
|
|
thread->RunLoop();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void Thread::CallerStart(void *pv) {
|
|
ICaller *caller = (ICaller *)pv;
|
|
caller->Call();
|
|
delete caller;
|
|
}
|
|
|
|
void Thread::Stop(bool wait) {
|
|
MessageQueue::Stop();
|
|
if (wait && started_ && ¤t() != this) {
|
|
void *pv;
|
|
pthread_join(thread_, &pv);
|
|
}
|
|
}
|
|
|
|
void Thread::RunLoop(long64 ct) {
|
|
Thread& thread = current();
|
|
|
|
long64 tEnd;
|
|
if (ct != kctForever) {
|
|
tEnd = base::GetTickCount() + ct;
|
|
}
|
|
long64 ctNext = ct;
|
|
|
|
while (true) {
|
|
Message msg;
|
|
if (!thread.Get(&msg, ctNext)) {
|
|
return;
|
|
}
|
|
thread.Dispatch(&msg);
|
|
|
|
if (ct != -1) {
|
|
long64 tCur = base::GetTickCount();
|
|
if (tCur >= tEnd) {
|
|
return;
|
|
}
|
|
ctNext = tEnd - tCur;
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace base
|