Another Asynchronous Example
Example 48 provides another alternative for processing the results of asynchronous operations. In this example, the RWRunnableServer is replaced by an RWServerPool, an identification value is added for each operation invocation, and the RWTIOUTrap processes the results of the operations.
Example 48 – Using an IOU trap to handle results from asynchronous operations
#include <rw/thread/RWRunnableSelf.h>
#include <rw/thread/RWServerPool.h>
#include <rw/thread/RWTRunnableIOUFunction.h>
#include <rw/itc/RWTIOUResult.h>
#include <rw/itc/RWTIOUTrap.h>
#include <iostream>
 
using namespace std;
 
class ServiceProvider; // Forward reference for inlines!
 
class ServiceProvider {
private:
RWServerPool server_;
protected:
int syncService(int opId, int delay) // 1
{
// Do something that takes varying amounts of time
rwSleep(delay);
return opId;
}
public:
ServiceProvider(size_t concurrencyLevel) { // 2
server_ = RWServerPool::make(concurrencyLevel);
server_.start();
}
~ServiceProvider() { // 3
server_.stop();
server_.join();
}
RWTIOUResult<int> asyncService(int opId, int delay) { // 4
RWTRunnableIOUFunction<int> runnable;
runnable = RWTRunnableIOUFunction<int>::make(
rwBind(&ServiceProvider::syncService, this, opId, delay));
server_.enqueue(runnable);
return runnable.result();
}
};
 
void
main()
{
const size_t concurrency = 5;
const size_t operations = 10;
size_t i;
 
ServiceProvider provider(concurrency); // 5
RWTIOUTrap<int> trap; // 6
for (i=0; i<operations; i++)
trap.setTrap(provider.asyncService(i,rand()%1000)); // 7
 
for (i=0; i<operations; i++) {
cout << "Operation ";
cout << trap.getNext(); // 8
cout << " complete!" << endl;
}
}
 
//1 Defines the actual service to be performed.
//2 Define sa constructor that creates and starts the internal server pool. The constructor argument specifies the number of runnable server threads to create within the pool.
//3 Defines a destructor that stops the internal server and waits for it to exit.
//4 Defines a member function to initiate an asynchronous operation by constructing a synchronous runnable and passing it to the internal server. The IOU representing the result of the operation is returned to the caller.
//5 Constructs an instance of the service provider.
//6 Creates an IOU trap instance.
//7 Starts one of several asynchronous service requests using the loop index to identify each request. Adds the IOU result of each request to the trap.
//8 Redeems the next available IOU result provided by the trap, blocking (if necessary) until the trap captures another result.