Lunchbox  1.15.0
Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs.
lunchbox::RequestHandler Class Reference

A thread-safe request handler. More...

#include <requestHandler.h>

+ Inheritance diagram for lunchbox::RequestHandler:
+ Collaboration diagram for lunchbox::RequestHandler:

Public Member Functions

 RequestHandler ()
 Construct a new request handler. More...
 
 ~RequestHandler ()
 Destruct the request handler. More...
 
template<class T >
Request< T > registerRequest (void *data=0)
 Register a request. More...
 
uint32_t registerRequest (void *data=0)
 Register a request. More...
 
void unregisterRequest (const uint32_t requestID)
 Unregister a request. More...
 
bool waitRequest (const uint32_t requestID, void *&result, const uint32_t timeout=LB_TIMEOUT_INDEFINITE)
 Wait a given time for the completion of a request. More...
 
bool waitRequest (const uint32_t requestID, uint32_t &result, const uint32_t timeout=LB_TIMEOUT_INDEFINITE)
 Wait for a request with an uint32_t result. More...
 
bool waitRequest (const uint32_t requestID, bool &result, const uint32_t timeout=LB_TIMEOUT_INDEFINITE)
 Wait for a request with a bool result. More...
 
bool waitRequest (const uint32_t requestID, servus::uint128_t &result, const uint32_t timeout=LB_TIMEOUT_INDEFINITE)
 Wait for a request with an uint128_t result. More...
 
bool waitRequest (const uint32_t requestID)
 Wait for a request without a result. More...
 
void * getRequestData (const uint32_t requestID)
 Retrieve the user-specific data for a request. More...
 
void serveRequest (const uint32_t requestID, void *result=0)
 Serve a request with a void* result. More...
 
void serveRequest (const uint32_t requestID, uint32_t result)
 Serve a request with an uint32_t result. More...
 
void serveRequest (const uint32_t requestID, bool result)
 Serve a request with a bool result. More...
 
void serveRequest (const uint32_t requestID, const servus::uint128_t &result)
 Serve a request with an uint128_t result. More...
 
bool hasPendingRequests () const
 
bool isRequestReady (const uint32_t) const
 

Friends

std::ostream & operator<< (std::ostream &, const RequestHandler &)
 

Detailed Description

A thread-safe request handler.

Different execution threads can synchronize using a request handler. One thread registers a request, and later waits for the request to be served. Another thread can serve the request, providing a result value.

Thread-safety: The methods registerRequest(), unregisterRequest() and waitRequest() are supposed to be called from one 'waiting' thread, and the functions serveRequest() and deleteRequest() are supposed to be called only from one 'serving' thread.

Example:

