Line data Source code
1 : // Snap Websites Server -- C++ object to handle threads
2 : // Copyright (c) 2013-2019 Made to Order Software Corp. All Rights Reserved
3 : //
4 : // This program is free software; you can redistribute it and/or modify
5 : // it under the terms of the GNU General Public License as published by
6 : // the Free Software Foundation; either version 2 of the License, or
7 : // (at your option) any later version.
8 : //
9 : // This program is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : // GNU General Public License for more details.
13 : //
14 : // You should have received a copy of the GNU General Public License
15 : // along with this program; if not, write to the Free Software
16 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 :
18 : /** \file
19 : * \brief Implementation of the Thread Runner and Managers.
20 : *
21 : * This file includes the implementation used by the snap_thread environment.
22 : */
23 :
24 :
25 : // self
26 : //
27 : #include "snapwebsites/snap_thread.h"
28 :
29 :
30 : // snapwebsites lib
31 : //
32 : #include "snapwebsites/log.h"
33 :
34 :
35 : // C lib
36 : //
37 : #include <signal.h>
38 : #include <sys/syscall.h>
39 : #include <sys/sysinfo.h>
40 :
41 :
42 : // last include
43 : //
44 : #include <snapdev/poison.h>
45 :
46 :
47 :
48 :
49 : namespace snap
50 : {
51 :
52 :
53 : /** \class snap_thread_exception
54 : * \brief To catch any thread exception, catch this base thread exception.
55 : *
56 : * This is the base thread exception for all the thread exceptions.
57 : * You may catch this exception to catch any of the thread exceptions.
58 : */
59 :
60 : /** \class snap_thread_exception_not_started
61 : * \brief Tried to start a thread and it failed.
62 : *
63 : * When using the thread_safe object which is created on the FIFO, one
64 : * guarantee is that the thread actually starts. If the threads cannot
65 : * be started, this exception is raised.
66 : */
67 :
68 : /** \class snap_thread_exception_in_use_error
69 : * \brief One thread runner can be attached to one thread.
70 : *
71 : * This exception is raised if a thread notices that a runner being
72 : * attached to it is already attached to another thread. This is just
73 : * not possible. One thread runner can only be running in one thread
74 : * not two or three (it has to stop and be removed from another thread
75 : * first otherwise.)
76 : */
77 :
78 : /** \class snap_thread_exception_not_locked_error
79 : * \brief A mutex cannot be unlocked if not locked.
80 : *
81 : * Each time we lock a mutex, we increase a counter. Each time we nulock a
82 : * mutex we decrease a counter. If you try to unlock when the counter is
83 : * zero, you have a lock/unlock discrepancy. This exception is raised
84 : * when such is discovered.
85 : */
86 :
87 : /** \class snap_thread_exception_not_locked_once_error
88 : * \brief When calling wait() the mutex should be locked once.
89 : *
90 : * When calling the wait() instruction, the mutex has to be locked once.
91 : *
92 : * At this time this is commented out as it caused problems. We probably
93 : * need to test that it is at least locked once and not exactly once.
94 : */
95 :
96 : /** \class snap_thread_exception_mutex_failed_error
97 : * \brief A mutex failed.
98 : *
99 : * In most cases, a mutex will fail if the input buffer is not considered
100 : * valid. (i.e. it was not initialized and it does not look like a mutex.)
101 : */
102 :
103 : /** \class snap_thread_exception_invalid_error
104 : * \brief An invalid parameter or value was detected.
105 : *
106 : * This exception is raised when a parameter or a variable member or some
107 : * other value is out of range or generally not valid for its purpose.
108 : */
109 :
110 : /** \class snap_thread_exception_system_error
111 : * \brief We called a system function and it failed.
112 : *
113 : * This exception is raised if a system function call fails.
114 : */
115 :
116 :
117 :
118 :
119 :
120 :
121 : /** \class snap_thread::snap_thread_life
122 : * \brief An RAII class managing the lifetime of a thread.
123 : *
124 : * This class is used to manage the life of a thread: the time it runs.
125 : * The constructor calls the snap_thread::start() function and
126 : * the destructor makes sure to call the snap_thread::stop() function.
127 : *
128 : * If you have a specific block or another class that should run a
129 : * thread for the lifetime of the block or class object, then this
130 : * is well adapted.
131 : *
132 : * \note
133 : * This class is not responsible for deleting the thread at the
134 : * end. It only manages the time while the thread runs.
135 : */
136 :
137 :
138 :
139 :
140 :
141 : /** \class snap_thread::snap_fifo
142 : * \brief Create a thread safe FIFO.
143 : *
144 : * This template defines a thread safe FIFO which is also a mutex.
145 : * You should use this snap_fifo object to lock your thread and
146 : * send messages/data across various threads. The FIFO itself is
147 : * a mutex so you can use it to lock the threads as with a normal
148 : * mutex:
149 : *
150 : * \code
151 : * {
152 : * snap_thread::snap_lock lock(f_messages);
153 : * ...
154 : * }
155 : * \endcode
156 : *
157 : * \note
158 : * It is recommanded that you use a smart pointer to your data as
159 : * the type T. This way you do not have to deal with copies in these
160 : * FIFOs. However, if your data is very small (a few integers, a
161 : * small string or two) then you may also use a type T which will
162 : * be shared by copy. A smart pointer, thou
163 : *
164 : * \tparam T the type of data that the FIFO will handle.
165 : */
166 :
167 : /** \typedef snap_thread::snap_fifo::items_t
168 : * \brief The container type of our items.
169 : *
170 : * All of the FIFO items are pushed and popped from this type of
171 : * container.
172 : */
173 :
174 : /** \typedef snap_thread::snap_fifo::value_type
175 : * \brief The type of value to push and pop from the FIFO.
176 : *
177 : * This typedef returns the type T of the template.
178 : */
179 :
180 : /** \typedef snap_thread::snap_fifo::fifo_type
181 : * \brief The type of the FIFO as a typedef.
182 : *
183 : * This is a declaration of the FIFO type from the template type T.
184 : * It can be useful in meta programming.
185 : */
186 :
187 : /** \typedef snap_thread::snap_fifo::pointer_t;
188 : * \brief A smart pointer to the FIFO.
189 : *
190 : * You may want to create FIFOs on the heap in which case we strongly
191 : * advice that you use this shared pointer type to old those FIFOs.
192 : *
193 : * It is otherwise possible to have the FIFO as a variable member of
194 : * your thread. One thing to consider, though, if that if thread A
195 : * owns a FIFO and shares it with thread B, then you must make sure
196 : * that B is done before destroying A.
197 : */
198 :
199 : /** \fn snap_thread::snap_fifo::push_back(T const & v)
200 : * \brief Push data on this FIFO.
201 : *
202 : * This function appends data on the FIFO queue. The function
203 : * has the side effect to wake up another thread if such is
204 : * currently waiting for data on the same FIFO.
205 : *
206 : * \note
207 : * You can also wake up the other thread by calling the signal()
208 : * function directly. This is especially useful after you marked
209 : * the FIFO as done to make sure that all the worker threads
210 : * wake up and exit cleanly.
211 : *
212 : * \attention
213 : * Remember that if a thread is not currently waiting on the
214 : * signal, calling signal is not likely to do anything except
215 : * for the one next thread that waits on that signal.
216 : *
217 : * \exception snap_thread_exception_invalid_error
218 : * Do not call this function after calling done(), it will raise
219 : * this exception if you do so.
220 : *
221 : * \param[in] v The value to be pushed on the FIFO queue.
222 : *
223 : * \return true if the value was pushed, false otherwise.
224 : *
225 : * \sa done()
226 : */
227 :
228 : /** \fn snap_thread::snap_fifo::pop_front(T & v, int64_t const usecs)
229 : * \brief Retrieve one value from the FIFO.
230 : *
231 : * This function retrieves one value from the thread FIFO.
232 : * If necessary, the function can wait for a value to be
233 : * received. The wait works as defined in the semaphore
234 : * wait() function:
235 : *
236 : * \li -1 -- wait forever (use with caution as this prevents
237 : * the STOP event from working.)
238 : * \li 0 -- do not wait if there is no data, return immediately
239 : * \li +1 and more -- wait that many microseconds
240 : *
241 : * If the function works (returns true,) then \p v is set
242 : * to the value being popped. Otherwise v is not modified
243 : * and the function returns false.
244 : *
245 : * \note
246 : * Because of the way the pthread conditions are implemented
247 : * it is possible that the condition was already raised
248 : * when you call this function. This means the wait, even if
249 : * you used a value of -1 or 1 or more, will not happen.
250 : *
251 : * \note
252 : * If the function returns false, \p v is not set to anything
253 : * so it still has the value it had when calling the function.
254 : *
255 : * \param[out] v The value read.
256 : * \param[in] usecs The number of microseconds to wait.
257 : *
258 : * \return true if a value was popped, false otherwise.
259 : */
260 :
261 : /** \fn snap_thread::snap_fifo::clear()
262 : * \brief Clear the current FIFO.
263 : *
264 : * This function can be used to clear the FIFO. Right after this
265 : * call, the FIFO will be empty. All the objects that were pushed
266 : * in the FIFO will be removed. It is your responsibility to ensure
267 : * they get cleaned up appropriately.
268 : *
269 : * \note
270 : * This function is often used along the done() function to quickly
271 : * terminate threads.
272 : *
273 : * \sa done()
274 : */
275 :
276 : /** \fn snap_thread::snap_fifo::empty() const
277 : * \brief Test whether the FIFO is empty.
278 : *
279 : * This function checks whether the FIFO is empty and if so
280 : * returns true, otherwise it returns false.
281 : *
282 : * The function does not check the semaphore. Instead it
283 : * checks the size of the FIFO itself.
284 : *
285 : * \return true if the FIFO is empty.
286 : */
287 :
288 : /** \fn snap_thread::snap_fifo::size() const
289 : * \brief Return the number of items in the FIFO.
290 : *
291 : * This function returns the number of items currently added to
292 : * the FIFO. This can be used by the caller to avoid flooding
293 : * the FIFO, if at all possible.
294 : *
295 : * The complexity of this function is O(1).
296 : *
297 : * \return the number of items in the FIFO.
298 : */
299 :
300 : /** \fn snap_thread::snap_fifo::byte_size() const
301 : * \brief Return the total size of the FIFO uses in memory.
302 : *
303 : * This function returns the sum of each element size() function.
304 : *
305 : * \note
306 : * This calculation does not include the amount of bytes used by
307 : * the FIFO itself. It only includes the size of the elements,
308 : * which in most cases is what you want anyway.
309 : *
310 : * The complexity of this function is O(n).
311 : *
312 : * \return the byte size of the FIFO.
313 : */
314 :
315 : /** \fn snap_thread::snap_fifo::done(bool clear)
316 : * \brief Mark the FIFO as done.
317 : *
318 : * By default the FIFO is not done. Once you are finished with it
319 : * and will never push any more data to it, call this function.
320 : * This flag is used by worker threads to know whether they should
321 : * wait for more data or just exit.
322 : *
323 : * This is rarely used with regular threads. It is more of a feature
324 : * for worker threads.
325 : *
326 : * \note
327 : * If the FIFO is empty, this function also broadcasts a signal
328 : * to all the worker threads so that way they can exit.
329 : *
330 : * \param[in] clear Whether the function should also call clear()
331 : *
332 : * \sa clear()
333 : */
334 :
335 : /** \fn snap_thread::snap_fifo::is_done() const
336 : * \brief Check whether the FIFO was marked as done.
337 : *
338 : * When a child process calls pop_front() and the function returns
339 : * false, it means the FIFO is empty. On return, the thread may
340 : * then check whether is_done() is true. If so, then the thread
341 : * is expected to exit (no more data will even be added to the
342 : * FIFO so you might as well leave.)
343 : *
344 : * \return true if the thread is expected to exit, false while still
345 : * running.
346 : */
347 :
348 : /** \var snap_thread::snap_fifo::f_queue
349 : * \brief The actual FIFO.
350 : *
351 : * This variable member holds the actual data in this FIFO
352 : * object.
353 : */
354 :
355 : /** \var snap_thread::snap_fifo::f_done
356 : * \brief Whether the FIFO is done.
357 : *
358 : * This flag tells us whether the FIFO is done or not.
359 : */
360 :
361 : /** \var snap_thread::snap_fifo::f_broadcast
362 : * \brief Whether the done() function called broadcast().
363 : *
364 : * This variable is set to true once the done() function called the
365 : * broadcast() function of the mutex. This way we avoid calling it
366 : * more than once even if you call the done() function multiple
367 : * times.
368 : */
369 :
370 :
371 : /** \class snap_thread::snap_mutex
372 : * \brief A mutex object to ensures atomicity.
373 : *
374 : * This class is used by threads when some data accessed by more than
375 : * one thread is about to be accessed. In most cases it is used with the
376 : * snap_lock class so it is safe even in the event an exception is raised.
377 : *
378 : * The snap_mutex also includes a condition variable which can be signaled
379 : * using the signal() function. This wakes threads that are currently
380 : * waiting on the condition with one of the wait() functions.
381 : *
382 : * \note
383 : * We use a recursive mutex so you may lock the mutex any number of times.
384 : * It has to be unlocked that many times, of course.
385 : */
386 :
387 : /** \var snap_thread::snap_mutex::f_mutex
388 : * \brief The pthread mutex.
389 : *
390 : * This variable member holds the pthread mutex. The snap_mutex
391 : * implementation manages this field as required.
392 : */
393 :
394 :
395 : /** \brief An inter-thread mutex to ensure unicity of execution.
396 : *
397 : * The mutex object is used to lock part of the code that needs to be run
398 : * by only one thread at a time. This is also called a critical section
399 : * and a memory barrier.
400 : *
401 : * In most cases one uses the snap_lock object to temporarily lock
402 : * the mutex using the FIFO to help ensure the mutex gets unlocked as
403 : * required in the event an exception occurs.
404 : *
405 : * \code
406 : * {
407 : * snap_thread::snap_lock lock(&my_mutex)
408 : * ... // protected code
409 : * }
410 : * \endcode
411 : *
412 : * The lock can be tried to see whether another thread already has the
413 : * lock and fail if so. See the try_lock() function.
414 : *
415 : * The class also includes a condition in order to send signals and wait
416 : * on signals. There are two ways to send signals and three ways to wait.
417 : * Note that to call any one of the wait funtions you must first have the
418 : * mutex locked, what otherwise happens is undefined.
419 : *
420 : * \code
421 : * {
422 : * // wake one waiting thread
423 : * my_mutex.signal();
424 : *
425 : * // wake all the waiting thread
426 : * my_mutex.broadcast();
427 : *
428 : * // wait on the signal forever
429 : * {
430 : * snap_thread::snap_lock lock(&my_mutex);
431 : * my_mutex.wait();
432 : * }
433 : *
434 : * // wait on the signal for the specified amount of time
435 : * {
436 : * snap_thread::snap_lock lock(&my_mutex);
437 : * my_mutex.timed_wait(1000000UL); // wait up to 1 second
438 : * }
439 : *
440 : * // wait on the signal for until date or later or the signal
441 : * {
442 : * snap_thread::snap_lock lock(&my_mutex);
443 : * my_mutex.dated_wait(date); // wait on signal or until date
444 : * }
445 : * }
446 : * \endcode
447 : *
448 : * If you need a FIFO of messages between your threads, look at the
449 : * snap_fifo template.
450 : *
451 : * \note
452 : * Care must be used to always initialized a mutex before it
453 : * is possibly accessed by more than one thread. This is usually
454 : * the case in the constructor of your objects.
455 : *
456 : * \exception snap_thread_exception_invalid_error
457 : * If any one of the initialization functions fails, this exception is
458 : * raised. The function also logs the error.
459 : */
460 0 : snap_thread::snap_mutex::snap_mutex()
461 : {
462 : // initialize the mutex
463 : pthread_mutexattr_t mattr;
464 0 : int err(pthread_mutexattr_init(&mattr));
465 0 : if(err != 0)
466 : {
467 0 : SNAP_LOG_FATAL("a mutex attribute structure could not be initialized, error #")(err);
468 0 : throw snap_thread_exception_invalid_error("pthread_muteattr_init() failed");
469 : }
470 0 : err = pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
471 0 : if(err != 0)
472 : {
473 0 : SNAP_LOG_FATAL("a mutex attribute structure type could not be setup, error #")(err);
474 0 : pthread_mutexattr_destroy(&mattr);
475 0 : throw snap_thread_exception_invalid_error("pthread_muteattr_settype() failed");
476 : }
477 0 : err = pthread_mutex_init(&f_mutex, &mattr);
478 0 : if(err != 0)
479 : {
480 0 : SNAP_LOG_FATAL("a mutex structure could not be initialized, error #")(err);
481 0 : pthread_mutexattr_destroy(&mattr);
482 0 : throw snap_thread_exception_invalid_error("pthread_mutex_init() failed");
483 : }
484 0 : err = pthread_mutexattr_destroy(&mattr);
485 0 : if(err != 0)
486 : {
487 0 : SNAP_LOG_FATAL("a mutex attribute structure could not be destroyed, error #")(err);
488 0 : pthread_mutex_destroy(&f_mutex);
489 0 : throw snap_thread_exception_invalid_error("pthread_mutexattr_destroy() failed");
490 : }
491 :
492 : // initialize the condition
493 : pthread_condattr_t cattr;
494 0 : err = pthread_condattr_init(&cattr);
495 0 : if(err != 0)
496 : {
497 0 : SNAP_LOG_FATAL("a mutex condition attribute structure could not be initialized, error #")(err);
498 0 : pthread_mutex_destroy(&f_mutex);
499 0 : throw snap_thread_exception_invalid_error("pthread_condattr_init() failed");
500 : }
501 0 : err = pthread_cond_init(&f_condition, &cattr);
502 0 : if(err != 0)
503 : {
504 0 : SNAP_LOG_FATAL("a mutex condition structure could not be initialized, error #")(err);
505 0 : pthread_condattr_destroy(&cattr);
506 0 : pthread_mutex_destroy(&f_mutex);
507 0 : throw snap_thread_exception_invalid_error("pthread_cond_init() failed");
508 : }
509 0 : err = pthread_condattr_destroy(&cattr);
510 0 : if(err != 0)
511 : {
512 0 : SNAP_LOG_FATAL("a mutex condition attribute structure could not be destroyed, error #")(err);
513 0 : pthread_mutex_destroy(&f_mutex);
514 0 : throw snap_thread_exception_invalid_error("pthread_condattr_destroy() failed");
515 : }
516 0 : }
517 :
518 :
519 : /** \brief Clean up a mutex object.
520 : *
521 : * This function ensures that the mutex object is cleaned up, which means
522 : * the mutex and conditions get destroyed.
523 : *
524 : * This destructor verifies that the mutex is not currently locked. A
525 : * locked mutex can't be destroyed. If still locked, then an error is
526 : * sent to the logger and the function calls exit(1).
527 : */
528 0 : snap_thread::snap_mutex::~snap_mutex()
529 : {
530 : // Note that the following reference count test only ensure that
531 : // you don't delete a mutex which is still locked; however, if
532 : // you still have multiple threads running, we can't really know
533 : // if another thread is not just about to use this thread...
534 : //
535 0 : if(f_reference_count != 0UL)
536 : {
537 : // we cannot legally throw in a destructor so we instead generate a fatal error
538 : //
539 0 : SNAP_LOG_FATAL("a mutex is being destroyed when its reference count is ")(f_reference_count)(" instead of zero.");
540 0 : exit(1);
541 : }
542 0 : int err(pthread_cond_destroy(&f_condition));
543 0 : if(err != 0)
544 : {
545 0 : SNAP_LOG_ERROR("a mutex condition destruction generated error #")(err);
546 : }
547 0 : err = pthread_mutex_destroy(&f_mutex);
548 0 : if(err != 0)
549 : {
550 0 : SNAP_LOG_ERROR("a mutex destruction generated error #")(err);
551 : }
552 0 : }
553 :
554 :
555 : /** \brief Lock a mutex
556 : *
557 : * This function locks the mutex. The function waits until the mutex is
558 : * available if it is not currently available. To avoid waiting one may
559 : * want to use the try_lock() function instead.
560 : *
561 : * Although the function cannot fail, the call can lock up a process if
562 : * two or more mutexes are used and another thread is already waiting
563 : * on this process.
564 : *
565 : * \exception snap_thread_exception_invalid_error
566 : * If the lock fails, this exception is raised.
567 : */
568 0 : void snap_thread::snap_mutex::lock()
569 : {
570 0 : int const err(pthread_mutex_lock(&f_mutex));
571 0 : if(err != 0)
572 : {
573 0 : SNAP_LOG_ERROR("a mutex lock generated error #")(err)(" -- ")(strerror(err));
574 0 : throw snap_thread_exception_invalid_error("pthread_mutex_lock() failed");
575 : }
576 :
577 : // note: we do not need an atomic call since we
578 : // already know we are running alone here...
579 0 : ++f_reference_count;
580 0 : }
581 :
582 :
583 : /** \brief Try locking the mutex.
584 : *
585 : * This function tries locking the mutex. If the mutex cannot be locked
586 : * because another process already locked it, then the function returns
587 : * immediately with false.
588 : *
589 : * \exception snap_thread_exception_invalid_error
590 : * If the lock fails, this exception is raised.
591 : *
592 : * \return true if the lock succeeded, false otherwise.
593 : */
594 0 : bool snap_thread::snap_mutex::try_lock()
595 : {
596 0 : int const err(pthread_mutex_trylock(&f_mutex));
597 0 : if(err == 0)
598 : {
599 : // note: we do not need an atomic call since we
600 : // already know we are running alone here...
601 0 : ++f_reference_count;
602 0 : return true;
603 : }
604 :
605 : // failed because another thread has the lock?
606 0 : if(err == EBUSY)
607 : {
608 0 : return false;
609 : }
610 :
611 : // another type of failure
612 0 : SNAP_LOG_ERROR("a mutex try lock generated error #")(err)(" -- ")(strerror(err));
613 0 : throw snap_thread_exception_invalid_error("pthread_mutex_trylock() failed");
614 : }
615 :
616 :
617 : /** \brief Unlock a mutex.
618 : *
619 : * This function unlock the specified mutex. The function must be called
620 : * exactly once per call to the lock() function, or successful call to
621 : * the try_lock() function.
622 : *
623 : * The unlock never waits.
624 : *
625 : * \exception snap_thread_exception_invalid_error
626 : * If the unlock fails, this exception is raised.
627 : *
628 : * \exception snap_thread_exception_not_locked_error
629 : * If the function is called too many times, then the lock count is going
630 : * to be zero and this exception will be raised.
631 : */
632 0 : void snap_thread::snap_mutex::unlock()
633 : {
634 : // We can't unlock if it wasn't locked before!
635 0 : if(f_reference_count <= 0UL)
636 : {
637 0 : SNAP_LOG_FATAL("attempting to unlock a mutex when it is still locked ")(f_reference_count)(" times");
638 0 : throw snap_thread_exception_not_locked_error("unlock was called too many times");
639 : }
640 :
641 : // NOTE: we do not need an atomic call since we
642 : // already know we are running alone here...
643 0 : --f_reference_count;
644 :
645 0 : int const err(pthread_mutex_unlock(&f_mutex));
646 0 : if(err != 0)
647 : {
648 0 : SNAP_LOG_ERROR("a mutex unlock generated error #")(err)(" -- ")(strerror(err));
649 0 : throw snap_thread_exception_invalid_error("pthread_mutex_unlock() failed");
650 : }
651 0 : }
652 :
653 :
654 : /** \brief Wait on a mutex condition.
655 : *
656 : * At times it is useful to wait on a mutex to become available without
657 : * polling the mutex (which uselessly wastes precious processing time.)
658 : * This function can be used to wait on a mutex condition.
659 : *
660 : * This version of the wait() blocks until a signal is received.
661 : *
662 : * \warning
663 : * This function cannot be called if the mutex is not locked or the
664 : * wait will fail in unpredicatable ways.
665 : *
666 : * \exception snap_thread_exception_not_locked_once_error
667 : * This exception is raised if the reference count is not exactly 1.
668 : * In other words, the mutex must be locked by the caller but only
669 : * one time.
670 : *
671 : * \exception snap_thread_exception_mutex_failed_error
672 : * This exception is raised in the event the conditional wait fails.
673 : */
674 0 : void snap_thread::snap_mutex::wait()
675 : {
676 : // For any mutex wait to work, we MUST have the
677 : // mutex locked already and just one time.
678 : //
679 : // note: the 1 time is just for assurance that it will
680 : // work in most cases; it should work even when locked
681 : // multiple times, but it is less likely. For sure, it
682 : // has to be at least once.
683 : //if(f_reference_count != 1UL)
684 : //{
685 : // SNAP_LOG_FATAL("attempting to wait on a mutex when it is not locked exactly once, current count is ")(f_reference_count);
686 : // throw snap_thread_exception_not_locked_once_error();
687 : //}
688 0 : int const err(pthread_cond_wait(&f_condition, &f_mutex));
689 0 : if(err != 0)
690 : {
691 : // an error occurred!
692 0 : SNAP_LOG_ERROR("a mutex conditional wait generated error #")(err)(" -- ")(strerror(err));
693 0 : throw snap_thread_exception_mutex_failed_error("pthread_cond_wait() failed");
694 : }
695 0 : }
696 :
697 :
698 : /** \brief Wait on a mutex condition with a time limit.
699 : *
700 : * At times it is useful to wait on a mutex to become available without
701 : * polling the mutex, but only for some time. This function waits for
702 : * the number of specified micro seconds. The function returns early if
703 : * the condition was triggered. Otherwise it waits until the specified
704 : * number of micro seconds elapsed and then returns.
705 : *
706 : * \warning
707 : * This function cannot be called if the mutex is not locked or the
708 : * wait will fail in unpredicatable ways.
709 : *
710 : * \exception snap_thread_exception_system_error
711 : * This exception is raised if a function returns an unexpected error.
712 : *
713 : * \exception snap_thread_exception_mutex_failed_error
714 : * This exception is raised when the mutex wait function fails.
715 : *
716 : * \param[in] usecs The maximum number of micro seconds to wait until you
717 : * receive the signal.
718 : *
719 : * \return true if the condition was raised, false if the wait timed out.
720 : */
721 0 : bool snap_thread::snap_mutex::timed_wait(uint64_t const usecs)
722 : {
723 : // For any mutex wait to work, we MUST have the
724 : // mutex locked already and just one time.
725 : //
726 : // note: the 1 time is just for assurance that it will
727 : // work in most cases; it should work even when locked
728 : // multiple times, but it is less likely. For sure, it
729 : // has to be at least once.
730 : //if(f_reference_count != 1UL)
731 : //{
732 : // SNAP_LOG_FATAL("attempting to timed wait ")(usec)(" usec on a mutex when it is not locked exactly once, current count is ")(f_reference_count);
733 : // throw snap_thread_exception_not_locked_once_error();
734 : //}
735 :
736 0 : int err(0);
737 :
738 : // get time now
739 : struct timeval vtime;
740 0 : if(gettimeofday(&vtime, nullptr) != 0)
741 : {
742 0 : err = errno;
743 0 : SNAP_LOG_FATAL("gettimeofday() failed with errno: ")(err)(" -- ")(strerror(err));
744 0 : throw snap_thread_exception_system_error("gettimeofday() failed");
745 : }
746 :
747 : // now + user specified usec
748 : struct timespec timeout;
749 0 : timeout.tv_sec = vtime.tv_sec + usecs / 1000000ULL;
750 0 : uint64_t micros(vtime.tv_usec + usecs % 1000000ULL);
751 0 : if(micros > 1000000ULL)
752 : {
753 0 : timeout.tv_sec++;
754 0 : micros -= 1000000ULL;
755 : }
756 0 : timeout.tv_nsec = static_cast<long>(micros * 1000ULL);
757 :
758 0 : err = pthread_cond_timedwait(&f_condition, &f_mutex, &timeout);
759 0 : if(err != 0)
760 : {
761 0 : if(err == ETIMEDOUT)
762 : {
763 0 : return false;
764 : }
765 :
766 : // an error occurred!
767 0 : SNAP_LOG_ERROR("a mutex conditional timed wait generated error #")(err)(" -- ")(strerror(err));
768 0 : throw snap_thread_exception_mutex_failed_error("pthread_cond_timedwait() failed");
769 : }
770 :
771 0 : return true;
772 : }
773 :
774 :
775 : /** \brief Wait on a mutex until the specified date.
776 : *
777 : * This function waits on the mutex condition to be signaled up until the
778 : * specified date is passed.
779 : *
780 : * \warning
781 : * This function cannot be called if the mutex is not locked or the
782 : * wait will fail in unpredicatable ways.
783 : *
784 : * \exception snap_thread_exception_mutex_failed_error
785 : * This exception is raised whenever the thread wait functionf fails.
786 : *
787 : * \param[in] usec The date when the mutex times out in microseconds.
788 : *
789 : * \return true if the condition occurs before the function times out,
790 : * false if the function times out.
791 : */
792 0 : bool snap_thread::snap_mutex::dated_wait(uint64_t usec)
793 : {
794 : // For any mutex wait to work, we MUST have the
795 : // mutex locked already and just one time.
796 : //
797 : // note: the 1 time is just for assurance that it will
798 : // work in most cases; it should work even when locked
799 : // multiple times, but it is less likely. For sure, it
800 : // has to be at least once.
801 : //if(f_reference_count != 1UL)
802 : //{
803 : // SNAP_LOG_FATAL("attempting to dated wait until ")(msec)(" msec on a mutex when it is not locked exactly once, current count is ")(f_reference_count);
804 : // throw snap_thread_exception_not_locked_once_error();
805 : //}
806 :
807 : // setup the timeout date
808 : struct timespec timeout;
809 0 : timeout.tv_sec = static_cast<long>(usec / 1000000ULL);
810 0 : timeout.tv_nsec = static_cast<long>((usec % 1000000ULL) * 1000ULL);
811 :
812 0 : int const err(pthread_cond_timedwait(&f_condition, &f_mutex, &timeout));
813 0 : if(err != 0)
814 : {
815 0 : if(err == ETIMEDOUT)
816 : {
817 0 : return false;
818 : }
819 :
820 : // an error occurred!
821 0 : SNAP_LOG_ERROR("a mutex conditional dated wait generated error #")(err)(" -- ")(strerror(err));
822 0 : throw snap_thread_exception_mutex_failed_error("pthread_cond_timedwait() failed");
823 : }
824 :
825 0 : return true;
826 : }
827 :
828 :
829 : /** \brief Signal a mutex.
830 : *
831 : * Our mutexes include a condition that get signaled by calling this
832 : * function. This function wakes up one listening thread.
833 : *
834 : * The function ensures that the mutex is locked before broadcasting
835 : * the signal so you do not have to lock the mutex yourself.
836 : *
837 : * \exception snap_thread_exception_invalid_error
838 : * If one of the pthread system functions return an error, the function
839 : * raises this exception.
840 : */
841 0 : void snap_thread::snap_mutex::signal()
842 : {
843 0 : snap_lock lock_mutex(*this);
844 :
845 0 : int const err(pthread_cond_signal(&f_condition));
846 0 : if(err != 0)
847 : {
848 0 : SNAP_LOG_ERROR("a mutex condition signal generated error #")(err);
849 0 : throw snap_thread_exception_invalid_error("pthread_cond_signal() failed");
850 : }
851 0 : }
852 :
853 :
854 : /** \brief Broadcast a mutex signal.
855 : *
856 : * Our mutexes include a condition that get signaled by calling this
857 : * function. This function actually signals all the threads that are
858 : * currently listening to the mutex signal. The order in which the
859 : * threads get awaken is unspecified.
860 : *
861 : * The function ensures that the mutex is locked before broadcasting
862 : * the signal so you do not have to lock the mutex yourself.
863 : *
864 : * \exception snap_thread_exception_invalid_error
865 : * If one of the pthread system functions return an error, the function
866 : * raises this exception.
867 : */
868 0 : void snap_thread::snap_mutex::broadcast()
869 : {
870 0 : snap_lock lock_mutex(*this);
871 :
872 0 : int const err(pthread_cond_broadcast(&f_condition));
873 0 : if(err != 0)
874 : {
875 0 : SNAP_LOG_ERROR("a mutex signal broadcast generated error #")(err);
876 0 : throw snap_thread_exception_invalid_error("pthread_cond_broadcast() failed");
877 : }
878 0 : }
879 :
880 :
881 :
882 :
883 :
884 : /** \class snap_thread::snap_lock
885 : * \brief Lock a mutex in an RAII manner.
886 : *
887 : * This class is used to lock mutexes in a safe manner in regard to
888 : * exceptions. It is extremely important to lock all mutexes before
889 : * a thread quits otherwise the application will lock up.
890 : *
891 : * \code
892 : * {
893 : * snap_lock lock(my_mutex);
894 : * ... // atomic work
895 : * }
896 : * \endcode
897 : */
898 :
899 :
900 : /** \var snap_thread::snap_lock::f_mutex
901 : * \brief The mutex used by the lock class.
902 : *
903 : * Whenever you want to lock a part of your code so only one thread
904 : * runs it at any given time, you want to use a lock. This lock
905 : * makes use of a mutex that you pass to it on construction.
906 : *
907 : * The snap_lock object keeps a reference to your mutex and uses
908 : * it to lock on construction and unlock on destruction. This
909 : * generates a perfect safe guard around your code. Safe guard
910 : * which is exception safe since it will still get unlocked when
911 : * an exception occurs.
912 : *
913 : * \warning
914 : * Note that it is not safe if you get a Unix signal. The lock
915 : * will very likely still be in place if such a signal happens
916 : * while within the lock.
917 : */
918 :
919 :
920 :
921 :
922 :
923 : /** \brief Lock a mutex.
924 : *
925 : * This function locks the specified mutex and keep track of the lock
926 : * until the destructor is called.
927 : *
928 : * The mutex parameter cannot be a reference to a nullptr pointer.
929 : *
930 : * \param[in] mutex The Snap! mutex to lock.
931 : */
932 0 : snap_thread::snap_lock::snap_lock(snap_mutex & mutex)
933 0 : : f_mutex(&mutex)
934 : {
935 0 : if(!f_mutex)
936 : {
937 : // mutex is mandatory
938 : //
939 0 : throw snap_thread_exception_invalid_error("mutex missing in snap_lock() constructor");
940 : }
941 0 : f_mutex->lock();
942 0 : }
943 :
944 :
945 : /** \brief Ensure that the mutex was unlocked.
946 : *
947 : * The destructor ensures that the mutex gets unlocked. Note that it is
948 : * written to avoid exceptions, however, if an exception occurs it ends
949 : * up calling exit(1).
950 : *
951 : * \note
952 : * If a function throws it logs information using the Snap! logger.
953 : */
954 0 : snap_thread::snap_lock::~snap_lock()
955 : {
956 : try
957 : {
958 0 : unlock();
959 : }
960 0 : catch(std::exception const & e)
961 : {
962 : // a log was already printed, we do not absolutely need another one
963 0 : exit(1);
964 : }
965 0 : }
966 :
967 :
968 : /** \brief Unlock this mutex.
969 : *
970 : * This function can be called any number of times. The first time it is
971 : * called, the mutex gets unlocked. Further calls (in most cases one more
972 : * when the destructor is called) have no effects.
973 : *
974 : * This function may throw an exception if the mutex unlock call
975 : * fails.
976 : */
977 0 : void snap_thread::snap_lock::unlock()
978 : {
979 0 : if(f_mutex != nullptr)
980 : {
981 0 : f_mutex->unlock();
982 0 : f_mutex = nullptr;
983 : }
984 0 : }
985 :
986 :
987 :
988 :
989 : /** \class snap_thread::snap_runner
990 : * \brief The runner is the class that wraps the actual system thread.
991 : *
992 : * This class defines the actuall thread wrapper. This is very important
993 : * because when the main snap_thread object gets destroyed and if it
994 : * were a system thread, the virtual tables would be destroyed and thus
995 : * invalid before you reached the ~snap_thread() destructor. This means
996 : * any of the virtual functions could not get called.
997 : *
998 : * For this reason we have a two level thread objects implementation:
999 : * the snap_thread which acts as a controller and the snap_runner which
1000 : * is the object that is the actual system thread and thus which has the
1001 : * run() virtual function: the function that gets called when the thread
1002 : * starts running.
1003 : */
1004 :
1005 :
1006 : /** \typedef snap_thread::snap_runner::pointer_t
1007 : * \brief The shared pointer of a thread runner.
1008 : *
1009 : * This type is used to hold a smart pointer to a thread runner.
1010 : *
1011 : * Be very careful. Using a smart pointer does NOT mean that you can just
1012 : * delete a snap_runner without first stopping the thread. Make sure to
1013 : * have a snap_thread object to manage your snap_running pointers (i.e you
1014 : * can delete a snap_thread, which will stop your snap_runner and then
1015 : * delete the snap_runner.)
1016 : */
1017 :
1018 :
1019 : /** \typedef snap_thread::snap_runner::vector_t
1020 : * \brief A vector of threads.
1021 : *
1022 : * This type defines a vector of thread runners as used by the
1023 : * snap_thread::snap_thread_pool template.
1024 : *
1025 : * Be careful as vectors are usually copyable and this one is because it
1026 : * holds smart pointers to thread runners, not the actual thread. You
1027 : * still only have one thread, just multiple instances of its pointer.
1028 : * However, keep in mind that you can't just destroy a runner. The
1029 : * thread it is runner must be stopped first. Please make sure to
1030 : * have a snap_thread or a snap_thread::snap_thread_pool to manage
1031 : * your thread runners.
1032 : */
1033 :
1034 :
1035 : /** \var snap_thread::snap_runner::f_mutex
1036 : * \brief The mutex of this thread.
1037 : *
1038 : * Each thread is given its own mutex so it can handle its data safely.
1039 : *
1040 : * This mutex is expected to mainly be used by the thread and its parent.
1041 : *
1042 : * If you want to share data and mutexes between multiple threads,
1043 : * you may want to consider using another mutex. For example, the
1044 : * snap_thread::snap_fifo is itself derived from the snap_mutex
1045 : * class. So when you use a FIFO between multiple threads, the
1046 : * lock/unlock mechanism is not using the mutex of your thread.
1047 : */
1048 :
1049 :
1050 : /** \var snap_thread::snap_runner::f_thread
1051 : * \brief A pointer back to the owner ("parent") of this runner
1052 : *
1053 : * When a snap_runner is created, it gets created by a specific \em parent
1054 : * object. This pointer holds that parent.
1055 : *
1056 : * The runner uses this pointer to know whether it is still running
1057 : * and to retrieve its identifier that the parent holds.
1058 : */
1059 :
1060 :
1061 : /** \var snap_thread::snap_runner::f_name
1062 : * \brief The name of this thread.
1063 : *
1064 : * Each thread is given a name. This can help greatly when debugging a
1065 : * threaded environment with a large number of threads. That way you
1066 : * can easily identify which thread did what and work you way to a
1067 : * perfect software.
1068 : *
1069 : * On some systems it may be possible to give this name to the OS
1070 : * which then can be displayed in tools listing processes and threads.
1071 : */
1072 :
1073 :
1074 : /** \brief Initializes the runner.
1075 : *
1076 : * The constructor expects a name. The name is mainly used in case a
1077 : * problem occur and we want to log a message. That way you will know
1078 : * which thread runner caused a problem.
1079 : *
1080 : * \param[in] name The name of this thread runner.
1081 : */
1082 0 : snap_thread::snap_runner::snap_runner(std::string const & name)
1083 0 : : f_name(name)
1084 : {
1085 0 : }
1086 :
1087 :
1088 : /** \brief The destructor checks that the thread was stopped.
1089 : *
1090 : * This function verifies that the thread was stopped before the
1091 : * object gets destroyed (and is likely to break something along
1092 : * the way.)
1093 : */
1094 0 : snap_thread::snap_runner::~snap_runner()
1095 : {
1096 : // the thread should never be set when the runner gets deleted
1097 0 : if(f_thread)
1098 : {
1099 : // this is a bug; it could be that the object that derived from
1100 : // the snap_runner calls gets destroyed under the thread controller's
1101 : // nose and that could break a lot of things.
1102 0 : SNAP_LOG_FATAL("The Snap! thread runner named \"")(f_name)("\" is still marked as running when its object is being destroyed.");
1103 0 : exit(1);
1104 : }
1105 0 : }
1106 :
1107 :
1108 : /** \brief Retrieve the name of the runner.
1109 : *
1110 : * This function returns the name of the runner as specified in the
1111 : * constructor.
1112 : *
1113 : * Since the name is read-only, it will always match one to one what
1114 : * you passed on.
1115 : *
1116 : * \return The name of this thread runner.
1117 : */
1118 0 : std::string const & snap_thread::snap_runner::get_name() const
1119 : {
1120 0 : return f_name;
1121 : }
1122 :
1123 :
1124 : /** \brief Check whether this thread runner is ready.
1125 : *
1126 : * By default a thread runner is considered ready. If you reimplement this
1127 : * function it is possible to tell the thread controller that you are not
1128 : * ready. This means the start() function will fail and return false.
1129 : *
1130 : * \return true by default, can return false to prevent a start() command.
1131 : */
1132 0 : bool snap_thread::snap_runner::is_ready() const
1133 : {
1134 0 : return true;
1135 : }
1136 :
1137 :
1138 : /** \brief Whether the thread should continue running.
1139 : *
1140 : * This function checks whether the user who handles the controller asked
1141 : * the thread to quit. If so, then the function returns false. If not
1142 : * the function returns true.
1143 : *
1144 : * The function can be reimplemented in your runner. In that case, the
1145 : * runner implementation should probably call this function too in order
1146 : * to make sure that the stop() function works.
1147 : *
1148 : * It is expected that your run() function implements a loop that checks
1149 : * this flag on each iteration with iterations that take as little time
1150 : * as possible.
1151 : *
1152 : * \code
1153 : * void my_runner::run()
1154 : * {
1155 : * while(continue_running())
1156 : * {
1157 : * // do some work
1158 : * ...
1159 : * }
1160 : * }
1161 : * \endcode
1162 : *
1163 : * \return true if the thread is expected to continue running.
1164 : */
1165 0 : bool snap_thread::snap_runner::continue_running() const
1166 : {
1167 0 : snap_lock lock(f_mutex);
1168 0 : if(f_thread == nullptr)
1169 : {
1170 0 : return true;
1171 : }
1172 0 : return !f_thread->is_stopping();
1173 : }
1174 :
1175 :
1176 : /** \fn snap_thread::snap_runner::run();
1177 : * \brief This virtual function represents the code run by the thread.
1178 : *
1179 : * The run() function is the one you have to implement in order to have
1180 : * something to execute when the thread is started.
1181 : *
1182 : * To exit the thread, simply return from the run() function.
1183 : */
1184 :
1185 :
1186 : /** \brief Retrieve the thread controller linked to this runner.
1187 : *
1188 : * Each runner is assigned a thread controller whenever the snap_thread
1189 : * is created (they get attached, in effect.) Once the snap_thread is
1190 : * destroyed, the pointer goes back to nullptr.
1191 : *
1192 : * \return A snap_thread pointer or nullptr.
1193 : */
1194 0 : snap_thread * snap_thread::snap_runner::get_thread() const
1195 : {
1196 0 : return f_thread;
1197 : }
1198 :
1199 :
1200 : /** \brief Get this runner thread identifier.
1201 : *
1202 : * This function returns the thread identifier of the thread running
1203 : * this runner run() function.
1204 : *
1205 : * This function can be called from any thread and the correct value
1206 : * will be returned.
1207 : *
1208 : * \return The thread identifier.
1209 : */
1210 0 : pid_t snap_thread::snap_runner::gettid() const
1211 : {
1212 0 : return f_thread->get_thread_tid();
1213 : }
1214 :
1215 :
1216 :
1217 :
1218 :
1219 :
1220 :
1221 :
1222 :
1223 :
1224 :
1225 : /** \class snap_thread
1226 : * \brief A thread object that ensures proper usage of system threads.
1227 : *
1228 : * This class is used to handle threads. It should NEVER be used, however,
1229 : * there are some very specific cases where a thread is necessary to make
1230 : * sure that main process doesn't get stuck. For example, the process
1231 : * environment using pipes requires threads to read and write pipes
1232 : * because otherwise the processes could lock up.
1233 : */
1234 :
1235 :
1236 : /** \typedef snap_thread::pointer_t
1237 : * \brief The shared pointer for a thread object.
1238 : *
1239 : * This type is used to hold a smart pointer to a thread.
1240 : *
1241 : * This smart pointer is safe. It can be used to hold a thread object and
1242 : * when it goes out of scope, it properly ends the corresponding thread
1243 : * runner (the snap_thread::snap_runner) and returns.
1244 : *
1245 : * Be cautious because the smart pointer of a snap_runner is not actually
1246 : * safe to delete without first stopping the thread. Make sure to manage
1247 : * all your threads in with two objects, making sure that the thread goes
1248 : * out of scope first so it can stop your thread before your thread object
1249 : * gets destroyed.
1250 : */
1251 :
1252 :
1253 : /** \typedef snap_thread::vector_t
1254 : * \brief A vector of threads.
1255 : *
1256 : * This type defines a vector of threads. Since each entry in the vector
1257 : * is a smart pointer, it is safe to use this type.
1258 : */
1259 :
1260 :
1261 : /** \brief Initialize the thread object.
1262 : *
1263 : * This function saves the name of the thread. The name is generally a
1264 : * static string and it is used to distinguish between threads when
1265 : * managing several at once. The function makes a copy of the name.
1266 : *
1267 : * The runner pointer is an object which has a run() function that will
1268 : * be called from another thread. That object becomes the "child" of
1269 : * this snap_thread controller. However, if it is already assigned a
1270 : * thread controller, then the initialization of the snap_thread fails.
1271 : * You may test whether a runner is already assigned a thread controller
1272 : * by calling its get_thread() function and see that it is not nullptr.
1273 : *
1274 : * The pointer to the runner object cannot be nullptr.
1275 : *
1276 : * \param[in] name The name of the process.
1277 : * \param[in] runner The runner (the actual thread) to handle.
1278 : */
1279 0 : snap_thread::snap_thread(std::string const & name, snap_runner * runner)
1280 : : f_name(name)
1281 0 : , f_runner(runner)
1282 : {
1283 0 : if(f_runner == nullptr)
1284 : {
1285 0 : throw snap_thread_exception_invalid_error("runner missing in snap_thread() constructor");
1286 : }
1287 0 : if(f_runner->f_thread != nullptr)
1288 : {
1289 0 : throw snap_thread_exception_in_use_error("this runner (" + name + ") is already is use");
1290 : }
1291 :
1292 0 : int err(pthread_attr_init(&f_thread_attr));
1293 0 : if(err != 0)
1294 : {
1295 0 : SNAP_LOG_ERROR("the thread attributes could not be initialized, error #")(err);
1296 0 : throw snap_thread_exception_invalid_error("pthread_attr_init() failed");
1297 : }
1298 0 : err = pthread_attr_setdetachstate(&f_thread_attr, PTHREAD_CREATE_JOINABLE);
1299 0 : if(err != 0)
1300 : {
1301 0 : SNAP_LOG_ERROR("the thread detach state could not be initialized, error #")(err);
1302 0 : pthread_attr_destroy(&f_thread_attr);
1303 0 : throw snap_thread_exception_invalid_error("pthread_attr_setdetachstate() failed");
1304 : }
1305 :
1306 0 : f_runner->f_thread = this;
1307 0 : }
1308 :
1309 :
1310 : /** \brief Delete a thread object.
1311 : *
1312 : * The destructor of a Snap! C++ thread object ensures that the thread stops
1313 : * running before actually deleting the runner object.
1314 : *
1315 : * Then it destroyes the thread attributes and returns.
1316 : *
1317 : * The destructor also removes the thread from the runner so the runner
1318 : * can create another thread controller and run again.
1319 : */
1320 0 : snap_thread::~snap_thread()
1321 : {
1322 : try
1323 : {
1324 0 : stop();
1325 : }
1326 0 : catch(snap_thread_exception_mutex_failed_error const &)
1327 : {
1328 : }
1329 0 : catch(snap_thread_exception_invalid_error const &)
1330 : {
1331 : }
1332 0 : f_runner->f_thread = nullptr;
1333 :
1334 0 : int const err(pthread_attr_destroy(&f_thread_attr));
1335 0 : if(err != 0)
1336 : {
1337 0 : SNAP_LOG_ERROR("the thread attributes could not be destroyed, error #")(err);
1338 : }
1339 0 : }
1340 :
1341 :
1342 : /** \brief Retrieve the name of this process object.
1343 : *
1344 : * This process object is given a name on creation. In most cases this is
1345 : * a static name that is used to determine which process is which.
1346 : *
1347 : * \return The name of the process.
1348 : */
1349 0 : std::string const & snap_thread::get_name() const
1350 : {
1351 0 : return f_name;
1352 : }
1353 :
1354 :
1355 : /** \brief Get a pointer to this thread runner.
1356 : *
1357 : * This function returns the pointer to the thread runner. There are cases
1358 : * where it is quite handy to be able to use this function rather than
1359 : * having to hold on the information in your own way.
1360 : *
1361 : * You will probably have to dynamic_cast<>() the result to your own
1362 : * object type.
1363 : *
1364 : * \note
1365 : * The snap_thread constructor ensures that this pointer is never nullptr.
1366 : * Therefore this function never returns a null pointer. However, the
1367 : * dynamic_cast<>() function may return a nullptr.
1368 : *
1369 : * \return The snap_runner object attached to this snap_thread.
1370 : */
1371 0 : snap_thread::snap_runner * snap_thread::get_runner() const
1372 : {
1373 0 : return f_runner;
1374 : }
1375 :
1376 :
1377 : /** \brief Check whether the thread is considered to be running.
1378 : *
1379 : * This flag is used to know whether the thread is running.
1380 : *
1381 : * \todo
1382 : * We need to save the pid of the process that creates threads.
1383 : * This tells us whether the thread is running in this process.
1384 : * i.e. if a fork() happens, then the child process does not
1385 : * have any threads so is_running() has to return false. Also,
1386 : * any other function that checks whether a thread is running
1387 : * needs to also check the pid. We have to save the pid at
1388 : * the time we start the thread and then when we check whether
1389 : * the thread is running.
1390 : *
1391 : * \return true if the thread is still considered to be running.
1392 : */
1393 0 : bool snap_thread::is_running() const
1394 : {
1395 0 : snap_lock lock(f_mutex);
1396 0 : return f_running;
1397 : }
1398 :
1399 :
1400 : /** \brief Check whether the thread was asked to stop.
1401 : *
1402 : * The thread is using three status flags. One of them is f_stopping which
1403 : * is set to false (which is also the default status) when start() is called
1404 : * and to true when stop() is called. This function is used to read that
1405 : * flag status from the continue_running() function.
1406 : *
1407 : * \return true if the stop() function was called, false otherwise.
1408 : */
1409 0 : bool snap_thread::is_stopping() const
1410 : {
1411 0 : snap_lock lock(f_mutex);
1412 0 : return f_stopping;
1413 : }
1414 :
1415 :
1416 : /** \brief Start the actual thread.
1417 : *
1418 : * This function is called when starting the thread. This is a static
1419 : * function since pthread can only accept such a function pointer.
1420 : *
1421 : * The function then calls the internal_run().
1422 : *
1423 : * \note
1424 : * The function parameter is a void * instead of snap_thread because that
1425 : * way the function signature matches the signature the pthread_create()
1426 : * function expects.
1427 : *
1428 : * \param[in] thread The thread pointer.
1429 : *
1430 : * \return We return a null pointer, which we do not use because we do
1431 : * not call the pthread_join() function.
1432 : */
1433 0 : void * func_internal_start(void * thread)
1434 : {
1435 0 : snap_thread * t(reinterpret_cast<snap_thread *>(thread));
1436 0 : t->internal_run();
1437 0 : return nullptr; // == pthread_exit(nullptr);
1438 : }
1439 :
1440 :
1441 : /** \brief Run the thread process.
1442 : *
1443 : * This function is called by the func_internal_start() so we run from
1444 : * within the snap_thread class. (i.e. the func_internal_start() function
1445 : * itself is static.)
1446 : *
1447 : * The function marks the thread as started which allows the parent start()
1448 : * function to return.
1449 : *
1450 : * \note
1451 : * The function catches standard exceptions thrown by any of the functions
1452 : * called by the thread. When that happens, the thread returns early after
1453 : * making a copy of the exception. The stop() function will then rethrow
1454 : * that exception and it can be managed as if it had happened in the main
1455 : * process (if a thread creates another thread, then it can be propagated
1456 : * multiple times between all the threads up to the main process.)
1457 : */
1458 0 : void snap_thread::internal_run()
1459 : {
1460 : {
1461 0 : snap_lock lock(f_mutex);
1462 0 : f_tid = gettid();
1463 : }
1464 :
1465 : try
1466 : {
1467 : {
1468 0 : snap_lock lock(f_mutex);
1469 0 : f_started = true;
1470 0 : f_mutex.signal();
1471 : }
1472 :
1473 0 : f_runner->run();
1474 :
1475 : // if useful (necessary) it would probably be better to call this
1476 : // function from here; see function and read the "note" section
1477 : // for additional info
1478 : //
1479 : //tcp_client_server::cleanup_on_thread_exit();
1480 : }
1481 0 : catch(std::exception const &)
1482 : {
1483 : // keep a copy of the exception
1484 : //
1485 0 : f_exception = std::current_exception();
1486 : }
1487 0 : catch(...)
1488 : {
1489 : // ... any other exception terminates the whole process ...
1490 : //
1491 0 : SNAP_LOG_FATAL("thread got an unknown exception (a.k.a. non-std::exception), exiting process");
1492 :
1493 : // rethrow, our goal is not to ignore the exception, only to
1494 : // have a log about it
1495 : //
1496 0 : throw;
1497 : }
1498 :
1499 : // marked we are done (outside of the try/catch because if this one
1500 : // fails, we have a big problem... (i.e. invalid mutex or more unlock
1501 : // than locks)
1502 : {
1503 0 : snap_lock lock(f_mutex);
1504 0 : f_running = false;
1505 0 : f_tid = -1;
1506 0 : f_mutex.signal();
1507 : }
1508 0 : }
1509 :
1510 :
1511 : /** \brief Attempt to start the thread.
1512 : *
1513 : * This function is used to start running the thread code. If the
1514 : * thread is already running, then the function returns false.
1515 : *
1516 : * The function makes use of a condition to wait until the thread
1517 : * is indeed started. The function will not return until the thread
1518 : * is started or something failed.
1519 : *
1520 : * \return true if the thread successfully started, false otherwise.
1521 : */
1522 0 : bool snap_thread::start()
1523 : {
1524 0 : snap_lock lock(f_mutex);
1525 :
1526 0 : if(f_running || f_started)
1527 : {
1528 0 : SNAP_LOG_WARNING("the thread is already running");
1529 0 : return false;
1530 : }
1531 :
1532 0 : if(!f_runner->is_ready())
1533 : {
1534 0 : SNAP_LOG_WARNING("the thread runner is not ready");
1535 0 : return false;
1536 : }
1537 :
1538 0 : f_running = true;
1539 0 : f_started = false;
1540 0 : f_stopping = false; // make sure it is reset
1541 0 : f_exception = std::exception_ptr();
1542 :
1543 0 : int const err(pthread_create(&f_thread_id, &f_thread_attr, &func_internal_start, this));
1544 0 : if(err != 0)
1545 : {
1546 0 : f_running = false;
1547 :
1548 0 : SNAP_LOG_ERROR("the thread could not be created, error #")(err);
1549 0 : return false;
1550 : }
1551 :
1552 0 : while(!f_started)
1553 : {
1554 0 : f_mutex.wait();
1555 : }
1556 :
1557 0 : return true;
1558 : }
1559 :
1560 :
1561 : /** \brief Stop the thread.
1562 : *
1563 : * This function requests the thread to stop. Note that the function does
1564 : * not actually forcebly stop the thread. It only turns on a flag (namely
1565 : * it makes the is_stopping() function return true) meaning that the
1566 : * thread should stop as soon as possible. This gives the thread the
1567 : * time necessary to do all necessary cleanup before quitting.
1568 : *
1569 : * The stop function blocks until the thread is done.
1570 : *
1571 : * \warning
1572 : * This function throws the thread exceptions that weren't caught in your
1573 : * run() function. This happens after the thread has completed.
1574 : */
1575 0 : void snap_thread::stop()
1576 : {
1577 : {
1578 0 : snap_lock lock(f_mutex);
1579 :
1580 0 : if(!f_running && !f_started)
1581 : {
1582 : // we return immediately in this case because
1583 : // there is nothing to join when the thread never
1584 : // started...
1585 : //
1586 0 : return;
1587 : }
1588 :
1589 : // request the child to stop
1590 : //
1591 0 : f_stopping = true;
1592 : }
1593 :
1594 : // wait for the child to be stopped
1595 : //
1596 : // we cannot pass any results through the pthread interface so we
1597 : // pass a nullptr for the result; instead, the user is expected to
1598 : // add fields to his class and fill in whatever results he wants
1599 : // there; it is going to work much better that way
1600 : //
1601 0 : pthread_join(f_thread_id, nullptr);
1602 :
1603 : // at this point the thread has fully exited
1604 :
1605 : // we are done now
1606 : //
1607 : // these flags are likely already the correct value except for
1608 : // f_stopping which the stop() function manages here
1609 : //
1610 0 : f_running = false;
1611 0 : f_started = false;
1612 0 : f_stopping = false;
1613 :
1614 : // if the child died because of a standard exception, rethrow it now
1615 : //
1616 0 : if(f_exception != std::exception_ptr())
1617 : {
1618 0 : std::rethrow_exception(f_exception);
1619 : }
1620 : }
1621 :
1622 :
1623 : /** \brief Retrieve the thread identifier of this thread.
1624 : *
1625 : * Under Linux, threads are tasks like any others. Each task is given a
1626 : * `pid_t` value. This function returns that `pid_t` for this thread.
1627 : *
1628 : * When the thread is not running this function returns -1. Note, however,
1629 : * that the value is set a little after the thread started and cleared a
1630 : * little before the thread exists. This is **not** a good way to know
1631 : * whether the thread is running. Use the is_running() function instead.
1632 : *
1633 : * \return The thread identifier (tid) or -1 if the thread is not running.
1634 : */
1635 0 : pid_t snap_thread::get_thread_tid() const
1636 : {
1637 0 : snap_lock lock(f_mutex);
1638 0 : return f_tid;
1639 : }
1640 :
1641 :
1642 : /** \brief Retrieve a reference to the thread mutex.
1643 : *
1644 : * This function returns a reference to this thread mutex. Note that
1645 : * the `snap_runner` has its own mutex as well.
1646 : *
1647 : * \return This thread's mutex.
1648 : */
1649 0 : snap_thread::snap_mutex & snap_thread::get_thread_mutex() const
1650 : {
1651 0 : return f_mutex;
1652 : }
1653 :
1654 :
1655 : /** \brief Send a signal to this thread.
1656 : *
1657 : * This function sends a signal to a specific thread.
1658 : *
1659 : * You have to be particularly careful with Unix signal and threads as they
1660 : * do not always work as expected. This is yet particularly useful if you
1661 : * want to send a signal such as SIGUSR1 and SIGUSR2 to a thread so it
1662 : * reacts one way or another (i.e. you are using poll() over a socket and
1663 : * need to be stopped without using a possibly long time out, you can use
1664 : * the signalfd() function to transform SIGUSR1 into a pollable signal.)
1665 : *
1666 : * \note
1667 : * Obviously, if the thread is not running, nothing happens.
1668 : *
1669 : * \param[in] sig The signal to send to this thread.
1670 : *
1671 : * \return true if the signal was sent, false if the signal could not
1672 : * be sent (i.e. the thread was already terminated...)
1673 : */
1674 0 : bool snap_thread::kill(int sig)
1675 : {
1676 0 : snap_lock lock(f_mutex);
1677 0 : if(f_running)
1678 : {
1679 : // pthread_kill() returns zero on success, otherwise it returns
1680 : // an error code which at this point we lose
1681 : //
1682 0 : return pthread_kill(f_thread_id, sig) == 0;
1683 : }
1684 :
1685 0 : return false;
1686 : }
1687 :
1688 :
1689 : /** \brief Retrieve the number of processors available on this system.
1690 : *
1691 : * This function returns the number of processors available on this system.
1692 : *
1693 : * \attention
1694 : * Note that the OS may not be using all of the available processors. This
1695 : * function returns the total number, including processors that are not
1696 : * currently usable by your application. Most often, you probably want to
1697 : * call get_number_of_available_processors() instead.
1698 : *
1699 : * \return The total number of processors on this system.
1700 : *
1701 : * \sa get_number_of_available_processors()
1702 : */
1703 0 : int snap_thread::get_total_number_of_processors()
1704 : {
1705 0 : return get_nprocs_conf();
1706 : }
1707 :
1708 :
1709 : /** \brief Retrieve the number of processors currently usable.
1710 : *
1711 : * This function returns the number of processors that are currently
1712 : * running on this system. This is usually what you want to know about
1713 : * to determine how many threads to run in parallel.
1714 : *
1715 : * This function is going to be equal or less than what the
1716 : * get_total_number_of_processors() returns. For example, on some systems
1717 : * a processors can be made offline. This is useful to save energy when
1718 : * the total load decreases under a given threshold.
1719 : *
1720 : * \note
1721 : * What is the right number of threads needed in a thread pool? If you
1722 : * have worker threads that do a fairly small amount of work, then
1723 : * having a number of threads equal to two times the number of
1724 : * available thread is still sensible:
1725 : *
1726 : * \code
1727 : * pool_size = get_number_of_available_processors() * 2;
1728 : * \endcode
1729 : *
1730 : * \par
1731 : * This is particularly true when threads perform I/O with high latency
1732 : * (i.e. read/write from a hard drive or a socket.)
1733 : *
1734 : * \par
1735 : * If your thread does really intesive work for a while (i.e. one thread
1736 : * working on one 4Mb image,) then the pool size should be limited to
1737 : * one worker per CPU:
1738 : *
1739 : * \code
1740 : * pool_size = get_number_of_available_processors();
1741 : * \endcode
1742 : *
1743 : * \par
1744 : * Also, if you know that you will never get more than `n` objects at
1745 : * a time in your input, then the maximum number of threads needed is
1746 : * going to be `n`. In most cases `n` is going to be larger than the
1747 : * number of processors although now that we can have machines with
1748 : * over 100 CPUs, make sure to clamp your `pool_size` parameter to
1749 : * `n` if known ahead of time.
1750 : *
1751 : * \return The number of processors currently available for your threads.
1752 : *
1753 : * \sa get_total_number_of_processors()
1754 : */
1755 0 : int snap_thread::get_number_of_available_processors()
1756 : {
1757 0 : return get_nprocs();
1758 : }
1759 :
1760 :
1761 : /** \brief Get the thread identifier of the current thread.
1762 : *
1763 : * This function retrieves the thread identifier of the current thread.
1764 : * In most cases, this is only useful to print out messages to a log
1765 : * including the thread identifier. This identifier is equivalent
1766 : * to the `pid_t` returned by `getpid()` but specific to the running
1767 : * thread.
1768 : *
1769 : * \return The thread identifier.
1770 : */
1771 0 : pid_t snap_thread::gettid()
1772 : {
1773 0 : return static_cast<pid_t>(syscall(SYS_gettid));
1774 : }
1775 :
1776 6 : } // namespace snap
1777 : // vim: ts=4 sw=4 et
|