kviewshell
GThreads.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifndef _GTHREADS_H_
00058 #define _GTHREADS_H_
00059 #ifdef HAVE_CONFIG_H
00060 #include "config.h"
00061 #endif
00062 #if NEED_GNUG_PRAGMAS
00063 # pragma interface
00064 #endif
00065
00066
00132
00133
00134 #include "DjVuGlobal.h"
00135 #include "GException.h"
00136
00137 #define NOTHREADS 0
00138 #define COTHREADS 1
00139 #define JRITHREADS 2
00140 #define POSIXTHREADS 10
00141 #define WINTHREADS 11
00142 #define MACTHREADS 12
00143
00144
00145 #ifndef THREADMODEL
00146 #if defined(WIN32)
00147 #define THREADMODEL WINTHREADS
00148 #endif
00149 #if defined(macintosh)
00150 #define THREADMODEL MACTHREADS
00151 #endif
00152 #endif
00153
00154
00155 #ifdef USE_EXCEPTION_EMULATION
00156 #undef THREADMODEL
00157 #define THREADMODEL NOTHREADS
00158 #endif
00159
00160 #ifndef THREADMODEL
00161 #define THREADMODEL NOTHREADS
00162 #endif
00163
00164
00165
00166
00167 #if THREADMODEL==WINTHREADS
00168 #ifndef _WINDOWS_
00169 #define WIN32_LEAN_AND_MEAN
00170 #include "windows.h"
00171 #endif
00172 #endif
00173
00174 #if THREADMODEL==MACTHREADS
00175 #include <threads.h>
00176 #endif
00177
00178 #if THREADMODEL==POSIXTHREADS
00179 #include <sys/types.h>
00180 #include <sys/time.h>
00181 #include <unistd.h>
00182 #undef TRY
00183 #undef CATCH
00184 #define _CMA_NOWRAPPERS_
00185 #include <pthread.h>
00186 #endif
00187
00188 #if THREADMODEL==JRITHREADS
00189 #include "jri.h"
00190 #endif
00191
00192 #if THREADMODEL==COTHREADS
00193 #include <sys/types.h>
00194 #include <sys/time.h>
00195 #include <unistd.h>
00196 #endif
00197
00198
00199
00200
00201
00202
00203 #ifdef HAVE_NAMESPACES
00204 namespace DJVU {
00205 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00206 }
00207 #endif
00208 #endif
00209
00210
00211
00230 class GThread {
00231 public:
00238 GThread(int stacksize = -1);
00242 ~GThread();
00247 int create(void (*entry)(void*), void *arg);
00253 void terminate();
00262 static int yield();
00264 static void *current();
00265
00266 #if THREADMODEL==WINTHREADS
00267 private:
00268 HANDLE hthr;
00269 DWORD thrid;
00270 #elif THREADMODEL==MACTHREADS
00271 private:
00272 unsigned long thid;
00273 static pascal void *start(void *arg);
00274 #elif THREADMODEL==POSIXTHREADS
00275 private:
00276 pthread_t hthr;
00277 static void *start(void *arg);
00278 #elif THREADMODEL==JRITHREADS
00279 private:
00280 JRIGlobalRef obj;
00281 #elif THREADMODEL==COTHREADS
00282 friend class GMonitor;
00283 public:
00284 class cotask;
00285 class cotask *task;
00305 static int select(int nfds, fd_set*, fd_set*, fd_set*, struct timeval*);
00315 static void get_select(int &nfds, fd_set*, fd_set*, fd_set*, unsigned long &timeout);
00323 static void set_scheduling_callback(void (*call)(int));
00324 enum { CallbackCreate, CallbackTerminate, CallbackUnblock };
00325
00326 #endif
00327 public:
00328
00329 void (*xentry)(void*);
00330 void *xarg;
00331 private:
00332
00333 GThread(const GThread&);
00334 GThread& operator=(const GThread&);
00335 };
00336
00337
00362 class GMonitor
00363 {
00364 public:
00365 GMonitor();
00366 ~GMonitor();
00370 void enter();
00376 void leave();
00382 void wait();
00389 void wait(unsigned long timeout);
00393 void signal();
00397 void broadcast();
00398 private:
00399 #if THREADMODEL==WINTHREADS
00400 int ok;
00401 int count;
00402 DWORD locker;
00403 CRITICAL_SECTION cs;
00404 struct thr_waiting *head;
00405 struct thr_waiting *tail;
00406 #elif THREADMODEL==MACTHREADS
00407 int ok;
00408 int count;
00409 unsigned long locker;
00410 int wlock;
00411 int wsig;
00412 #elif THREADMODEL==POSIXTHREADS
00413 int ok;
00414 int count;
00415 pthread_t locker;
00416 pthread_mutex_t mutex;
00417 pthread_cond_t cond;
00418 #elif THREADMODEL==COTHREADS
00419 int ok;
00420 int count;
00421 void *locker;
00422 int wlock;
00423 int wsig;
00424 #elif THREADMODEL==JRITHREADS
00425 JRIGlobalRef obj;
00426 #endif
00427 private:
00428
00429 GMonitor(const GMonitor&);
00430 GMonitor& operator=(const GMonitor&);
00431 };
00432
00433
00434
00435
00436
00437
00438
00439 #if THREADMODEL==NOTHREADS
00440 inline GThread::GThread(int) {}
00441 inline GThread::~GThread(void) {}
00442 inline void GThread::terminate() {}
00443 inline int GThread::yield() { return 0; }
00444 inline void* GThread::current() { return 0; }
00445 inline GMonitor::GMonitor() {}
00446 inline GMonitor::~GMonitor() {}
00447 inline void GMonitor::enter() {}
00448 inline void GMonitor::leave() {}
00449 inline void GMonitor::wait() {}
00450 inline void GMonitor::wait(unsigned long) {}
00451 inline void GMonitor::signal() {}
00452 inline void GMonitor::broadcast() {}
00453 #endif // NOTHREADS
00454
00455
00456
00457
00458
00459
00478 class GMonitorLock
00479 {
00480 private:
00481 GMonitor *gsec;
00482 public:
00484 GMonitorLock(GMonitor *gsec) : gsec(gsec)
00485 { if (gsec) gsec->enter(); };
00487 ~GMonitorLock()
00488 { if (gsec) gsec->leave(); };
00489 };
00490
00491
00492
00493
00494
00495
00496
00505 class GSafeFlags : public GMonitor
00506 {
00507 private:
00508 volatile long flags;
00509 public:
00511 GSafeFlags(long flags=0);
00512
00515 GSafeFlags & operator=(long flags);
00516
00518 operator long(void) const;
00521 GSafeFlags & operator|=(long mask);
00524 GSafeFlags & operator&=(long mask);
00525
00531 bool test_and_modify(long set_mask, long clr_mask,
00532 long set_mask1, long clr_mask1);
00533
00538 void wait_and_modify(long set_mask, long clr_mask,
00539 long set_mask1, long clr_mask1);
00540
00543 void wait_for_flags(long set_mask, long clr_mask=0) const;
00544
00548 void modify(long set_mask, long clr_mask);
00549 };
00550
00551 inline
00552 GSafeFlags::GSafeFlags(long xflags)
00553 : flags(xflags)
00554 {
00555 }
00556
00557 inline void
00558 GSafeFlags::wait_for_flags(long set_mask, long clr_mask) const
00559 {
00560 ((GSafeFlags *) this)->wait_and_modify(set_mask, clr_mask, 0, 0);
00561 }
00562
00563 inline void
00564 GSafeFlags::modify(long set_mask, long clr_mask)
00565 {
00566 test_and_modify(0, 0, set_mask, clr_mask);
00567 }
00568
00569 inline GSafeFlags &
00570 GSafeFlags::operator|=(long mask)
00571 {
00572 test_and_modify(0, 0, mask, 0);
00573 return *this;
00574 }
00575
00576 inline GSafeFlags &
00577 GSafeFlags::operator&=(long mask)
00578 {
00579 test_and_modify(0, 0, 0, ~mask);
00580 return *this;
00581 }
00582
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 class GCriticalSection : protected GMonitor
00595 {
00596 public:
00597 void lock()
00598 { GMonitor::enter(); };
00599 void unlock()
00600 { GMonitor::leave(); };
00601 };
00602
00603 class GEvent : protected GMonitor
00604 {
00605 private:
00606 int status;
00607 public:
00608 GEvent()
00609 : status(0) { };
00610 void set()
00611 { if (!status) { enter(); status=1; signal(); leave(); } };
00612 void wait()
00613 { enter(); if (!status) GMonitor::wait(); status=0; leave(); };
00614 void wait(int timeout)
00615 { enter(); if (!status) GMonitor::wait(timeout); status=0; leave(); };
00616 };
00617
00618 class GCriticalSectionLock
00619 {
00620 private:
00621 GCriticalSection *gsec;
00622 public:
00623 GCriticalSectionLock(GCriticalSection *gsec) : gsec(gsec)
00624 { if (gsec) gsec->lock(); };
00625 ~GCriticalSectionLock()
00626 { if (gsec) gsec->unlock(); };
00627 };
00628
00629
00630
00631
00632 #ifdef HAVE_NAMESPACES
00633 }
00634 # ifndef NOT_USING_DJVU_NAMESPACE
00635 using namespace DJVU;
00636 # endif
00637 #endif
00638 #endif //_GTHREADS_H_
00639