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