<
html
>
<
head
>
<
title
>pasync.h</
title
>
<
style
type
=
"text/css"
>
/*
Webcpp v0.8.1 compatible StyleSheet
Theme: ide-msvcpp
*/
body
{
background-color: #ffffff
}
.webcpp a:link {color:#000000}
.webcpp a:visited {color:#008000}
.webcpp a:active {color:#0000ff}
.webcpp a:hover {color:#0000ff}
.webcpp pre
{
color: #000000
}
.webcpp font
{
font-size:100%
}
.webcpp .symbols
{
color: #000000
}
.webcpp .preproc
{
color: #0000ff
}
.webcpp .integer
{
color: #000000
}
.webcpp .floatpt
{
color: #000000
}
.webcpp .dblquot
{
color: #000000
}
.webcpp .sinquot
{
color: #000000
}
.webcpp .keyword
{
color: #0000ff;
}
.webcpp .keytype
{
color: #0000ff;
}
.webcpp .comment
{
color: #008000;
}
</
style
>
</
head
>
<
body
bgcolor
=
"#FFFFFF"
leftmargin
=
"40"
marginwidth
=
"40"
> <
p
><
a
href
=
"../htsrc.html"
>Index</
a
><
hr
noshade></
p
>
<
div
class
=
"webcpp"
>
<
pre
>
<
font
CLASS
=
preproc
>#ifndef</
font
> __PASYNC_H__
<
font
CLASS
=
preproc
>#define</
font
> __PASYNC_H__
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
<
font
CLASS
=
preproc
>#</
font
> define _WINSOCKAPI_ <
font
CLASS
=
comment
>// prevent inclusion of winsock.h, since we need winsock2.h </
font
>
<
font
CLASS
=
preproc
>#</
font
> include <
windows.h
>
<
font
CLASS
=
preproc
>#else</
font
>
<
font
CLASS
=
preproc
>#</
font
> include <
pthread.h
>
<
font
CLASS
=
preproc
>#</
font
> ifndef __bsdi__
<
font
CLASS
=
preproc
>#</
font
> include <
semaphore.h
>
<
font
CLASS
=
preproc
>#</
font
> endif
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
preproc
>#ifndef</
font
> __PPORT_H__
<
font
CLASS
=
preproc
>#include</
font
> <
font
CLASS
=
dblquot
>"pport.h"</
font
>
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
preproc
>#ifndef</
font
> __PTYPES_H__
<
font
CLASS
=
preproc
>#include</
font
> <
font
CLASS
=
dblquot
>"ptypes.h"</
font
>
<
font
CLASS
=
preproc
>#endif</
font
>
PTYPES_BEGIN
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// Summary of implementation:</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// atomic increment/decrement/exchange</
font
>
<
font
CLASS
=
comment
>// MSVC/BCC/i386: internal, asm</
font
>
<
font
CLASS
=
comment
>// GCC/i386: internal, asm</
font
>
<
font
CLASS
=
comment
>// GCC/PowerPC: internal, asm</
font
>
<
font
CLASS
=
comment
>// GCC/SPARC: internal, asm</
font
>
<
font
CLASS
=
comment
>// Other: internal, mutex hash table</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// mutex</
font
>
<
font
CLASS
=
comment
>// Win32: Critical section</
font
>
<
font
CLASS
=
comment
>// Other: POSIX mutex</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// trigger</
font
>
<
font
CLASS
=
comment
>// Win32: Event</
font
>
<
font
CLASS
=
comment
>// Other: internal, POSIX condvar/mutex</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// rwlock:</
font
>
<
font
CLASS
=
comment
>// Win32: internal, Event/mutex</
font
>
<
font
CLASS
=
comment
>// MacOS: internal, POSIX condvar/mutex</
font
>
<
font
CLASS
=
comment
>// Other: POSIX rwlock</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// semaphore:</
font
>
<
font
CLASS
=
comment
>// Win32: = timedsem</
font
>
<
font
CLASS
=
comment
>// MacOS: = timedsem</
font
>
<
font
CLASS
=
comment
>// Other: POSIX semaphore</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// timedsem (with timed waiting):</
font
>
<
font
CLASS
=
comment
>// Win32: Semaphore</
font
>
<
font
CLASS
=
comment
>// Other: internal, POSIX mutex/condvar</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> _MSC_VER
<
font
CLASS
=
preproc
>#pragma</
font
> pack(<
font
CLASS
=
keyword
>push</
font
>, <
font
CLASS
=
integer
>4</
font
>)
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
typedef <
font
CLASS
=
keyword
>int</
font
> pthread_id_t<
font
CLASS
=
comment
>;</
font
>
typedef HANDLE pthread_t<
font
CLASS
=
comment
>;</
font
>
<
font
CLASS
=
preproc
>#else</
font
>
typedef pthread_t pthread_id_t<
font
CLASS
=
comment
>;</
font
>
<
font
CLASS
=
preproc
>#endif</
font
>
void psleep(uint milliseconds)<
font
CLASS
=
comment
>;</
font
>
bool pthrequal(pthread_id_t id)<
font
CLASS
=
comment
>; // note: this is NOT the thread handle, use thread::get_id()</
font
>
pthread_id_t pthrself()<
font
CLASS
=
comment
>; // ... same</
font
>
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// --- mutex ---------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
struct mutex: public noncopyable
{
<
font
CLASS
=
preproc
>protected:</
font
>
CRITICAL_SECTION critsec<
font
CLASS
=
comment
>;</
font
>
<
font
CLASS
=
preproc
>public:</
font
>
mutex() { InitializeCriticalSection(&<
font
CLASS
=
comment
>;critsec); }</
font
>
~mutex() { DeleteCriticalSection(&critsec); }
<
font
CLASS
=
keytype
>void</
font
> enter() { EnterCriticalSection(&critsec); }
<
font
CLASS
=
keytype
>void</
font
> leave() { LeaveCriticalSection(&critsec); }
<
font
CLASS
=
keytype
>void</
font
> lock() { enter(); }
<
font
CLASS
=
keytype
>void</
font
> unlock() { leave(); }
};
<
font
CLASS
=
preproc
>#else</
font
>
<
font
CLASS
=
keyword
>struct</
font
> mutex: public noncopyable
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
pthread_mutex_t mtx;
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
mutex() { pthread_mutex_init(&mtx, <
font
CLASS
=
integer
>0</
font
>); }
~mutex() { pthread_mutex_destroy(&mtx); }
<
font
CLASS
=
keytype
>void</
font
> enter() { pthread_mutex_lock(&mtx); }
<
font
CLASS
=
keytype
>void</
font
> leave() { pthread_mutex_unlock(&mtx); }
<
font
CLASS
=
keytype
>void</
font
> lock() { enter(); }
<
font
CLASS
=
keytype
>void</
font
> unlock() { leave(); }
};
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// scopelock</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
keyword
>class</
font
> scopelock: <
font
CLASS
=
keyword
>public</
font
> noncopyable
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
mutex* mtx;
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
scopelock(mutex& imtx): mtx(&imtx) { mtx<
font
CLASS
=
symbols
>-</
font
>>lock(); }
~scopelock() { mtx<
font
CLASS
=
symbols
>-</
font
>>unlock(); }
};
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// mutex table for hashed memory locking (undocumented)</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
preproc
>#define</
font
> _MUTEX_HASH_SIZE <
font
CLASS
=
integer
>29</
font
> <
font
CLASS
=
comment
>// a prime number for hashing </
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
<
font
CLASS
=
preproc
>#</
font
> define pmemlock mutex
<
font
CLASS
=
preproc
>#</
font
> define pmementer(m) (m)<
font
CLASS
=
symbols
>-</
font
>>lock()
<
font
CLASS
=
preproc
>#</
font
> define pmemleave(m) (m)<
font
CLASS
=
symbols
>-</
font
>>unlock()
<
font
CLASS
=
preproc
>#else</
font
>
<
font
CLASS
=
preproc
>#</
font
> define _MTX_INIT PTHREAD_MUTEX_INITIALIZER
<
font
CLASS
=
preproc
>#</
font
> define pmemlock pthread_mutex_t
<
font
CLASS
=
preproc
>#</
font
> define pmementer pthread_mutex_lock
<
font
CLASS
=
preproc
>#</
font
> define pmemleave pthread_mutex_unlock
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
keyword
>extern</
font
> pmemlock _mtxtable[_MUTEX_HASH_SIZE];
<
font
CLASS
=
preproc
>#define</
font
> pgetmemlock(addr) (_mtxtable <
font
CLASS
=
symbols
>+</
font
> pintptr(addr) % _MUTEX_HASH_SIZE)
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// --- trigger -------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
<
font
CLASS
=
keyword
>class</
font
> trigger: public noncopyable
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
HANDLE handle; <
font
CLASS
=
comment
>// Event object</
font
>
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
trigger(<
font
CLASS
=
keytype
>bool</
font
> autoreset, <
font
CLASS
=
keytype
>bool</
font
> state);
~trigger() { CloseHandle(handle); }
<
font
CLASS
=
keytype
>void</
font
> wait() { WaitForSingleObject(handle, INFINITE); }
<
font
CLASS
=
keytype
>void</
font
> post() { SetEvent(handle); }
<
font
CLASS
=
keytype
>void</
font
> signal() { post(); }
<
font
CLASS
=
keytype
>void</
font
> reset() { ResetEvent(handle); }
};
<
font
CLASS
=
preproc
>#else</
font
>
<
font
CLASS
=
keyword
>class</
font
> trigger: public noncopyable
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
pthread_mutex_t mtx;
pthread_cond_t cond;
<
font
CLASS
=
keytype
>int</
font
> state;
<
font
CLASS
=
keytype
>bool</
font
> autoreset;
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
trigger(<
font
CLASS
=
keytype
>bool</
font
> autoreset, <
font
CLASS
=
keytype
>bool</
font
> state);
~trigger();
<
font
CLASS
=
keytype
>void</
font
> wait();
<
font
CLASS
=
keytype
>void</
font
> post();
<
font
CLASS
=
keytype
>void</
font
> signal() { post(); }
<
font
CLASS
=
keytype
>void</
font
> reset();
};
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// --- rwlock --------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
preproc
>#if</
font
> defined(WIN32) <
font
CLASS
=
symbols
>||</
font
> defined(__DARWIN__) <
font
CLASS
=
symbols
>||</
font
> defined(__bsdi__)
<
font
CLASS
=
preproc
>#</
font
> define __PTYPES_RWLOCK__
<
font
CLASS
=
preproc
>#elif</
font
> defined(linux)
<
font
CLASS
=
comment
>// on Linux rwlocks are included only with -D_GNU_SOURCE.</
font
>
<
font
CLASS
=
comment
>// programs that don't use rwlocks, do not need to define</
font
>
<
font
CLASS
=
comment
>// _GNU_SOURCE either.</
font
>
<
font
CLASS
=
preproc
>#</
font
> <
font
CLASS
=
keyword
>if</
font
> defined(_GNU_SOURCE) <
font
CLASS
=
symbols
>||</
font
> defined(__USE_UNIX98)
<
font
CLASS
=
preproc
>#</
font
> define __POSIX_RWLOCK__
<
font
CLASS
=
preproc
>#</
font
> endif
<
font
CLASS
=
preproc
>#else</
font
>
<
font
CLASS
=
preproc
>#</
font
> define __POSIX_RWLOCK__
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> __PTYPES_RWLOCK__
<
font
CLASS
=
keyword
>struct</
font
> rwlock: <
font
CLASS
=
keyword
>protected</
font
> mutex
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
HANDLE reading; <
font
CLASS
=
comment
>// Event object</
font
>
HANDLE finished; <
font
CLASS
=
comment
>// Event object</
font
>
<
font
CLASS
=
keytype
>int</
font
> readcnt;
<
font
CLASS
=
keytype
>int</
font
> writecnt;
<
font
CLASS
=
preproc
>#else</
font
>
pthread_mutex_t mtx;
pthread_cond_t readcond;
pthread_cond_t writecond;
<
font
CLASS
=
keytype
>int</
font
> locks;
<
font
CLASS
=
keytype
>int</
font
> writers;
<
font
CLASS
=
keytype
>int</
font
> readers;
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
rwlock();
~rwlock();
<
font
CLASS
=
keytype
>void</
font
> rdlock();
<
font
CLASS
=
keytype
>void</
font
> wrlock();
<
font
CLASS
=
keytype
>void</
font
> unlock();
<
font
CLASS
=
keytype
>void</
font
> lock() { wrlock(); }
};
<
font
CLASS
=
preproc
>#elif</
font
> defined(__POSIX_RWLOCK__)
<
font
CLASS
=
keyword
>struct</
font
> rwlock: public noncopyable
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
pthread_rwlock_t rw;
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
rwlock();
~rwlock() { pthread_rwlock_destroy(&rw); }
<
font
CLASS
=
keytype
>void</
font
> rdlock() { pthread_rwlock_rdlock(&rw); }
<
font
CLASS
=
keytype
>void</
font
> wrlock() { pthread_rwlock_wrlock(&rw); }
<
font
CLASS
=
keytype
>void</
font
> unlock() { pthread_rwlock_unlock(&rw); }
<
font
CLASS
=
keytype
>void</
font
> lock() { wrlock(); }
};
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
preproc
>#if</
font
> defined(__PTYPES_RWLOCK__) <
font
CLASS
=
symbols
>||</
font
> defined(__POSIX_RWLOCK__)
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
comment
>// scoperead & scopewrite</
font
>
<
font
CLASS
=
comment
>//</
font
>
<
font
CLASS
=
keyword
>class</
font
> scoperead: <
font
CLASS
=
keyword
>public</
font
> noncopyable
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
rwlock* rw;
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
scoperead(rwlock& irw): rw(&irw) { rw<
font
CLASS
=
symbols
>-</
font
>>rdlock(); }
~scoperead() { rw<
font
CLASS
=
symbols
>-</
font
>>unlock(); }
};
<
font
CLASS
=
keyword
>class</
font
> scopewrite: <
font
CLASS
=
keyword
>public</
font
> noncopyable
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
rwlock* rw;
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
scopewrite(rwlock& irw): rw(&irw) { rw<
font
CLASS
=
symbols
>-</
font
>>wrlock(); }
~scopewrite() { rw<
font
CLASS
=
symbols
>-</
font
>>unlock(); }
};
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// --- semaphore ------------------------------------------------------ //</
font
>
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
preproc
>#if</
font
> defined(WIN32) <
font
CLASS
=
symbols
>||</
font
> defined(__DARWIN__) <
font
CLASS
=
symbols
>||</
font
> defined(__bsdi__)
<
font
CLASS
=
preproc
>#</
font
> define __SEM_TO_TIMEDSEM__
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> __SEM_TO_TIMEDSEM__
<
font
CLASS
=
comment
>// map ordinary semaphore to timed semaphore</
font
>
<
font
CLASS
=
keyword
>class</
font
> timedsem;
<
font
CLASS
=
keyword
>typedef</
font
> timedsem semaphore;
<
font
CLASS
=
preproc
>#else</
font
>
<
font
CLASS
=
keyword
>class</
font
> semaphore: public unknown
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
sem_t handle;
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
semaphore(<
font
CLASS
=
keytype
>int</
font
> initvalue);
<
font
CLASS
=
keyword
>virtual</
font
> ~semaphore();
<
font
CLASS
=
keytype
>void</
font
> wait();
<
font
CLASS
=
keytype
>void</
font
> post();
<
font
CLASS
=
keytype
>void</
font
> signal() { post(); }
};
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
keyword
>class</
font
> timedsem: public unknown
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
HANDLE handle;
<
font
CLASS
=
preproc
>#else</
font
>
<
font
CLASS
=
keytype
>int</
font
> count;
pthread_mutex_t mtx;
pthread_cond_t cond;
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
timedsem(<
font
CLASS
=
keytype
>int</
font
> initvalue);
<
font
CLASS
=
keyword
>virtual</
font
> ~timedsem();
<
font
CLASS
=
keytype
>bool</
font
> wait(<
font
CLASS
=
keytype
>int</
font
> msecs <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>);
<
font
CLASS
=
keytype
>void</
font
> post();
<
font
CLASS
=
keytype
>void</
font
> signal() { post(); }
};
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// --- thread --------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
keyword
>class</
font
> thread: public unknown
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
<
font
CLASS
=
keytype
>unsigned</
font
> id;
<
font
CLASS
=
preproc
>#endif</
font
>
pthread_t handle;
<
font
CLASS
=
keytype
>int</
font
> autofree;
<
font
CLASS
=
keytype
>int</
font
> running;
<
font
CLASS
=
keytype
>int</
font
> signaled;
<
font
CLASS
=
keytype
>int</
font
> finished;
<
font
CLASS
=
keytype
>int</
font
> freed;
<
font
CLASS
=
keytype
>int</
font
> reserved; <
font
CLASS
=
comment
>// for priorities</
font
>
timedsem relaxsem;
<
font
CLASS
=
keyword
>virtual</
font
> <
font
CLASS
=
keytype
>void</
font
> execute() <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>0</
font
>;
<
font
CLASS
=
keyword
>virtual</
font
> <
font
CLASS
=
keytype
>void</
font
> cleanup();
<
font
CLASS
=
keytype
>bool</
font
> relax(<
font
CLASS
=
keytype
>int</
font
> msecs) { <
font
CLASS
=
keyword
>return</
font
> relaxsem.wait(msecs); }
<
font
CLASS
=
keyword
>friend</
font
> <
font
CLASS
=
keytype
>void</
font
> _threadepilog(thread* thr);
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
<
font
CLASS
=
keyword
>friend</
font
> <
font
CLASS
=
keytype
>unsigned</
font
> __stdcall _threadproc(<
font
CLASS
=
keytype
>void</
font
>* arg);
<
font
CLASS
=
preproc
>#else</
font
>
<
font
CLASS
=
keyword
>friend</
font
> <
font
CLASS
=
keytype
>void</
font
>* _threadproc(<
font
CLASS
=
keytype
>void</
font
>* arg);
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
thread(<
font
CLASS
=
keytype
>bool</
font
> iautofree);
<
font
CLASS
=
keyword
>virtual</
font
> ~thread();
<
font
CLASS
=
preproc
>#ifdef</
font
> WIN32
pthread_id_t get_id() { <
font
CLASS
=
keyword
>return</
font
> <
font
CLASS
=
keytype
>int</
font
>(id); }
<
font
CLASS
=
preproc
>#else</
font
>
pthread_id_t get_id() { <
font
CLASS
=
keyword
>return</
font
> handle; }
<
font
CLASS
=
preproc
>#endif</
font
>
<
font
CLASS
=
keytype
>bool</
font
> get_running() { <
font
CLASS
=
keyword
>return</
font
> running <
font
CLASS
=
symbols
>!=</
font
> <
font
CLASS
=
integer
>0</
font
>; }
<
font
CLASS
=
keytype
>bool</
font
> get_finished() { <
font
CLASS
=
keyword
>return</
font
> finished <
font
CLASS
=
symbols
>!=</
font
> <
font
CLASS
=
integer
>0</
font
>; }
<
font
CLASS
=
keytype
>bool</
font
> get_signaled() { <
font
CLASS
=
keyword
>return</
font
> signaled <
font
CLASS
=
symbols
>!=</
font
> <
font
CLASS
=
integer
>0</
font
>; }
<
font
CLASS
=
keytype
>void</
font
> start();
<
font
CLASS
=
keytype
>void</
font
> signal();
<
font
CLASS
=
keytype
>void</
font
> waitfor();
};
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// --- jobqueue & msgqueue -------------------------------------------- //</
font
>
<
font
CLASS
=
comment
>// -------------------------------------------------------------------- //</
font
>
<
font
CLASS
=
keyword
>const</
font
> <
font
CLASS
=
keytype
>int</
font
> MSG_USER <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>0</
font
>;
<
font
CLASS
=
keyword
>const</
font
> <
font
CLASS
=
keytype
>int</
font
> MSG_QUIT <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>;
<
font
CLASS
=
keyword
>const</
font
> <
font
CLASS
=
keytype
>int</
font
> DEF_QUEUE_LIMIT <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>5000</
font
>;
<
font
CLASS
=
keyword
>class</
font
> message: public unknown
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
message* next; <
font
CLASS
=
comment
>// next in the message chain, used internally</
font
>
semaphore* sync; <
font
CLASS
=
comment
>// used internally by msgqueue::send(), when called from a different thread</
font
>
<
font
CLASS
=
keyword
>friend</
font
> <
font
CLASS
=
keyword
>class</
font
> jobqueue; <
font
CLASS
=
comment
>// my friends, job queue and message queue...</
font
>
<
font
CLASS
=
keyword
>friend</
font
> <
font
CLASS
=
keyword
>class</
font
> msgqueue;
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
<
font
CLASS
=
keytype
>int</
font
> id;
pintptr param;
pintptr result;
message(<
font
CLASS
=
keytype
>int</
font
> iid, pintptr iparam <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>0</
font
>);
<
font
CLASS
=
keyword
>virtual</
font
> ~message();
};
<
font
CLASS
=
keyword
>class</
font
> jobqueue: public noncopyable
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>private</
font
>:</
font
>
<
font
CLASS
=
keytype
>int</
font
> limit; <
font
CLASS
=
comment
>// queue limit</
font
>
message* head; <
font
CLASS
=
comment
>// queue head</
font
>
message* tail; <
font
CLASS
=
comment
>// queue tail</
font
>
<
font
CLASS
=
keytype
>int</
font
> qcount; <
font
CLASS
=
comment
>// number of items in the queue</
font
>
timedsem sem; <
font
CLASS
=
comment
>// queue semaphore</
font
>
timedsem ovrsem; <
font
CLASS
=
comment
>// overflow semaphore</
font
>
mutex qlock; <
font
CLASS
=
comment
>// critical sections in enqueue and dequeue</
font
>
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
<
font
CLASS
=
keytype
>bool</
font
> enqueue(message* msg, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>);
<
font
CLASS
=
keytype
>bool</
font
> push(message* msg, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>);
message* dequeue(<
font
CLASS
=
keytype
>bool</
font
> safe <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
keyword
>true</
font
>, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> -<
font
CLASS
=
integer
>1</
font
>);
<
font
CLASS
=
keytype
>void</
font
> purgequeue();
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
jobqueue(<
font
CLASS
=
keytype
>int</
font
> ilimit <
font
CLASS
=
symbols
>=</
font
> DEF_QUEUE_LIMIT);
<
font
CLASS
=
keyword
>virtual</
font
> ~jobqueue();
<
font
CLASS
=
keytype
>int</
font
> get_count() <
font
CLASS
=
keyword
>const</
font
> { <
font
CLASS
=
keyword
>return</
font
> qcount; }
<
font
CLASS
=
keytype
>int</
font
> get_limit() <
font
CLASS
=
keyword
>const</
font
> { <
font
CLASS
=
keyword
>return</
font
> limit; }
<
font
CLASS
=
keytype
>bool</
font
> post(message* msg, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>);
<
font
CLASS
=
keytype
>bool</
font
> post(<
font
CLASS
=
keytype
>int</
font
> id, pintptr param <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>0</
font
>, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> -<
font
CLASS
=
integer
>1</
font
>);
<
font
CLASS
=
keytype
>bool</
font
> posturgent(message* msg, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>);
<
font
CLASS
=
keytype
>bool</
font
> posturgent(<
font
CLASS
=
keytype
>int</
font
> id, pintptr param <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>0</
font
>, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> -<
font
CLASS
=
integer
>1</
font
>);
message* getmessage(<
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>);
<
font
CLASS
=
preproc
>#ifdef</
font
> PTYPES19_COMPAT
<
font
CLASS
=
keytype
>int</
font
> msgsavail() <
font
CLASS
=
keyword
>const</
font
> { <
font
CLASS
=
keyword
>return</
font
> get_count(); }
<
font
CLASS
=
preproc
>#endif</
font
>
};
<
font
CLASS
=
keyword
>template</
font
> <<
font
CLASS
=
keyword
>class</
font
> T> <
font
CLASS
=
keyword
>class</
font
> tjobqueue: <
font
CLASS
=
keyword
>protected</
font
> jobqueue
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
tjobqueue(<
font
CLASS
=
keytype
>int</
font
> ilimit <
font
CLASS
=
symbols
>=</
font
> DEF_QUEUE_LIMIT);
<
font
CLASS
=
keytype
>int</
font
> get_count() <
font
CLASS
=
keyword
>const</
font
> { <
font
CLASS
=
keyword
>return</
font
> jobqueue::get_count(); }
<
font
CLASS
=
keytype
>int</
font
> get_limit() <
font
CLASS
=
keyword
>const</
font
> { <
font
CLASS
=
keyword
>return</
font
> jobqueue::get_limit(); }
<
font
CLASS
=
keytype
>bool</
font
> post(T* msg, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>) { <
font
CLASS
=
keyword
>return</
font
> jobqueue::post(msg, timeout); }
<
font
CLASS
=
keytype
>bool</
font
> posturgent(T* msg, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>) { <
font
CLASS
=
keyword
>return</
font
> jobqueue::posturgent(msg, timeout); }
T* getmessage(<
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>) { <
font
CLASS
=
keyword
>return</
font
> (T*)jobqueue::getmessage(timeout); }
};
<
font
CLASS
=
keyword
>class</
font
> msgqueue: <
font
CLASS
=
keyword
>protected</
font
> jobqueue
{
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>private</
font
>:</
font
>
mutex thrlock; <
font
CLASS
=
comment
>// lock for the queue processing</
font
>
pthread_id_t owner; <
font
CLASS
=
comment
>// thread ID of the queue processing thread</
font
>
pintptr finishmsg(message* msg);
<
font
CLASS
=
keytype
>void</
font
> handlemsg(message* msg);
<
font
CLASS
=
keytype
>void</
font
> takeownership();
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>protected</
font
>:</
font
>
<
font
CLASS
=
keytype
>bool</
font
> quit;
<
font
CLASS
=
keytype
>void</
font
> defhandler(message& msg);
<
font
CLASS
=
keyword
>virtual</
font
> <
font
CLASS
=
keytype
>void</
font
> msghandler(message& msg) <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>0</
font
>;
<
font
CLASS
=
preproc
><
font
CLASS
=
keyword
>public</
font
>:</
font
>
msgqueue(<
font
CLASS
=
keytype
>int</
font
> ilimit <
font
CLASS
=
symbols
>=</
font
> DEF_QUEUE_LIMIT);
<
font
CLASS
=
keyword
>virtual</
font
> ~msgqueue();
// functions calling from the owner<
font
CLASS
=
preproc
> thread:</
font
>
<
font
CLASS
=
keytype
>void</
font
> processone(); <
font
CLASS
=
comment
>// process one message, may hang if no msgs in the queue</
font
>
<
font
CLASS
=
keytype
>void</
font
> processmsgs(); <
font
CLASS
=
comment
>// process all available messages and return</
font
>
<
font
CLASS
=
keytype
>void</
font
> run(); <
font
CLASS
=
comment
>// process messages until MSG_QUIT</
font
>
// functions calling from any<
font
CLASS
=
preproc
> thread:</
font
>
<
font
CLASS
=
keytype
>int</
font
> get_count() <
font
CLASS
=
keyword
>const</
font
> { <
font
CLASS
=
keyword
>return</
font
> jobqueue::get_count(); }
<
font
CLASS
=
keytype
>int</
font
> get_limit() <
font
CLASS
=
keyword
>const</
font
> { <
font
CLASS
=
keyword
>return</
font
> jobqueue::get_limit(); }
<
font
CLASS
=
keytype
>bool</
font
> post(message* msg, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>) { <
font
CLASS
=
keyword
>return</
font
> jobqueue::post(msg, timeout); }
<
font
CLASS
=
keytype
>bool</
font
> post(<
font
CLASS
=
keytype
>int</
font
> id, pintptr param <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>0</
font
>, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> -<
font
CLASS
=
integer
>1</
font
>) { <
font
CLASS
=
keyword
>return</
font
> jobqueue::post(id, param, timeout); }
<
font
CLASS
=
keytype
>bool</
font
> posturgent(message* msg, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
symbols
>-</
font
><
font
CLASS
=
integer
>1</
font
>) { <
font
CLASS
=
keyword
>return</
font
> jobqueue::posturgent(msg, timeout); }
<
font
CLASS
=
keytype
>bool</
font
> posturgent(<
font
CLASS
=
keytype
>int</
font
> id, pintptr param <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>0</
font
>, <
font
CLASS
=
keytype
>int</
font
> timeout <
font
CLASS
=
symbols
>=</
font
> -<
font
CLASS
=
integer
>1</
font
>) { <
font
CLASS
=
keyword
>return</
font
> jobqueue::posturgent(id, param, timeout); }
pintptr send(message* msg);
pintptr send(int id, pintptr param <
font
CLASS
=
symbols
>=</
font
> <
font
CLASS
=
integer
>0</
font
>);
<
font
CLASS
=
preproc
>#ifdef</
font
> PTYPES19_COMPAT
<
font
CLASS
=
keytype
>int</
font
> msgsavail() <
font
CLASS
=
keyword
>const</
font
> { <
font
CLASS
=
keyword
>return</
font
> get_count(); }
<
font
CLASS
=
preproc
>#endif</
font
>
};
<
font
CLASS
=
preproc
>#ifdef</
font
> _MSC_VER
<
font
CLASS
=
preproc
>#pragma</
font
> pack(pop)
<
font
CLASS
=
preproc
>#endif</
font
>
PTYPES_END
<
font
CLASS
=
preproc
>#endif</
font
> <
font
CLASS
=
comment
>// __PASYNC_H__ </
font
>
</
pre
>
</
div
>
<
hr
noshade></
body
>
</
html
>