Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. // -*- c++ -*-
  2. /*
  3.  * Copyright 1999 Karl Nelson <kenelson@ece.ucdavis.edu>
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Library General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Library General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Library General Public
  16.  * License along with this library; if not, write to the Free
  17.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19. #ifndef SIGCXX_THREAD_H
  20. #define SIGCXX_THREAD_H
  21. #include <sigc++config.h>
  22.  
  23. #ifdef SIGC_PTHREADS
  24.  
  25. #ifdef SIGC_THREAD_IMPL
  26. #include <pthread.h>
  27. #else
  28. #include <time.h>
  29. #endif
  30.  
  31. #ifdef SIGC_CXX_NAMESPACES
  32. namespace SigC
  33. {
  34. namespace Threads
  35. {
  36. #else
  37. #define Threads
  38. #endif
  39.  
  40. #ifdef SIGC_THREAD_IMPL
  41. #ifdef SIGC_PTHREAD_DCE
  42. struct CondAttr { pthread_condattr_t impl_;};
  43. struct MutexAttr { pthread_mutexattr_t impl_;};
  44. struct ThreadAttr { pthread_attr_t impl_;};
  45. #else
  46. struct CondAttr { pthread_condattr_t* impl_;};
  47. struct MutexAttr { pthread_mutexattr_t* impl_;};
  48. struct ThreadAttr { pthread_attr_t* impl_;};
  49. #endif
  50. typedef pthread_mutex_t MutexImpl;
  51. typedef pthread_cond_t CondImpl;
  52. typedef pthread_key_t KeyImpl;
  53. typedef pthread_t ThreadImpl;
  54. #else
  55. class CondAttr {unsigned char dummy[SIGC_PTHREAD_COND_ATTR];};
  56. class CondImpl {unsigned char dummy[SIGC_PTHREAD_COND_IMPL];};
  57. class MutexAttr {unsigned char dummy[SIGC_PTHREAD_MUTEX_ATTR];};
  58. class MutexImpl {unsigned char dummy[SIGC_PTHREAD_MUTEX_IMPL];};
  59. class ThreadAttr {unsigned char dummy[SIGC_PTHREAD_THREAD_ATTR];};
  60. class ThreadImpl {unsigned char dummy[SIGC_PTHREAD_THREAD_IMPL];};
  61. class KeyImpl {unsigned char dummy[SIGC_PTHREAD_KEY_IMPL];};
  62. #endif
  63.  
  64. // Mutual Exclusion
  65. class Mutex
  66.   {
  67.    typedef MutexImpl Impl;
  68.    private:
  69.      Impl mutex_;
  70.      int destroy();
  71.  
  72.    public:
  73.      static MutexAttr Default;
  74. #ifdef SIGC_THREAD_IMPL
  75.      operator Impl* ()  {return (Impl*)(&mutex_);}
  76. #endif
  77.  
  78.      Mutex(const MutexAttr attr=Default);
  79.  
  80.      // (needs work)
  81.      ~Mutex();
  82.  
  83.      int lock();
  84.      int trylock();
  85.      int unlock();
  86.   };
  87.  
  88. // A lazy way to unlock at end of scope
  89. struct MLock
  90.   {
  91.    Mutex &mutex_;
  92.    MLock(Mutex& mutex):mutex_(mutex) {mutex_.lock();}
  93.    ~MLock()                          {mutex_.unlock();}
  94.   };
  95.  
  96. // Condition Variable
  97. struct Condition
  98.   {
  99.    typedef CondImpl Impl;
  100.    private:
  101.      Impl cond_;
  102.  
  103.      int destroy();
  104.    public:
  105.      static CondAttr Default;
  106. #ifdef SIGC_THREAD_IMPL
  107.      operator Impl* ()  {return (Impl*)(&cond_);}
  108. #endif
  109.  
  110.      Condition(const CondAttr &attr=Default);
  111.      ~Condition();
  112.  
  113.      // restarts exactly one thread hung on condition
  114.      int signal();
  115.  
  116.      // restarts all threads waiting on condition
  117.      int broadcast();
  118.  
  119.      // unlocks a mutex while waiting on a condition, then reaquires lock.
  120.      int wait(Mutex &m);
  121.  
  122.      // unlocks a mutex while waiting on a condition, then reaquires lock
  123.      // with a fixed maximum duration.
  124.      int wait(Mutex &m,struct timespec* spec);
  125.  
  126.   };
  127.  
  128. // Integer Semaphore
  129. struct Semaphore
  130.   {
  131.    int value_;
  132.    Condition sig_;
  133.    Mutex access_;
  134.  
  135.    void up();
  136.    void down();
  137.    
  138.    Semaphore(int value=1);
  139.    ~Semaphore();
  140.   };
  141.  
  142. struct Private_
  143.   {
  144.     KeyImpl key_;
  145.     void* get();
  146.     void set(void *value);
  147.     void create(void (*dtor)(void*));
  148.     void destroy();
  149.   };
  150.  
  151. // Private is a thread split static.  
  152. template <class T>
  153. class Private : private Private_
  154.   {
  155.     private:
  156.       static void dtor(void* v)
  157.         {
  158.           T* obj=(T*)v;
  159.           delete obj;
  160.         }
  161.  
  162.     public:
  163.  
  164.       T& operator =(const T& t)
  165.         {return (((T&)*this)=t);}
  166.  
  167.       operator T& ()
  168.         {
  169.           T *value=(T*)get();
  170.           if (!value)
  171.             set((void*)(value=new T()));  
  172.           return *(value);
  173.         }
  174.  
  175.       Private()  { create(&dtor); }
  176.       ~Private() { destroy(); }
  177.   };
  178.  
  179. // int needs to initialized
  180. template <>
  181. class Private<int> : private Private_
  182.   {
  183.     private:
  184.       static void dtor(void* v)
  185.         {
  186.           int* obj=(int*)v;
  187.           delete obj;
  188.         }
  189.  
  190.       public:
  191.         int& operator =(const int& t)
  192.           {return (((int&)*this)=t);}
  193.  
  194.         operator int& ()
  195.           {
  196.            int *value=(int*)get();
  197.            if (!value)
  198.              set((void*)(value=new int(0)));  
  199.            return *(value);
  200.           }
  201.  
  202.         Private() { create(&dtor); }
  203.         ~Private() { destroy(); }
  204.   };
  205.  
  206. struct Thread
  207.   {
  208.    protected:
  209.      typedef ThreadImpl Impl;
  210.      Impl thread_;
  211.      void*     arg_;
  212.      ThreadAttr attr_;
  213.  
  214.      static void* call_main_(void* obj);
  215.  
  216.    public:
  217. #ifdef SIGC_THREAD_IMPL
  218.      operator Impl* () {return &thread_;}
  219. #endif
  220.  
  221.      virtual void* main(void*)=0;
  222.      int detach();
  223.  
  224.      static ThreadAttr Default;
  225.  
  226.      // arg is for passing extra data to main, but never pass a
  227.      // local variable or address of local variable.  Arg must
  228.      // be available throughout life of program.
  229.      int start(void* arg=0);
  230.      
  231.      Thread(const ThreadAttr &attr=Default);
  232.      virtual ~Thread();
  233.   };
  234.  
  235.  
  236. #ifdef SIGC_CXX_NAMESPACES
  237. } /* namespace Threads */
  238. } /* namespace SigC */
  239. #endif
  240.  
  241. #endif /* SIGC_PTHREADS */
  242. #endif /* SIGCXX_THREAD_H */
  243.