Skip to content
Snippets Groups Projects
Commit 0b324501 authored by slevy's avatar slevy
Browse files

Some pthreads helpers.

parent b22dcb64
No related branches found
No related tags found
No related merge requests found
#ifndef THREADABLE_H
#define THREADABLE_H 1
/*
* Generic class for something readable by a threaded assistant
*/
#include <pthread.h>
template <class T> class Threader {
private:
bool threaded_; // is a separate reader thread running?
pthread_t th_;
pthread_mutex_t mut_; // lock on shared data
char *name_;
public:
Threader() : threaded_(false), name_(NULL)
{
pthread_mutex_init( &mut_, NULL );
}
class Thunk {
void *(T::*func_)(void);
T *inst_;
// private constructor -- thanks to Matt Hall
Thunk( T *inst, void *(T::*func)() ) : inst_(inst), func_(func)
{ }
public:
static Thunk *make( T *inst, void *(T::*func)(void) ) {
return new Thunk( inst, func );
}
static void *call( Thunk *deleteme ) {
Thunk t = *deleteme;
delete deleteme;
return ((t.inst_)->*(t.func_))();
}
};
public:
void start( T *inst, void *(T::*func)(void) ) {
threaded_ = true;
Thunk *g = Thunk::make( inst, func );
pthread_create( &th_, NULL, (void *(*)(void *))&g->call, (void *)g );
}
pthread_mutex_t &mutex() { return mut_; }
bool threading() const { return threaded_; }
void lock() {
if(threaded_) {
if(pthread_mutex_lock( &mut_ ) != 0) {
fprintf(stderr, "%s->lock(): %s\n",
name_ ? name_ : "Threader", strerror(errno));
}
}
}
void unlock() {
if(threaded_) {
if(pthread_mutex_unlock( &mut_ ) != 0) {
fprintf(stderr, "%s->unlock(): %s\n",
name_ ? name_ : "Threader", strerror(errno));
}
}
}
void testcancel() {
if(threaded_) pthread_testcancel();
}
void cancel() {
if(threaded_) {
if(pthread_cancel( th_ ) != 0) {
fprintf(stderr, "%s->cancel(0x%lx): %s\n",
name_ ? name_ : "Threadable",
(long int)th_, strerror(errno));
}
}
}
};
// Maybe convenient for above?
// { scoped_lock lock(threader.mutex());
// mess with threader's contents
// }
class scoped_lock {
pthread_mutex_t *m_;
public:
scoped_lock( pthread_mutex_t &mut ) {
m_ = &mut;
pthread_mutex_lock( m_ );
}
~scoped_lock() {
pthread_mutex_unlock( m_ );
}
};
#endif /*THREADABLE_H*/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment