Resource Management in C++: Listing 2
Shared_resource implementation.
// shared_resource.cpp
#include "shared_resource.hpp"
#include <iostream>
#include <stdlib.h>
#include <stdexcept>
#include <sstream>
using namespace std;
string _compose_msg_about_resource(shared_resource*, const char*);
shared_resource* create_resource()
{
static int id = 0;
shared_resource* ret = static_cast<shared_resource*>(malloc(sizeof(shared_resource)));
if (ret)
{
ret->id = ++id;
cout << _compose_msg_about_resource(ret, "reserved for application");
ret->status = resource_status::available;
reset_resource(ret);
}
else
throw runtime_error("Resource couldn't be created.");
return ret;
}
void recycle_resource(shared_resource* resource)
{
if (resource)
{
shut_resource(resource);
cout << _compose_msg_about_resource(resource, "recycled");
free(resource);
}
// no else: recycling a null resource has no effect.
}
void shut_resource(shared_resource* resource)
{
if ((resource)&&(resource->status==resource_status::in_use))
{
resource->status = resource_status::available;
// other code that shuts the resource
// ...
cout << _compose_msg_about_resource(resource, "shut down (still allocated)");
}
// no else: turning off a null resource, or an already shut one has no effect.
}
// whatever its status, reinitiates the resource.
void reset_resource(shared_resource* resource)
{
if (resource)
{
if (resource->status==resource_status::available)
{
resource->status = resource_status::in_use;
// other code that reinitiates the resource
// ...
cout << _compose_msg_about_resource(resource, "ready for use");
}
else
{
throw runtime_error(_compose_msg_about_resource(resource, "already in use"));
}
}
else
throw invalid_argument("Resource is null.");
}
void do_alpha_with_resource(shared_resource* resource)
{
if (resource)
{
if (resource->status==resource_status::in_use)
cout << _compose_msg_about_resource(resource, "used for <alpha>");
// some code that does <alpha> with resource...
// ...
else
throw runtime_error(_compose_msg_about_resource(resource, "not ready"));
}
else
throw invalid_argument("Resource is null.");
}
void do_beta_with_resource(shared_resource* resource)
{
if (resource)
{
if (resource->status==resource_status::in_use)
{
cout << _compose_msg_about_resource(resource, "used for <beta>");
// some code that does <beta> with resource...
// ...
cout << _compose_msg_about_resource(resource, "... oops! Something's wrong. An exception must be issued");
throw runtime_error(_compose_msg_about_resource(resource, "error while doing <beta>"));
}
else
throw runtime_error(_compose_msg_about_resource(resource, "not ready"));
}
else
throw invalid_argument("Resource is null.");
}
string _compose_msg_about_resource(shared_resource* resource, const char* msg)
{
stringstream ss;
if (resource)
ss << "Resource " << resource->id << " " << string(msg) << "." << endl;
return ss.str();
}
About the Author
Diego Dagum is a software architect and developer with more than 20 years of experience. He can be reached at [email protected].