summaryrefslogtreecommitdiff
path: root/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/task_adaptors.hpp
blob: 6b874e33587f360a4bffc7a1d3087f9cd82aef45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*! \file
* \brief Task adaptors.
*
* This file contains adaptors for task function objects.
*
* Copyright (c) 2005-2007 Philipp Henkel
*
* Use, modification, and distribution are  subject to the
* Boost Software License, Version 1.0. (See accompanying  file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
* http://threadpool.sourceforge.net
*
*/


#ifndef THREADPOOL_TASK_ADAPTERS_HPP_INCLUDED
#define THREADPOOL_TASK_ADAPTERS_HPP_INCLUDED


#include <boost/smart_ptr.hpp>
#include <boost/function.hpp>
#include <boost/thread.hpp>


namespace boost { namespace threadpool
{

  /*! \brief Standard task function object.
  *
  * This function object wraps a nullary function which returns void.
  * The wrapped function is invoked by calling the operator ().
  *
  * \see boost function library
  *
  */ 
  typedef function0<void> task_func;




  /*! \brief Prioritized task function object. 
  *
  * This function object wraps a task_func object and binds a priority to it.
  * prio_task_funcs can be compared using the operator < which realises a partial ordering.
  * The wrapped task function is invoked by calling the operator ().
  *
  * \see prio_scheduler
  *
  */ 
  class prio_task_func
  {
  private:
    unsigned int m_priority;  //!< The priority of the task's function.
    task_func m_function;     //!< The task's function.

  public:
    typedef void result_type; //!< Indicates the functor's result type.

  public:
    /*! Constructor.
    * \param priority The priority of the task.
    * \param function The task's function object.
    */
    prio_task_func(unsigned int const priority, task_func const & function)
      : m_priority(priority)
      , m_function(function)
    {
    }

    /*! Executes the task function.
    */
    void operator() (void) const
    {
      if(m_function)
      {
        m_function();
      }
    }

    /*! Comparison operator which realises a partial ordering based on priorities.
    * \param rhs The object to compare with.
    * \return true if the priority of *this is less than right hand side's priority, false otherwise.
    */
    bool operator< (const prio_task_func& rhs) const
    {
      return m_priority < rhs.m_priority; 
    }

  };  // prio_task_func



 




  /*! \brief Looped task function object. 
  *
  * This function object wraps a boolean thread function object.
  * The wrapped task function is invoked by calling the operator () and it is executed in regular 
  * time intervals until false is returned. The interval length may be zero.
  * Please note that a pool's thread is engaged as long as the task is looped.
  *
  */ 
  class looped_task_func
  {
  private:
    function0<bool> m_function;   //!< The task's function.
    unsigned int m_break_s;              //!< Duration of breaks in seconds.
    unsigned int m_break_ns;             //!< Duration of breaks in nano seconds.

  public:
    typedef void result_type; //!< Indicates the functor's result type.

  public:
    /*! Constructor.
    * \param function The task's function object which is looped until false is returned.
    * \param interval The minimum break time in milli seconds before the first execution of the task function and between the following ones.
    */
    looped_task_func(function0<bool> const & function, unsigned int const interval = 0)
      : m_function(function)
    {
      m_break_s  = interval / 1000;
      m_break_ns = (interval - m_break_s * 1000) * 1000 * 1000;
    }

    /*! Executes the task function.
    */
    void operator() (void) const
    {
      if(m_function)
      {
        if(m_break_s > 0 || m_break_ns > 0)
        { // Sleep some time before first execution
          xtime xt;
          xtime_get(&xt, TIME_UTC);
          xt.nsec += m_break_ns;
          xt.sec += m_break_s;
          thread::sleep(xt); 
        }

        while(m_function())
        {
          if(m_break_s > 0 || m_break_ns > 0)
          {
            xtime xt;
            xtime_get(&xt, TIME_UTC);
            xt.nsec += m_break_ns;
            xt.sec += m_break_s;
            thread::sleep(xt); 
          }
          else
          {
            thread::yield(); // Be fair to other threads
          }
        }
      }
    }

  }; // looped_task_func


} } // namespace boost::threadpool

#endif // THREADPOOL_TASK_ADAPTERS_HPP_INCLUDED