Line data Source code
1 :
2 : /* Copyright (c) 2005-2014, 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 { class RequestHandler; }
29 :
30 : /**
31 : * A thread-safe request handler.
32 : *
33 : * Different execution threads can synchronize using a request handler. One
34 : * thread registers a request, and later waits for the request to be
35 : * served. Another thread can serve the request, providing a result value.
36 : *
37 : * Thread-safety: The methods registerRequest(), unregisterRequest() and
38 : * waitRequest() are supposed to be called from one 'waiting' thread, and the
39 : * functions serveRequest() and deleteRequest() are supposed to be called only
40 : * from one 'serving' thread.
41 : *
42 : * Example: @include tests/requestHandler.cpp
43 : */
44 : class RequestHandler : public boost::noncopyable
45 : {
46 : public:
47 : /** Construct a new request handler. @version 1.0 */
48 : LUNCHBOX_API RequestHandler();
49 :
50 : /** Destruct the request handler. */
51 : LUNCHBOX_API ~RequestHandler();
52 :
53 : /**
54 : * Register a request.
55 : *
56 : * @param data a pointer to user-specific data for the request, can be
57 : * 0.
58 : * @return A Future which will be fulfilled on serveRequest().
59 : * @version 1.9.1
60 : */
61 : template< class T > Request< T > registerRequest( void* data = 0 );
62 :
63 : /**
64 : * Register a request.
65 : *
66 : * @param data a pointer to user-specific data for the request, can be
67 : * 0.
68 : * @return the request identifier.
69 : * @version 1.0
70 : * @deprecated use the future-based registerRequest()
71 : */
72 2 : uint32_t registerRequest( void* data = 0 ) LB_DEPRECATED
73 2 : { return _register( data ); }
74 :
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( const uint32_t requestID, void*& result,
102 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
103 :
104 : /** Wait for a request with an uint32_t result. @version 1.0 */
105 : LUNCHBOX_API bool waitRequest( const uint32_t requestID, uint32_t& result,
106 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
107 : /** Wait for a request with a bool result. @version 1.0 */
108 : LUNCHBOX_API bool waitRequest( const uint32_t requestID, bool& result,
109 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
110 : /** Wait for a request with an uint128_t result. @version 1.0 */
111 : LUNCHBOX_API bool waitRequest( const uint32_t requestID,
112 : servus::uint128_t& result,
113 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
114 : /** Wait for a request without a result. @version 1.0 */
115 : LUNCHBOX_API bool waitRequest( const uint32_t requestID );
116 :
117 : /**
118 : * Poll for the completion of a request.
119 : *
120 : * @version 1.0
121 : * @deprecated use Request::isReady()
122 : */
123 1 : bool isRequestServed( const uint32_t id ) const LB_DEPRECATED
124 1 : { return isRequestReady( id ); }
125 :
126 : /**
127 : * Retrieve the user-specific data for a request.
128 : *
129 : * @param requestID the request identifier.
130 : * @return the user-specific data for the request.
131 : * @version 1.0
132 : */
133 : LUNCHBOX_API void* getRequestData( const uint32_t requestID );
134 :
135 : /**
136 : * Serve a request with a void* result.
137 : *
138 : * @param requestID the request identifier.
139 : * @param result the result of the request.
140 : * @version 1.0
141 : */
142 : LUNCHBOX_API void serveRequest( const uint32_t requestID,
143 : void* result = 0 );
144 : /** Serve a request with an uint32_t result. @version 1.0 */
145 : LUNCHBOX_API void serveRequest( const uint32_t requestID,
146 : uint32_t result );
147 : /** Serve a request with a bool result. @version 1.0 */
148 : LUNCHBOX_API void serveRequest( const uint32_t requestID, bool result );
149 : /** Serve a request with an uint128_t result. @version 1.0 */
150 : LUNCHBOX_API void serveRequest( const uint32_t requestID,
151 : const servus::uint128_t& result );
152 : /**
153 : * @return true if this request handler has pending requests.
154 : * @version 1.0
155 : */
156 : LUNCHBOX_API bool hasPendingRequests() const;
157 :
158 : LUNCHBOX_API bool isRequestReady( const uint32_t ) const; //!< @internal
159 :
160 : private:
161 : detail::RequestHandler* const _impl;
162 : friend LUNCHBOX_API std::ostream& operator << ( std::ostream&,
163 : const RequestHandler& );
164 : LUNCHBOX_API uint32_t _register( void* data );
165 2 : LB_TS_VAR( _thread );
166 : };
167 :
168 : LUNCHBOX_API std::ostream& operator << ( std::ostream&, const RequestHandler& );
169 : }
170 :
171 : #include <lunchbox/request.h>
172 :
173 : namespace lunchbox
174 : {
175 : template< class T > inline
176 3 : Request< T > RequestHandler::registerRequest( void* data )
177 : {
178 3 : return Request< T >( *this, _register( data ));
179 : }
180 : }
181 :
182 : #endif //LUNCHBOX_REQUESTHANDLER_H
|