Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

331 lines (246 sloc) 4.359 kB
#ifndef com_sleepless_thread_cpp
#define com_sleepless_thread_cpp
// Copyright 1998-2002
// Sleepless Software Inc.
// All Rights Reserved
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff
#include <windows.h>
#include <process.h>
#endif
#if defined(linux) || (defined(__APPLE__) && defined(__GNUC__)) || __CYGWIN__
#include <pthread.h>
#endif
struct Runnable
{
virtual void run() = 0;
virtual ~Runnable() { };
};
struct Thread : Runnable
{
#ifdef WIN32
HANDLE event;
#endif
#if defined(linux) || (defined(__APPLE__) && defined(__GNUC__)) || __CYGWIN__
pthread_t pt;
#endif
Runnable *runnable;
bool started;
void init(Runnable *r)
{
started = false;
runnable = r;
#ifdef WIN32
event = CreateEvent(0, false, false, 0);
#endif
}
Thread(Runnable *r)
{
init(r);
}
Thread()
{
init(this);
}
virtual ~Thread()
{
#ifdef WIN32
CloseHandle(event);
#endif
}
void start()
{
#ifdef WIN32
_beginthread(stub, 0, this);
#endif
#if defined(linux) || (defined(__APPLE__) && defined(__GNUC__)) || __CYGWIN__
pthread_create(&pt, NULL, stub, this);
#endif
}
int join()
{
if(started)
{
#ifdef WIN32
WaitForSingleObject(event, INFINITE);
#endif
#if defined(linux) || (defined(__APPLE__) && defined(__GNUC__)) || __CYGWIN__
return pthread_join(pt, NULL);
#endif
started = false;
}
return 0;
}
#ifdef WIN32
static void stub(void *p)
#endif
#if defined(linux) || (defined(__APPLE__) && defined(__GNUC__)) || __CYGWIN__
static void *stub(void *p)
#endif
{
Thread *th = (Thread *)p;
th->started = true;
th->runnable->run();
#ifdef WIN32
SetEvent(th->event);
#endif
#if defined(linux) || (defined(__APPLE__) && defined(__GNUC__)) || __CYGWIN__
return 0;
#endif
}
virtual void run()
{
}
};
#if 0
// XXX re-visit this shit and make it so that thread return codes can
// be retrieved.
struct Thread // : Runnable
{
#ifdef WIN32
void *ud;
HANDLE event;
void *(*func)(void *);
Thread()
{
func = 0;
}
Thread(void *(*_func)(void *))
{
func = _func;
event = CreateEvent(0, false, false, 0);
}
virtual ~Thread()
{
CloseHandle(event);
}
int start(void *_ud)
{
ud = _ud;
return _beginthread(stub, 0, this) == -1;
}
static int join(Thread *th)
{
WaitForSingleObject(th->event, INFINITE);
return 0;
}
static void stub(void *p)
{
Thread *th = (Thread *)p;
th->func(th->ud);
SetEvent(th->event);
}
#endif
#if defined(linux) || (defined(__APPLE__) && defined(__GNUC__))
pthread_t pt;
void *(*func)(void *);
Thread()
{
func = 0;
}
Thread(void *(*_func)(void *))
{
func = _func;
}
virtual ~Thread()
{
}
int start(void *ud)
{
return pthread_create(&pt, NULL, func, ud);
}
static int join(Thread *th)
{
return pthread_join(th->pt, NULL);
}
#endif
};
// Runnable interface.
struct Runnable
{
Thread *thread;
Runnable()
{
thread = 0;
}
static void *threadEntry(void *p)
{
Runnable *r = (Runnable *)p;
r->run();
return 0;
}
virtual void start()
{
if(thread)
{
return;
}
thread = new Thread(threadEntry);
if(thread)
{
thread->start(this);
}
}
void join()
{
if(thread)
{
Thread::join(thread);
delete thread;
thread = 0;
}
}
virtual void run() = 0;
};
#endif
#ifdef TEST_THREAD
#include <stdio.h>
//#include <unistd.h>
#include "system.cpp"
int main(int argc, char **argv)
{
printf("main enter ...\n");
printf("starting plain thread \n");
Thread th;
th.start();
th.join();
printf("plain thread joined\n");
printf("starting thread subclass \n");
struct ThreadSubclass : Thread
{
void run()
{
printf("ThreadSubclass %p running\n", this);
}
} sub;
sub.start();
sub.join();
printf("thread subclass joined\n");
printf("firing off 2 ThreadSubclasses\n");
ThreadSubclass sub1;
ThreadSubclass sub2;
sub1.start();
sub2.start();
printf("fired and forgotten. sleeping 2 secs ...\n");
System::ssleep(2);
printf("joining them now\n");
sub1.join();
sub2.join();
printf("joined\n");
struct RunSub : Runnable
{
void run()
{
printf("RunSub %p running\n", this);
}
};
RunSub rs1;
printf("running RunSub class \n");
Thread th_r1(&rs1);
th_r1.start();
printf("RunSub class started\n");
th_r1.join();
printf("RunSub class joined\n");
}
#endif
#endif // com_sleepless_thread_cpp
Jump to Line
Something went wrong with that request. Please try again.