/* Copyright (c) 2013-2014, Stefan.Eilemann@epfl.ch
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 2.1 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <lunchbox/test.h>
#include <lunchbox/mtQueue.h>
#include <lunchbox/requestHandler.h>
#include <lunchbox/sleep.h>
#include <lunchbox/thread.h>
#include <servus/uint128_t.h>
using servus::uint128_t;
const uint128_t uuid = servus::make_UUID();
class Thread : public lunchbox::Thread
{
public:
virtual void run() final
{
const bool boolIn = true;
uint8_t* payload = (uint8_t*)42;
uint32_t request = requestQ_.pop();
TEST( handler_.getRequestData( request ) == ++payload );
handler_.serveRequest( request, boolIn );
const uint32_t uint32In = 0xC0FFEE;
request = requestQ_.pop();
TEST( handler_.getRequestData( request ) == ++payload );
handler_.serveRequest( request, uint32In );
request = requestQ_.pop();
TEST( handler_.getRequestData( request ) == ++payload );
handler_.serveRequest( request );
request = requestQ_.pop();
TESTINFO( handler_.getRequestData( request ) == ++payload,
(size_t)handler_.getRequestData( request ) << " for " <<
request );
handler_.serveRequest( request );
request = requestQ_.pop();
TEST( handler_.getRequestData( request ) == ++payload );
handler_.serveRequest( request, uuid );
request = requestQ_.pop();
TEST( handler_.getRequestData( request ) == ++payload );
handler_.serveRequest( request );
}
};
int main( int, char** )
{
uint8_t* payload = (uint8_t*)42;
Thread thread;
thread.start();
uint32_t request = handler_.registerRequest( ++payload );
requestQ_.push( request );
bool boolOut = false;
TEST( handler_.waitRequest( request, boolOut ));
TEST( boolOut == true );
handler_.registerRequest< uint32_t >( ++payload );
requestQ_.push( future.getID( ));
request = handler_.registerRequest( ++payload );
requestQ_.push( request );
TEST( handler_.waitRequest( request ));
handler_.registerRequest< void >( ++payload );
handler_.registerRequest< uint128_t >( ++payload );
requestQ_.push( voidFuture.getID( ));
requestQ_.push( uint128Future.getID( ));
TEST( future.wait( ) == 0xC0FFEE );
TEST( future.wait( ));
TEST( uint128Future.wait() == uuid );
TEST( voidFuture.isReady( ));
voidFuture.wait( );
{
lunchbox::Request< void > waitAtDestructor =
handler_.registerRequest< void >( ++payload );
requestQ_.push( waitAtDestructor.getID( ));
}
{
handler_.registerRequest< void >( ++payload );
try
{
wontBeServed.wait( 1 );
lunchbox::abort();
}
catch( const lunchbox::FutureTimeout& ) {}
TEST( handler_.hasPendingRequests( ))
wontBeServed.unregister();
TEST( !handler_.hasPendingRequests( ))
try
{
wontBeServed.wait();
lunchbox::abort();
}
catch( const lunchbox::UnregisteredRequest& ) {}
}
TEST( thread.join( ));
return EXIT_SUCCESS;
}

Definition at line 44 of file requestHandler.h.

Constructor & Destructor Documentation

lunchbox::RequestHandler::RequestHandler ( )

Construct a new request handler.

Version
1.0
lunchbox::RequestHandler::~RequestHandler ( )

Destruct the request handler.

Member Function Documentation

void* lunchbox::RequestHandler::getRequestData ( const uint32_t  requestID)

Retrieve the user-specific data for a request.

Parameters
requestIDthe request identifier.
Returns
the user-specific data for the request.
Version
1.0
bool lunchbox::RequestHandler::hasPendingRequests ( ) const
Returns
true if this request handler has pending requests.
Version
1.0
template<class T >
Request< T > lunchbox::RequestHandler::registerRequest ( void *  data = 0)
inline

Register a request.

Parameters
dataa pointer to user-specific data for the request, can be 0.
Returns
A Future which will be fulfilled on serveRequest().
Version
1.9.1

Definition at line 164 of file requestHandler.h.

uint32_t lunchbox::RequestHandler::registerRequest ( void *  data = 0)
inline

Register a request.

Parameters
dataa pointer to user-specific data for the request, can be 0.
Returns
the request identifier.
Version
1.0
Deprecated:
use the future-based registerRequest()

Definition at line 70 of file requestHandler.h.

References LB_TIMEOUT_INDEFINITE, and lunchbox::operator<<().

+ Here is the call graph for this function:

void lunchbox::RequestHandler::serveRequest ( const uint32_t  requestID,
void *  result = 0 
)

Serve a request with a void* result.

Parameters
requestIDthe request identifier.
resultthe result of the request.
Version
1.0
void lunchbox::RequestHandler::serveRequest ( const uint32_t  requestID,
uint32_t  result 
)

Serve a request with an uint32_t result.

Version
1.0
void lunchbox::RequestHandler::serveRequest ( const uint32_t  requestID,
bool  result 
)

Serve a request with a bool result.

Version
1.0
void lunchbox::RequestHandler::serveRequest ( const uint32_t  requestID,
const servus::uint128_t &  result 
)

Serve a request with an uint128_t result.

Version
1.0
void lunchbox::RequestHandler::unregisterRequest ( const uint32_t  requestID)

Unregister a request.

Note that waitRequest automatically unregisters the request when it was successful. This method is only used when a waitRequest has timed out and the request will no longer be used.

Parameters
requestIDthe request identifier.
Version
1.0
bool lunchbox::RequestHandler::waitRequest ( const uint32_t  requestID,
void *&  result,
const uint32_t  timeout = LB_TIMEOUT_INDEFINITE 
)

Wait a given time for the completion of a request.

The request is unregistered upon successful completion, i.e, the when the method returns true.

Parameters
requestIDthe request identifier.
resultthe result code of the operation.
timeoutthe timeout in milliseconds to wait for the request, or LB_TIMEOUT_INDEFINITE to wait indefinitely.
Returns
true if the request was served, false if not.
Version
1.0
bool lunchbox::RequestHandler::waitRequest ( const uint32_t  requestID,
uint32_t &  result,
const uint32_t  timeout = LB_TIMEOUT_INDEFINITE 
)

Wait for a request with an uint32_t result.

Version
1.0
bool lunchbox::RequestHandler::waitRequest ( const uint32_t  requestID,
bool &  result,
const uint32_t  timeout = LB_TIMEOUT_INDEFINITE 
)

Wait for a request with a bool result.

Version
1.0
bool lunchbox::RequestHandler::waitRequest ( const uint32_t  requestID,
servus::uint128_t &  result,
const uint32_t  timeout = LB_TIMEOUT_INDEFINITE 
)

Wait for a request with an uint128_t result.

Version
1.0
bool lunchbox::RequestHandler::waitRequest ( const uint32_t  requestID)

Wait for a request without a result.

Version
1.0

The documentation for this class was generated from the following file: