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 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 0.
66 : * @return the request identifier.
67 : * @version 1.0
68 : * @deprecated use the future-based registerRequest()
69 : */
70 2 : uint32_t registerRequest( void* data = 0 ) { return _register( data ); }
71 :
72 : /**
73 : * Unregister a request.
74 : *
75 : * Note that waitRequest automatically unregisters the request when it was
76 : * successful. This method is only used when a waitRequest has timed out and
77 : * the request will no longer be used.
78 : *
79 : * @param requestID the request identifier.
80 : * @version 1.0
81 : */
82 : LUNCHBOX_API void unregisterRequest( const uint32_t requestID );
83 :
84 : /**
85 : * Wait a given time for the completion of a request.
86 : *
87 : * The request is unregistered upon successful completion, i.e, the when the
88 : * method returns true.
89 : *
90 : * @param requestID the request identifier.
91 : * @param result the result code of the operation.
92 : * @param timeout the timeout in milliseconds to wait for the request,
93 : * or <code>LB_TIMEOUT_INDEFINITE</code> to wait
94 : * indefinitely.
95 : * @return true if the request was served, false if not.
96 : * @version 1.0
97 : */
98 : LUNCHBOX_API bool waitRequest( const uint32_t requestID, void*& result,
99 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
100 :
101 : /** Wait for a request with an uint32_t result. @version 1.0 */
102 : LUNCHBOX_API bool waitRequest( const uint32_t requestID, uint32_t& result,
103 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
104 : /** Wait for a request with a bool result. @version 1.0 */
105 : LUNCHBOX_API bool waitRequest( const uint32_t requestID, bool& result,
106 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
107 : /** Wait for a request with an uint128_t result. @version 1.0 */
108 : LUNCHBOX_API bool waitRequest( const uint32_t requestID,
109 : servus::uint128_t& result,
110 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
111 : /** Wait for a request without a result. @version 1.0 */
112 : LUNCHBOX_API bool waitRequest( const uint32_t requestID );
113 :
114 : /**
115 : * Retrieve the user-specific data for a request.
116 : *
117 : * @param requestID the request identifier.
118 : * @return the user-specific data for the request.
119 : * @version 1.0
120 : */
121 : LUNCHBOX_API void* getRequestData( const uint32_t requestID );
122 :
123 : /**
124 : * Serve a request with a void* result.
125 : *
126 : * @param requestID the request identifier.
127 : * @param result the result of the request.
128 : * @version 1.0
129 : */
130 : LUNCHBOX_API void serveRequest( const uint32_t requestID,
131 : void* result = 0 );
132 : /** Serve a request with an uint32_t result. @version 1.0 */
133 : LUNCHBOX_API void serveRequest( const uint32_t requestID,
134 : uint32_t result );
135 : /** Serve a request with a bool result. @version 1.0 */
136 : LUNCHBOX_API void serveRequest( const uint32_t requestID, bool result );
137 : /** Serve a request with an uint128_t result. @version 1.0 */
138 : LUNCHBOX_API void serveRequest( const uint32_t requestID,
139 : const servus::uint128_t& result );
140 : /**
141 : * @return true if this request handler has pending requests.
142 : * @version 1.0
143 : */
144 : LUNCHBOX_API bool hasPendingRequests() const;
145 :
146 : LUNCHBOX_API bool isRequestReady( const uint32_t ) const; //!< @internal
147 :
148 : private:
149 : detail::RequestHandler* const _impl;
150 : friend LUNCHBOX_API std::ostream& operator << ( std::ostream&,
151 : const RequestHandler& );
152 : LUNCHBOX_API uint32_t _register( void* data );
153 2 : LB_TS_VAR( _thread );
154 : };
155 :
156 : LUNCHBOX_API std::ostream& operator << ( std::ostream&, const RequestHandler& );
157 : }
158 :
159 : #include <lunchbox/request.h>
160 :
161 : namespace lunchbox
162 : {
163 : template< class T > inline
164 5 : Request< T > RequestHandler::registerRequest( void* data )
165 : {
166 5 : return Request< T >( *this, _register( data ));
167 : }
168 : }
169 :
170 : #endif //LUNCHBOX_REQUESTHANDLER_H
|