home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / arts / thread.h < prev    next >
Encoding:
C/C++ Source or Header  |  2005-09-10  |  7.9 KB  |  376 lines

  1.     /*
  2.  
  3.     Copyright (C) 2001 Stefan Westerfeld
  4.                        stefan@space.twc.de
  5.  
  6.     This library is free software; you can redistribute it and/or
  7.     modify it under the terms of the GNU Library General Public
  8.     License as published by the Free Software Foundation; either
  9.     version 2 of the License, or (at your option) any later version.
  10.   
  11.     This library is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.     Library General Public License for more details.
  15.    
  16.     You should have received a copy of the GNU Library General Public License
  17.     along with this library; see the file COPYING.LIB.  If not, write to
  18.     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19.     Boston, MA 02111-1307, USA.
  20.  
  21.     */
  22.  
  23. #ifndef ARTS_MCOP_THREAD_H
  24. #define ARTS_MCOP_THREAD_H
  25.  
  26. #include "arts_export.h"
  27.  
  28. /*
  29.  * BC - Status (2002-03-08): SystemThreads, Thread, Mutex, ThreadCondition,
  30.  * Semaphore
  31.  *
  32.  * These classes are kept binary compatible. As the threading implementation
  33.  * can be changed, also
  34.  *
  35.  * Thread_impl, Mutex_impl, ThreadCondition_impl and Semaphore_impl need
  36.  * to remain as they are. The implementation of these depends on what thread
  37.  * system is used, and can attach the required data as necessary to the
  38.  * base classes. So i.e. a posix mutex can contain the pthread_mutex_t in
  39.  * the PosixMutex_impl.
  40.  */
  41.  
  42. namespace Arts {
  43.  
  44. class Mutex_impl;
  45. class Thread_impl;
  46. class ThreadCondition_impl;
  47. class Thread;
  48. class Semaphore_impl;
  49.  
  50. /**
  51.  * Encapsulates the operating system threading facilities
  52.  */
  53. class ARTS_EXPORT SystemThreads {
  54. public:
  55.     static SystemThreads *the();
  56.     static bool init(SystemThreads *the);
  57.  
  58.     /**
  59.      * Check whether there is threading support available
  60.      *
  61.      * If there is no real threading support, the Threading classes try to
  62.      * gracefully degrade the performance. For instance, locking a mutex will
  63.      * do * nothing, and calling the start() function of a Thread will execute
  64.      * it's run function.
  65.      *
  66.      * @returns true if there are real threads 
  67.      */
  68.     static bool supported();
  69.  
  70.     /**
  71.      * Check wether the current thread is the main thread
  72.      *
  73.      * The main thread is the thread that the application's main() was
  74.      * executed in. The IOManager event loop will only run in the main
  75.      * thread.
  76.      */
  77.     virtual bool isMainThread() = 0;
  78.  
  79.     virtual Mutex_impl *createMutex_impl() = 0;
  80.     virtual Mutex_impl *createRecMutex_impl() = 0;
  81.     virtual Thread_impl *createThread_impl(Thread *thread) = 0;
  82.     virtual ThreadCondition_impl *createThreadCondition_impl() = 0;
  83.     virtual Semaphore_impl *createSemaphore_impl(int, int) = 0;
  84.     virtual ~SystemThreads();
  85.  
  86.     /**
  87.      * Returns a pointer to the current thread, or a null pointer if
  88.      * we're the main thread (isMainThread() is true).
  89.      */
  90.     virtual Thread *getCurrentThread() = 0;
  91. };
  92.  
  93. /**
  94.  * Base class for platform specific thread code
  95.  */
  96. class ARTS_EXPORT Thread_impl
  97. {
  98. public:
  99.     virtual void setPriority(int) =0;
  100.     virtual void start() = 0;
  101.     virtual void waitDone() = 0;
  102.     virtual ~Thread_impl();
  103. };
  104.  
  105. /**
  106.  * Base class for platform specific mutex code
  107.  */
  108. class ARTS_EXPORT Mutex_impl {
  109. public:
  110.     virtual void lock() = 0;
  111.     virtual bool tryLock() = 0;
  112.     virtual void unlock() = 0;
  113.     virtual ~Mutex_impl();
  114. };
  115.  
  116. /**
  117.  * Base class for platform specific thread condition code
  118.  */
  119. class ARTS_EXPORT ThreadCondition_impl {
  120. public:
  121.     virtual void wakeOne() = 0;
  122.     virtual void wakeAll() = 0;
  123.     virtual void wait(Mutex_impl *impl) = 0;
  124.     virtual ~ThreadCondition_impl();
  125. };
  126.  
  127. class ARTS_EXPORT Semaphore_impl {
  128. public:
  129.     virtual void wait() = 0;
  130.     virtual int tryWait() = 0;
  131.     virtual void post() = 0;
  132.     virtual int getValue() = 0;
  133.     virtual ~Semaphore_impl();
  134. };
  135.  
  136. /**
  137.  * A thread of execution
  138.  *
  139.  * Example for implementing a thread:
  140.  *
  141.  * <pre>
  142.  * class Counter : public Arts::Thread 
  143.  * {
  144.  * public:
  145.  *   void run() {
  146.  *     for(int i = 0;i < 10;i++)
  147.  *     {
  148.  *       printf("%d\n",i+1);
  149.  *       sleep(1);
  150.  *     }
  151.  *   }
  152.  * };            // start the thread with Counter c; c.start();
  153.  * </pre>
  154.  */
  155. class ARTS_EXPORT Thread {
  156. private:
  157.     Thread_impl *impl;
  158.          
  159. public:
  160.     Thread() : impl(SystemThreads::the()->createThread_impl(this))
  161.     {
  162.     }
  163.     
  164.     virtual ~Thread();
  165.  
  166.     /**
  167.      * set the priority parameters for the thread
  168.      * 
  169.      * FIXME: what should be minimum, maximum, recommended?
  170.      */
  171.     inline void setPriority(int priority) {
  172.         impl->setPriority(priority);
  173.     }
  174.  
  175.     /**
  176.      * starts the run() method in a thread
  177.      */
  178.     inline void start()
  179.     {
  180.         impl->start();
  181.     }
  182.  
  183.     /**
  184.      * waits until the thread is executed completely
  185.      */
  186.     inline void waitDone()
  187.     {
  188.         impl->waitDone();
  189.     }
  190.  
  191.     /**
  192.      * implement this method, if you want to create an own thread - then
  193.      * you can simply call thread.start() to start execution of run() in
  194.      * a seperate thread
  195.      */
  196.     virtual void run() = 0;
  197. };
  198.  
  199. /**
  200.  * A mutex
  201.  *
  202.  * To protect a critical section, you can use a mutex, which will ensure that
  203.  * only one thread at a time can lock it. Here is an example for a thread-safe
  204.  * random number generator:
  205.  *
  206.  * <pre>
  207.  * class RandomGenerator {
  208.  *   Arts::Mutex mutex;
  209.  *   long seed;
  210.  * public:
  211.  *   long get() {
  212.  *     mutex.lock();
  213.  *     // do complicated calculation with seed here
  214.  *     mutex.unlock();
  215.  *     return seed;
  216.  *   }
  217.  * };
  218.  * </pre>
  219.  */
  220. class ARTS_EXPORT Mutex {
  221. private:
  222.     Mutex_impl *impl;
  223.     friend class ThreadCondition;
  224.  
  225. public:
  226.     /**
  227.      * constructor
  228.      *
  229.      * @param recursive whether to create a recursive mutex (may be locked by
  230.      *                  the same thread more than once), or a normal mutex
  231.      */
  232.     inline Mutex(bool recursive = false)
  233.         : impl(recursive?SystemThreads::the()->createRecMutex_impl()
  234.                         :SystemThreads::the()->createMutex_impl())
  235.     {
  236.     }
  237.  
  238.     /**
  239.      * destructor
  240.      */
  241.     virtual ~Mutex();
  242.  
  243.     /**
  244.      * locks the mutex
  245.      */
  246.     inline void lock() {
  247.         impl->lock();
  248.     }
  249.  
  250.     /**
  251.      * tries to lock the mutex, returning immediately in any case (even if
  252.      * mutex is locked by another thread)
  253.      *
  254.      * @returns true if successful (mutex locked), false otherwise
  255.      */
  256.     inline bool tryLock() {
  257.         return impl->tryLock();
  258.     }
  259.  
  260.     /**
  261.      * unlocks the mutex
  262.      */
  263.     inline void unlock() {
  264.         impl->unlock();
  265.     }
  266. };
  267.  
  268. /**
  269.  * A thread condition
  270.  *
  271.  * Thread conditions are used to let a different thread know that a certain
  272.  * condition might have changed. For instance, if you have a thread that
  273.  * waits until a counter exceeds a limit, the thread would look like this:
  274.  *
  275.  * <pre>
  276.  * class WaitCounter : public Arts::Thread 
  277.  * {
  278.  *   int counter;
  279.  *   Arts::Mutex mutex;
  280.  *   Arts::ThreadCondition cond;
  281.  * 
  282.  * public:
  283.  *   WaitCounter() : counter(0) {}
  284.  *
  285.  *   void run() {  // run will terminate once the counter reaches 20
  286.  *     mutex.lock();
  287.  *     while(counter < 20)
  288.  *       cond.wait(mutex);
  289.  *     mutex.unlock();
  290.  *   }
  291.  *
  292.  *   void inc() {  // inc will increment the counter and indicate the change
  293.  *     mutex.lock();
  294.  *     counter++;
  295.  *     cond.wakeOne();
  296.  *     mutex.unlock();
  297.  *   }
  298.  * };
  299.  * </pre>
  300.  */
  301. class ARTS_EXPORT ThreadCondition {
  302. private:
  303.     ThreadCondition_impl *impl;
  304.          
  305. public:
  306.     ThreadCondition()
  307.         : impl(SystemThreads::the()->createThreadCondition_impl())
  308.     {
  309.     }
  310.     
  311.     virtual ~ThreadCondition();
  312.  
  313.     /**
  314.      * wakes one waiting thread
  315.      */
  316.     inline void wakeOne()
  317.     {
  318.         impl->wakeOne();
  319.     }
  320.  
  321.     /**
  322.      * wakes all waiting threads
  323.      */
  324.     inline void wakeAll()
  325.     {
  326.         impl->wakeAll();
  327.     }
  328.  
  329.     /**
  330.      * Waits until the condition changes. You will need to lock the mutex
  331.      * before calling this. Internally it will unlock the mutex (to let
  332.      * others change the condition), and relock it once the wait succeeds.
  333.      */
  334.     inline void wait(Mutex& mutex)
  335.     {
  336.         impl->wait(mutex.impl);
  337.     }
  338. };
  339.  
  340. class ARTS_EXPORT Semaphore {
  341. private:
  342.     Semaphore_impl *impl;
  343.  
  344. public:
  345.     Semaphore(int shared=0, int count=0)
  346.     {
  347.         impl = SystemThreads::the()->createSemaphore_impl(shared, count);
  348.     }
  349.  
  350.     virtual ~Semaphore();
  351.  
  352.     inline void wait()
  353.     {
  354.         impl->wait();
  355.     }
  356.  
  357.     inline int tryWait()
  358.     {
  359.         return impl->tryWait();
  360.     }
  361.  
  362.     inline void post()
  363.     {
  364.         impl->post();
  365.     }
  366.  
  367.     inline int getValue()
  368.     {
  369.         return impl->getValue();
  370.     }
  371. };
  372.  
  373. }
  374.  
  375. #endif /* ARTS_MCOP_THREAD_H */
  376.