]> git.lyx.org Git - lyx.git/blob - sigc++/thread.h
fix typo that put too many include paths for most people
[lyx.git] / sigc++ / thread.h
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++/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 */