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@diegodagum.com.