Lunchbox  1.16.0
Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs.
request.h
1 
2 /* Copyright (c) 2013-2015, Stefan.Eilemann@epfl.ch
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License version 2.1 as published
6  * by the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11  * details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this library; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  */
17 
18 #ifndef LUNCHBOX_REQUEST_H
19 #define LUNCHBOX_REQUEST_H
20 
21 #include <boost/mpl/if.hpp>
22 #include <boost/type_traits/is_same.hpp>
23 #include <lunchbox/future.h>
24 
25 namespace lunchbox
26 {
27 class UnregisteredRequest : public std::runtime_error
28 {
29 public:
31  : std::runtime_error("wait on an unregistered request")
32  {
33  }
34 };
35 
40 template <class T>
41 class Request : public Future<T>
42 {
43  class Impl;
44 
45 public:
47  Request(RequestHandler& handler, const uint32_t request);
48 
53  virtual ~Request();
54 
56  uint32_t getID() const;
57 
65  void unregister();
66 };
67 }
68 
69 // Implementation: Here be dragons
70 
71 #include <lunchbox/requestHandler.h>
72 namespace lunchbox
73 {
74 template <class T>
75 class Request<T>::Impl : public FutureImpl<T>
76 {
77  typedef typename boost::mpl::if_<boost::is_same<T, void>, void*, T>::type
78  value_t;
79 
80 public:
81  Impl(RequestHandler& handler, const uint32_t req)
82  : request(req)
83  , result(0)
84  , handler_(handler)
85  , state_(UNRESOLVED)
86  {
87  }
88  virtual ~Impl() {}
89  const uint32_t request;
90  value_t result;
91 
92  void unregister()
93  {
94  if (state_ == UNRESOLVED)
95  {
96  state_ = UNREGISTERED;
97  handler_.unregisterRequest(request);
98  }
99  }
100 
101  bool isUnresolved() const { return state_ == UNRESOLVED; }
102 protected:
103  T wait(const uint32_t timeout) final
104  {
105  switch (state_)
106  {
107  case UNREGISTERED:
108  throw UnregisteredRequest();
109  case UNRESOLVED:
110  if (!handler_.waitRequest(request, result, timeout))
111  throw FutureTimeout();
112  state_ = DONE;
113  // No break
114  default: // DONE
115  return result;
116  }
117  }
118 
119  bool isReady() const final
120  {
121  switch (state_)
122  {
123  case UNRESOLVED:
124  return handler_.isRequestReady(request);
125  case UNREGISTERED:
126  return false;
127  default: // DONE:
128  return true;
129  }
130  }
131 
132 private:
133  RequestHandler& handler_;
134  enum State
135  {
136  UNRESOLVED,
137  DONE,
138  UNREGISTERED
139  };
140  State state_;
141 };
142 
143 template <>
144 inline void Request<void>::Impl::wait(const uint32_t timeout)
145 {
146  switch (state_)
147  {
148  case UNREGISTERED:
149  throw UnregisteredRequest();
150  case UNRESOLVED:
151  if (!handler_.waitRequest(request, result, timeout))
152  throw FutureTimeout();
153  state_ = DONE;
154  // No break
155  case DONE:;
156  }
157 }
158 
159 template <class T>
160 inline Request<T>::Request(RequestHandler& handler, const uint32_t request)
161  : Future<T>(new Impl(handler, request))
162 {
163 }
164 
165 template <class T>
167 {
168  if (static_cast<const Impl*>(this->impl_.get())->isUnresolved())
169  this->wait();
170 }
171 
172 template <class T>
173 inline uint32_t Request<T>::getID() const
174 {
175  return static_cast<const Impl*>(this->impl_.get())->request;
176 }
177 
178 template <class T>
180 {
181  static_cast<Impl*>(this->impl_.get())->unregister();
182 }
183 }
184 
185 #endif // LUNCHBOX_REQUEST_H
bool isReady() const final
Definition: request.h:119
virtual ~Request()
Destruct and wait for completion of the request, unless relinquished.
Definition: request.h:166
uint32_t getID() const
Definition: request.h:173
Request(RequestHandler &handler, const uint32_t request)
Construct a new request.
Definition: request.h:160
T wait(const uint32_t timeout_=LB_TIMEOUT_INDEFINITE)
Wait for the promise to be fullfilled.
Definition: future.h:85
A Future implementation for a RequestHandler request.
Definition: request.h:41
void unregister()
Unregister this request from the request handler.
Definition: request.h:179
Base class to implement the wait method fulfilling the future.
Definition: future.h:39
A future represents a asynchronous operation.
Definition: future.h:62
Abstraction layer and common utilities for multi-threaded programming.
Definition: algorithm.h:29
A thread-safe request handler.
T wait(const uint32_t timeout) final
Wait for the promise to be fullfilled.
Definition: request.h:103