Line data Source code
1 :
2 : /* Copyright (c) 2005-2017, Stefan Eilemann <eile@equalizergraphics.com>
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_REQUESTHANDLER_H
19 : #define LUNCHBOX_REQUESTHANDLER_H
20 :
21 : #include <lunchbox/api.h> // LUNCHBOX_API definition
22 : #include <lunchbox/thread.h> // thread-safety macros
23 : #include <lunchbox/types.h>
24 : #include <servus/uint128_t.h>
25 :
26 : namespace lunchbox
27 : {
28 : namespace detail
29 : {
30 : class RequestHandler;
31 : }
32 :
33 : /**
34 : * A thread-safe request handler.
35 : *
36 : * Different execution threads can synchronize using a request handler. One
37 : * thread registers a request, and later waits for the request to be
38 : * served. Another thread can serve the request, providing a result value.
39 : *
40 : * Thread-safety: The methods registerRequest(), unregisterRequest() and
41 : * waitRequest() are supposed to be called from one 'waiting' thread, and the
42 : * functions serveRequest() and deleteRequest() are supposed to be called only
43 : * from one 'serving' thread.
44 : *
45 : * Example: @include tests/requestHandler.cpp
46 : */
47 : class RequestHandler : public boost::noncopyable
48 : {
49 : public:
50 : /** Construct a new request handler. @version 1.0 */
51 : LUNCHBOX_API RequestHandler();
52 :
53 : /** Destruct the request handler. */
54 : LUNCHBOX_API ~RequestHandler();
55 :
56 : /**
57 : * Register a request.
58 : *
59 : * @param data a pointer to user-specific data for the request, can be 0.
60 : * @return A Future which will be fulfilled on serveRequest().
61 : * @version 1.9.1
62 : */
63 : template <class T>
64 : Request<T> registerRequest(void* data = 0);
65 :
66 : /**
67 : * Register a request.
68 : *
69 : * @param data a pointer to user-specific data for the request, can be 0.
70 : * @return the request identifier.
71 : * @version 1.0
72 : * @deprecated use the future-based registerRequest()
73 : */
74 2 : uint32_t registerRequest(void* data = 0) { return _register(data); }
75 : /**
76 : * Unregister a request.
77 : *
78 : * Note that waitRequest automatically unregisters the request when it was
79 : * successful. This method is only used when a waitRequest has timed out and
80 : * the request will no longer be used.
81 : *
82 : * @param requestID the request identifier.
83 : * @version 1.0
84 : */
85 : LUNCHBOX_API void unregisterRequest(const uint32_t requestID);
86 :
87 : /**
88 : * Wait a given time for the completion of a request.
89 : *
90 : * The request is unregistered upon successful completion, i.e, the when the
91 : * method returns true.
92 : *
93 : * @param requestID the request identifier.
94 : * @param result the result code of the operation.
95 : * @param timeout the timeout in milliseconds to wait for the request,
96 : * or <code>LB_TIMEOUT_INDEFINITE</code> to wait
97 : * indefinitely.
98 : * @return true if the request was served, false if not.
99 : * @version 1.0
100 : */
101 : LUNCHBOX_API bool waitRequest(
102 : const uint32_t requestID, void*& result,
103 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE);
104 :
105 : /** Wait for a request with an uint32_t result. @version 1.0 */
106 : LUNCHBOX_API bool waitRequest(
107 : const uint32_t requestID, uint32_t& result,
108 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE);
109 : /** Wait for a request with a bool result. @version 1.0 */
110 : LUNCHBOX_API bool waitRequest(
111 : const uint32_t requestID, bool& result,
112 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE);
113 : /** Wait for a request with an uint128_t result. @version 1.0 */
114 : LUNCHBOX_API bool waitRequest(
115 : const uint32_t requestID, servus::uint128_t& result,
116 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE);
117 : /** Wait for a request without a result. @version 1.0 */
118 : LUNCHBOX_API bool waitRequest(const uint32_t requestID);
119 :
120 : /**
121 : * Retrieve the user-specific data for a request.
122 : *
123 : * @param requestID the request identifier.
124 : * @return the user-specific data for the request.
125 : * @version 1.0
126 : */
127 : LUNCHBOX_API void* getRequestData(const uint32_t requestID);
128 :
129 : /**
130 : * Serve a request with a void* result.
131 : *
132 : * @param requestID the request identifier.
133 : * @param result the result of the request.
134 : * @version 1.0
135 : */
136 : LUNCHBOX_API void serveRequest(const uint32_t requestID, void* result = 0);
137 : /** Serve a request with an uint32_t result. @version 1.0 */
138 : LUNCHBOX_API void serveRequest(const uint32_t requestID, uint32_t result);
139 : /** Serve a request with a bool result. @version 1.0 */
140 : LUNCHBOX_API void serveRequest(const uint32_t requestID, bool result);
141 : /** Serve a request with an uint128_t result. @version 1.0 */
142 : LUNCHBOX_API void serveRequest(const uint32_t requestID,
143 : const servus::uint128_t& result);
144 : /**
145 : * @return true if this request handler has pending requests.
146 : * @version 1.0
147 : */
148 : LUNCHBOX_API bool hasPendingRequests() const;
149 :
150 : LUNCHBOX_API bool isRequestReady(const uint32_t) const; //!< @internal
151 :
152 : private:
153 : detail::RequestHandler* const _impl;
154 :
155 : LUNCHBOX_API uint32_t _register(void* data);
156 2 : LB_TS_VAR(_thread);
157 : };
158 : }
159 :
160 : #include <lunchbox/request.h>
161 :
162 : namespace lunchbox
163 : {
164 : template <class T>
165 5 : inline Request<T> RequestHandler::registerRequest(void* data)
166 : {
167 5 : return Request<T>(*this, _register(data));
168 : }
169 : }
170 :
171 : #endif // LUNCHBOX_REQUESTHANDLER_H
|