RCFProto
 All Classes Functions Typedefs
ThreadLibrary.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_RCF_THREADLIBRARY_HPP
20 #define INCLUDE_RCF_THREADLIBRARY_HPP
21 
22 #include <boost/noncopyable.hpp>
23 #include <boost/shared_ptr.hpp>
24 
25 #include <RCF/Config.hpp>
26 #include <RCF/Export.hpp>
27 
28 #include <RCF/AsioFwd.hpp>
29 #include <boost/cstdint.hpp>
30 #include <boost/noncopyable.hpp>
31 #include <boost/throw_exception.hpp>
32 
33 #ifdef BOOST_WINDOWS
34 #include <windows.h>
35 #endif
36 
37 namespace RCF {
38  namespace detail {
39  typedef boost::noncopyable noncopyable;
40  }
41 }
42 
43 #include <RCF/thread/event.hpp>
44 #include <RCF/thread/mutex.hpp>
45 #include <RCF/thread/thread.hpp>
46 #include <RCF/thread/tss_ptr.hpp>
47 
48 namespace RCF {
49 
50  // Multithreading primitives, based on the ones in asio.
51 
52  typedef RCF::detail::thread Thread;
53  typedef RCF::detail::mutex Mutex;
54  typedef RCF::detail::mutex::scoped_lock Lock;
55  typedef RCF::detail::event Condition;
56 
57 #ifdef BOOST_WINDOWS
58  typedef int ThreadId;
59 #else
60  typedef pthread_t ThreadId;
61 #endif
62 
63  template<typename T>
64  class ThreadSpecificPtr : public RCF::detail::tss_ptr<T>
65  {
66  public:
67  void reset(T * pt = NULL)
68  {
69  RCF::detail::tss_ptr<T>::operator =(pt);
70  }
71 
72  T * get() const
73  {
74  return RCF::detail::tss_ptr<T>::operator T*();
75  }
76 
77  T * operator->() const
78  {
79  return RCF::detail::tss_ptr<T>::operator T*();
80  }
81 
82  typedef ThreadSpecificPtr Val;
83  };
84 
85  // Simple read-write mutex.
86 
87  class ReadWriteMutex;
88 
89  class RCF_EXPORT ReadLock : boost::noncopyable
90  {
91  public:
92  ReadLock(ReadWriteMutex &rwm);
93  ~ReadLock();
94  void lock();
95  void unlock();
96 
97  private:
98  ReadWriteMutex & rwm;
99  bool locked;
100  };
101 
102  class RCF_EXPORT WriteLock : boost::noncopyable
103  {
104  public:
105  WriteLock(ReadWriteMutex &rwm);
106  ~WriteLock();
107  void lock();
108  void unlock();
109 
110  private:
111  ReadWriteMutex & rwm;
112  Lock readLock;
113  Lock writeLock;
114  bool locked;
115  };
116 
117  enum ReadWritePriority
118  {
119  ReaderPriority,
120  WriterPriority
121  };
122 
123  class RCF_EXPORT ReadWriteMutex : boost::noncopyable
124  {
125  public:
126  ReadWriteMutex(ReadWritePriority rwsp);
127 
128  private:
129 
130  void waitOnReadUnlock(Lock &lock);
131  void notifyReadUnlock(Lock &lock);
132 
133  Mutex readMutex;
134  Mutex writeMutex;
135  Condition readUnlockEvent;
136  int readerCount;
137 
138  public:
139 
140  friend class ReadLock;
141  friend class WriteLock;
142 
143  };
144 
145 #ifdef BOOST_WINDOWS
146 
147  // On Windows critical sections are automatically recursive. All
148  // this class does is disable the recursive locking assert in win_mutex.
149  class RCF_EXPORT RecursiveMutex : public RCF::detail::win_mutex
150  {
151  public:
152  RecursiveMutex();
153  ~RecursiveMutex();
154  };
155 
156  typedef Lock RecursiveLock;
157 
158 #else
159 
160  // Some pthreads versions have built in recursive mutexes
161  // (PTHREAD_MUTEX_RECURSIVE). For portability we're using
162  // a custom implemenation instead.
163 
164  class RCF_EXPORT RecursiveMutex : boost::noncopyable
165  {
166  public:
167  RecursiveMutex();
168  ~RecursiveMutex();
169 
170  private:
171 
172  friend class RCF::detail::scoped_lock<RecursiveMutex>;
173 
174  void lock();
175  void unlock();
176 
177  Mutex mMutex;
178  Condition mCondition;
179  bool mIsLocked;
180  ThreadId mOwner;
181  std::size_t mLockCount;
182 
183  };
184 
185  typedef RCF::detail::scoped_lock<RecursiveMutex> RecursiveLock;
186 
187 #endif
188 
189  typedef boost::shared_ptr<RecursiveLock> RecursiveLockPtr;
190  typedef boost::shared_ptr<RecursiveMutex> RecursiveMutexPtr;
191 
192  typedef boost::shared_ptr<Thread> ThreadPtr;
193  typedef boost::shared_ptr<ReadWriteMutex> ReadWriteMutexPtr;
194  typedef boost::shared_ptr<Mutex> MutexPtr;
195  typedef boost::shared_ptr<Lock> LockPtr;
196  typedef boost::shared_ptr<Condition> ConditionPtr;
197 
198 
199  RCF_EXPORT ThreadId getCurrentThreadId();
200 
201  // Time in ms since ca 1970, modulo 65536 s (turns over every ~18.2 hrs).
202  RCF_EXPORT boost::uint32_t getCurrentTimeMs();
203 
204  // Generate a timeout value for the given ending time.
205  // Returns zero if endTime <= current time <= endTime+10%of timer resolution, otherwise returns a nonzero duration in ms.
206  // Timer resolution as above (18.2 hrs).
207  static const unsigned int MaxTimeoutMs = (((unsigned int)-1)/10)*9;
208  RCF_EXPORT boost::uint32_t generateTimeoutMs(unsigned int endTimeMs);
209 
210  RCF_EXPORT Mutex & getRootMutex();
211 
212  RCF_EXPORT void sleepMs(boost::uint32_t msec);
213 }
214 
215 #endif // ! INCLUDE_RCF_THREADLIBRARY_HPP