1 // Generated by gmmproc 2.64.2 -- DO NOT MODIFY!
2
3 // Don't let glibmm.h include thread.h. Pretend that it's already included.
4 // glib.h can then be included with G_DISABLE_DEPRECATED defined, and
5 // the compiler can react if deprecated glib functions are used.
6 #define _GLIBMM_THREAD_H
7
8 #include <glibmmconfig.h>
9 #ifndef GLIBMM_DISABLE_DEPRECATED
10
11
12 #include <glibmm.h>
13
14 #include <glibmm/threads.h>
15 #include <glibmm/private/threads_p.h>
16
17
18 /* Copyright (C) 2002 The gtkmm Development Team
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This library is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
32 */
33
34 #include <glibmm/exceptionhandler.h>
35 #include <glib.h>
36
37 /* Why reinterpret_cast<Thread*>(gobject) is needed:
38 *
39 * A Thread instance is in fact always a GThread instance.
40 * Unfortunately, GThread cannot be a member of Thread,
41 * because it is an opaque struct. Also, the C interface does not provide
42 * any hooks to install a destroy notification handler, thus we cannot
43 * wrap it dynamically either.
44 *
45 * The cast works because Thread does not have any member data, and
46 * it is impossible to derive from it. This is ensured by not implementing
47 * the (private) default constructor.
48 * This trick is used also in classes declared as _CLASS_OPAQUE_REFCOUNTED.
49 */
50
51 namespace
52 {
53
54 extern "C" {
55
56 static void*
call_thread_entry_slot(void * data)57 call_thread_entry_slot(void* data)
58 {
59 const auto slot = reinterpret_cast<sigc::slot_base*>(data);
60
61 try
62 {
63 // Recreate the specific slot.
64 (*static_cast<sigc::slot<void>*>(slot))();
65 }
66 catch (Glib::Threads::Thread::Exit&)
67 {
68 // Just exit from the thread. The Threads::Thread::Exit exception
69 // is our sane C++ replacement of g_thread_exit().
70 }
71 catch (...)
72 {
73 Glib::exception_handlers_invoke();
74 }
75
76 delete slot;
77 return nullptr;
78 }
79
80 } // extern "C"
81
82 } // anonymous namespace
83
84 namespace Glib
85 {
86
87 namespace Threads
88 {
89
90 /**** Glib::Threads::Thread ************************************************/
91
92 // static
93 Thread*
create(const sigc::slot<void> & slot,const std::string & name)94 Thread::create(const sigc::slot<void>& slot, const std::string& name)
95 {
96 // Make a copy of slot on the heap.
97 const auto slot_copy = new sigc::slot<void>(slot);
98
99 GError* error = nullptr;
100 auto thread = g_thread_try_new(
101 name.empty() ? nullptr : name.c_str(), &call_thread_entry_slot, slot_copy, &error);
102
103 if (error)
104 {
105 delete slot_copy;
106 Glib::Error::throw_exception(error);
107 }
108 if (!thread)
109 {
110 delete slot_copy;
111 }
112 return reinterpret_cast<Thread*>(thread);
113 }
114
115 // static
116 Thread*
create(const sigc::slot<void> & slot)117 Thread::create(const sigc::slot<void>& slot)
118 {
119 return create(slot, std::string());
120 }
121
122 // static
123 Thread*
self()124 Thread::self()
125 {
126 return reinterpret_cast<Thread*>(g_thread_self());
127 }
128
129 void
join()130 Thread::join()
131 {
132 g_thread_join(reinterpret_cast<GThread*>(this));
133 }
134
135 // static
136 void
yield()137 Thread::yield()
138 {
139 g_thread_yield();
140 }
141
142 GThread*
gobj()143 Thread::gobj()
144 {
145 return reinterpret_cast<GThread*>(this);
146 }
147
148 const GThread*
gobj() const149 Thread::gobj() const
150 {
151 return reinterpret_cast<const GThread*>(this);
152 }
153
154 Thread*
wrap(GThread * gobject)155 wrap(GThread* gobject)
156 {
157 return reinterpret_cast<Thread*>(gobject);
158 }
159
160 /**** Glib::Threads::Mutex *************************************************/
161
Mutex()162 Mutex::Mutex()
163 {
164 g_mutex_init(&gobject_);
165 }
166
~Mutex()167 Mutex::~Mutex()
168 {
169 g_mutex_clear(&gobject_);
170 }
171
172 void
lock()173 Mutex::lock()
174 {
175 g_mutex_lock(&gobject_);
176 }
177
178 bool
trylock()179 Mutex::trylock()
180 {
181 return g_mutex_trylock(&gobject_);
182 }
183
184 void
unlock()185 Mutex::unlock()
186 {
187 g_mutex_unlock(&gobject_);
188 }
189
190 Mutex*
wrap(GMutex * gobject)191 wrap(GMutex* gobject)
192 {
193 return reinterpret_cast<Mutex*>(gobject);
194 }
195
196 /**** Glib::Threads::RecMutex **********************************************/
197
RecMutex()198 RecMutex::RecMutex()
199 {
200 g_rec_mutex_init(&gobject_);
201 }
202
~RecMutex()203 RecMutex::~RecMutex()
204 {
205 g_rec_mutex_clear(&gobject_);
206 }
207
208 void
lock()209 RecMutex::lock()
210 {
211 g_rec_mutex_lock(&gobject_);
212 }
213
214 bool
trylock()215 RecMutex::trylock()
216 {
217 return g_rec_mutex_trylock(&gobject_);
218 }
219
220 void
unlock()221 RecMutex::unlock()
222 {
223 g_rec_mutex_unlock(&gobject_);
224 }
225
226 RecMutex*
wrap(GRecMutex * gobject)227 wrap(GRecMutex* gobject)
228 {
229 return reinterpret_cast<RecMutex*>(gobject);
230 }
231
232 /**** Glib::Threads::RWLock ************************************************/
233
234 void
reader_lock()235 RWLock::reader_lock()
236 {
237 g_rw_lock_reader_lock(&gobject_);
238 }
239
240 bool
reader_trylock()241 RWLock::reader_trylock()
242 {
243 return g_rw_lock_reader_trylock(&gobject_);
244 }
245
246 void
reader_unlock()247 RWLock::reader_unlock()
248 {
249 g_rw_lock_reader_unlock(&gobject_);
250 }
251
252 void
writer_lock()253 RWLock::writer_lock()
254 {
255 g_rw_lock_writer_lock(&gobject_);
256 }
257
258 bool
writer_trylock()259 RWLock::writer_trylock()
260 {
261 return g_rw_lock_writer_trylock(&gobject_);
262 }
263
264 void
writer_unlock()265 RWLock::writer_unlock()
266 {
267 g_rw_lock_writer_unlock(&gobject_);
268 }
269
RWLock()270 RWLock::RWLock()
271 {
272 g_rw_lock_init(&gobject_);
273 }
274
~RWLock()275 RWLock::~RWLock()
276 {
277 g_rw_lock_clear(&gobject_);
278 }
279
280 /**** Glib::Threads::Cond **************************************************/
281
Cond()282 Cond::Cond()
283 {
284 g_cond_init(&gobject_);
285 }
286
~Cond()287 Cond::~Cond()
288 {
289 g_cond_clear(&gobject_);
290 }
291
292 void
signal()293 Cond::signal()
294 {
295 g_cond_signal(&gobject_);
296 }
297
298 void
broadcast()299 Cond::broadcast()
300 {
301 g_cond_broadcast(&gobject_);
302 }
303
304 void
wait(Mutex & mutex)305 Cond::wait(Mutex& mutex)
306 {
307 g_cond_wait(&gobject_, mutex.gobj());
308 }
309
310 bool
wait_until(Mutex & mutex,gint64 end_time)311 Cond::wait_until(Mutex& mutex, gint64 end_time)
312 {
313 return g_cond_wait_until(&gobject_, mutex.gobj(), end_time);
314 }
315
316 } // namespace Threads
317
318 } // namespace Glib
319
320 namespace
321 {
322 } // anonymous namespace
323
324
ThreadError(Glib::Threads::ThreadError::Code error_code,const Glib::ustring & error_message)325 Glib::Threads::ThreadError::ThreadError(Glib::Threads::ThreadError::Code error_code, const Glib::ustring& error_message)
326 :
327 Glib::Error (G_THREAD_ERROR, error_code, error_message)
328 {}
329
ThreadError(GError * gobject)330 Glib::Threads::ThreadError::ThreadError(GError* gobject)
331 :
332 Glib::Error (gobject)
333 {}
334
code() const335 Glib::Threads::ThreadError::Code Glib::Threads::ThreadError::code() const
336 {
337 return static_cast<Code>(Glib::Error::code());
338 }
339
throw_func(GError * gobject)340 void Glib::Threads::ThreadError::throw_func(GError* gobject)
341 {
342 throw Glib::Threads::ThreadError(gobject);
343 }
344
345 #endif // GLIBMM_DISABLE_DEPRECATED
346
347
348