Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4973 right-hear 1
// -*- c++ -*-
2
/*
3
 * Copyright 1999 Karl Nelson 
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 
22
 
23
#ifdef SIGC_PTHREADS
24
 
25
#ifdef SIGC_THREAD_IMPL
26
#include 
27
#else
28
#include 
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 
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 : 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 */