1 // Copyright (C) 2003  Davis E. King (davis@dlib.net)
2 // License: Boost Software License   See LICENSE.txt for the full license.
3 #undef DLIB_SYNC_EXTENSION_KERNEl_ABSTRACT_
4 #ifdef DLIB_SYNC_EXTENSION_KERNEl_ABSTRACT_
5 
6 #include "../threads/threads_kernel_abstract.h"
7 #include "../threads/rmutex_extension_abstract.h"
8 #include "../threads/rsignaler_extension_abstract.h"
9 #include "../algs.h"
10 
11 namespace dlib
12 {
13 
14     template <
15         typename base
16         >
17     class sync_extension : public base
18     {
19 
20         /*!
21             REQUIREMENTS ON base
22                 base must have a default constructor
23                 base must implement swap(base&)
24 
25 
26             WHAT THIS OBJECT REPRESENTS
27                 This object represents a general extension to any object (given the
28                 restrictions on base).  This object gives any object which it extends
29                 an integrated rmutex and rsignaler object.  The extended object will
30                 then be able to be treated as if it was also a rmutex and rsignaler.
31 
32                 NOTE that just like the threading api, this object does not check
33                 its requires clauses so be careful with it.
34 
35                 Also note that swap() does not swap the rmutex and rsignaler objects.
36                 the rmutex and rsignaler are associated with the object instance itself,
37                 not with whatever the object represents.
38         !*/
39 
40 
41         public:
42 
43         sync_extension (
44         );
45         /*!
46             ensures
47                 - #*this is properly initialized
48             throws
49                 - std::bad_alloc
50                     this is thrown if there is a problem gathering memory
51                 - dlib::thread_error
52                     this is thrown if there is a problem creating threading objects
53                 - any exception thrown by the constructor for the parent class base
54         !*/
55 
56         template <
57             typename T
58             >
59         sync_extension (
60             const T& one
61         );
62         /*!
63             ensures
64                 - #*this is properly initialized
65                 - the argument one will be passed on to the constructor for the parent
66                   class base.
67             throws
68                 - std::bad_alloc
69                     this is thrown if there is a problem gathering memory
70                 - dlib::thread_error
71                     this is thrown if there is a problem creating threading objects
72                 - any exception thrown by the constructor for the parent class base
73         !*/
74 
75         template <
76             typename T,
77             typename U
78             >
79         sync_extension (
80             const T& one,
81             const T& two
82         );
83         /*!
84             ensures
85                 - #*this is properly initialized
86                 - the argument one will be passed on to the constructor for the parent
87                   class base as its first argument.
88                 - the argument two will be passed on to the constructor for the parent
89                   class base as its second argument.
90             throws
91                 - std::bad_alloc
92                     this is thrown if there is a problem gathering memory
93                 - dlib::thread_error
94                     this is thrown if there is a problem creating threading objects
95                 - any exception thrown by the constructor for the parent class base
96         !*/
97 
98 
99         const rmutex& get_mutex (
100         ) const;
101         /*!
102             ensures
103                 - returns the rmutex embedded in this object
104         !*/
105 
106         void lock (
107         ) const;
108         /*!
109             requires
110                 - the thread calling lock() does not already have a lock on *this
111             ensures
112                 - if (*this is currently locked by another thread) then
113                     - the thread that called lock() on *this is put to sleep until
114                       it becomes available
115                 - if (*this is currently unlocked) then
116                     - #*this becomes locked and the current thread is NOT put to sleep
117                       but now "owns" #*this
118         !*/
119 
120         void unlock (
121         ) const;
122         /*!
123             ensures
124                 - #*this is unlocked (i.e. other threads may now lock this object)
125         !*/
126 
127 
128         void wait (
129         ) const;
130         /*!
131             requires
132                 - *this is locked and owned by the calling thread
133             ensures
134                 - atomically unlocks *this and blocks the calling thread
135                 - calling thread will wake if another thread calls signal() or broadcast()
136                   on *this
137                 - when wait returns the calling thread again has a lock on #*this
138         !*/
139 
140 
141         bool wait_or_timeout (
142             unsigned long milliseconds
143         ) const;
144         /*!
145             requires
146                 - *this is locked and owned by the calling thread
147             ensures
148                 - atomically unlocks *this and blocks the calling thread
149                 - calling thread will wake if another thread calls signal() or broadcast()
150                   on *this
151                 - after the specified number of milliseconds has elapsed the calling thread
152                   will wake once *this is free to be locked
153                 - when wait returns the calling thread again has a lock on #*this
154 
155                 - returns false if the call to wait_or_timeout timed out
156                 - returns true if the call did not time out
157         !*/
158 
159         void signal (
160         ) const;
161         /*!
162             ensures
163                 - if (at least one thread is waiting on *this) then
164                     - at least one of the waiting threads will wake
165         !*/
166 
167         void broadcast (
168         ) const;
169         /*!
170             ensures
171                 - any and all threads waiting on *this will wake
172         !*/
173 
174     };
175 
176     template <
177         typename base
178         >
swap(sync_extension<base> & a,sync_extension<base> & b)179     inline void swap (
180         sync_extension<base>& a,
181         sync_extension<base>& b
182     ) { a.swap(b); }
183     /*!
184         provides a global swap function
185     !*/
186 
187 }
188 
189 #endif // DLIB_SYNC_EXTENSION_KERNEl_ABSTRACT_
190 
191