LCOV - code coverage report
Current view: top level - snapwebsites - snap_thread.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 265 0.4 %
Date: 2019-12-15 17:13:15 Functions: 2 39 5.1 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.13