Showing posts with label Execute Around Sequence. Show all posts
Showing posts with label Execute Around Sequence. Show all posts

Tuesday, July 17, 2012

"Execute Around Sequence", C++ Pattern

For clearing the need for this pattern, I start this post with a problem statement.
Problem:
"suppose that we have a pair of actions that surrounds a sequence of  statements and we need abstract that actions around the statements and have a error prone and exception safe code".
Let's start with a sample code snippet :
void F()
{
  |----------------------------------------------------------------------------------------------------------|
  |1. block of code which acquires lock, memory or other resources and some other statements |
  |----------------------------------------------------------------------------------------------------------|
  
  |----------------------------------------------------------------------------------------------------|
  |--2. ---- Sequences of statements                                                     |
  |----------------------------------------------------------------------------------------------------|

  |---------------------------------------------------------------------------------------------------------|
   |3. block of code which release lock, memory or other resources and some other statements |
  |---------------------------------------------------------------------------------------------------------|


}
    ---------------- Code 1 -----------------------
What happens in "Code 1" if an exception occur in block 2?. Answer is easy; block 3 won't run! So acquired lock will not be unlocked and other threads will waiting for unlock forever, allocated memory in part 1 won't be freed and all resources acquired in part1 won't be released.
Solution:
Initial solution which may bloom in your mind may be following strategy :

void F()
{
  |----------------------------------------------------------------------------------------------------------|

  |1. block of code which acquires lock, memory or other resources and some other statements |
  |----------------------------------------------------------------------------------------------------------|
   try

{
  |----------------------------------------------------------------------------------------------------|
  |--2. ---- Sequences of statements                                                     |
  |----------------------------------------------------------------------------------------------------|
} catch(...)
{
  throw ;
}
finally
{
  |---------------------------------------------------------------------------------------------------------|

   |3. block of code which release lock, memory or other resources and some other statements |
  |---------------------------------------------------------------------------------------------------------|

}
}

    ---------------- Code 2-----------------------
But as you know, C++ doesn't have finally statement in exception handling. So we have to change the code as following :


void F()
{
  |----------------------------------------------------------------------------------------------------------|
  |1. block of code which acquires lock, memory or other resources and some other statements |
  |----------------------------------------------------------------------------------------------------------|
   try
{

  |----------------------------------------------------------------------------------------------------|
  |--2. ---- Sequences of statements                                                     |
  |----------------------------------------------------------------------------------------------------|

} catch(...)
{
  |---------------------------------------------------------------------------------------------------------|

   |3. block of code which release lock, memory or other resources and some other statements |
  |---------------------------------------------------------------------------------------------------------|

  throw ;
}

  |---------------------------------------------------------------------------------------------------------|
   |3'. block of code which release lock, memory or other resources and some other statements |
  |---------------------------------------------------------------------------------------------------------|

}

    ---------------- Code 3-----------------------
Code 3 is an acceptable solution but how about the case you are not allowed to use try/catch ?
Considering this fact that destructor of C++ class will run automatically if object goes out of scope, guides us to write a class and put "block 1" of Code 1 into a constructor of class and "block 3" of Code 1 into destructor of that class. This way helps us to achieve an exception safe code which is named executive around sequence :

class scoped_resource_manager
{
public:
  scoped_resource_manager(resource_related_parameters)
{
     block 1 : acquires lock,allocate memory, open connections ....
}
~scoped_resource_manager()
{
     block 3 :  release lock, free memory , close  connection ...
}

}

void F()
{
 scoped_resource_manager resource_manager(resource_related_parameters);
  |----------------------------------------------------------------------------------------------------|

  |--2. ---- Sequences of statements                                                     |
  |----------------------------------------------------------------------------------------------------|

}

    ---------------- Code 4-----------------------
In Code 4, we are not worry if exception occurs in block 2 or not; all allocated resources will be released  when function returns or execution steps out of it's scope because of automatically running  of scoped_resource_manager class destructor.!

Thanks for C++ class destructors.
"Finally" here is a simple real world code sample for you :
 class ScopedConnection
{
 private :
  BaseDBProvider *mDB;
 public:
  ScopedConnection(BaseDBProvider *pDB)
  {
   mDB=pDB;
   mDB->Open();
                       mDB->StartTransaction();
                }
  ~ScopedConnection()
  {
                        mDB->DetachTransaction();
                  mDB->Close();
  }
};
void F()
{
 BaseDBProvider *bdp=DBFactory::GetDBProvider();
 ScopedConnection scoped_con(bdp);
 DBDataReader *dr;
 dr=bdp->ExcecuteReader(dbs);
 while(dr->ReadNext())
  ret->push_back(Load(dr));
 return ret;
}

scoped_ptr<T> and scoped_lock ( from boost library ) are also implemented to help us in such problems.

Showing posts with label Execute Around Sequence. Show all posts
Showing posts with label Execute Around Sequence. Show all posts

Tuesday, July 17, 2012

"Execute Around Sequence", C++ Pattern

For clearing the need for this pattern, I start this post with a problem statement.
Problem:
"suppose that we have a pair of actions that surrounds a sequence of  statements and we need abstract that actions around the statements and have a error prone and exception safe code".
Let's start with a sample code snippet :
void F()
{
  |----------------------------------------------------------------------------------------------------------|
  |1. block of code which acquires lock, memory or other resources and some other statements |
  |----------------------------------------------------------------------------------------------------------|
  
  |----------------------------------------------------------------------------------------------------|
  |--2. ---- Sequences of statements                                                     |
  |----------------------------------------------------------------------------------------------------|

  |---------------------------------------------------------------------------------------------------------|
   |3. block of code which release lock, memory or other resources and some other statements |
  |---------------------------------------------------------------------------------------------------------|


}
    ---------------- Code 1 -----------------------
What happens in "Code 1" if an exception occur in block 2?. Answer is easy; block 3 won't run! So acquired lock will not be unlocked and other threads will waiting for unlock forever, allocated memory in part 1 won't be freed and all resources acquired in part1 won't be released.
Solution:
Initial solution which may bloom in your mind may be following strategy :

void F()
{
  |----------------------------------------------------------------------------------------------------------|

  |1. block of code which acquires lock, memory or other resources and some other statements |
  |----------------------------------------------------------------------------------------------------------|
   try

{
  |----------------------------------------------------------------------------------------------------|
  |--2. ---- Sequences of statements                                                     |
  |----------------------------------------------------------------------------------------------------|
} catch(...)
{
  throw ;
}
finally
{
  |---------------------------------------------------------------------------------------------------------|

   |3. block of code which release lock, memory or other resources and some other statements |
  |---------------------------------------------------------------------------------------------------------|

}
}

    ---------------- Code 2-----------------------
But as you know, C++ doesn't have finally statement in exception handling. So we have to change the code as following :


void F()
{
  |----------------------------------------------------------------------------------------------------------|
  |1. block of code which acquires lock, memory or other resources and some other statements |
  |----------------------------------------------------------------------------------------------------------|
   try
{

  |----------------------------------------------------------------------------------------------------|
  |--2. ---- Sequences of statements                                                     |
  |----------------------------------------------------------------------------------------------------|

} catch(...)
{
  |---------------------------------------------------------------------------------------------------------|

   |3. block of code which release lock, memory or other resources and some other statements |
  |---------------------------------------------------------------------------------------------------------|

  throw ;
}

  |---------------------------------------------------------------------------------------------------------|
   |3'. block of code which release lock, memory or other resources and some other statements |
  |---------------------------------------------------------------------------------------------------------|

}

    ---------------- Code 3-----------------------
Code 3 is an acceptable solution but how about the case you are not allowed to use try/catch ?
Considering this fact that destructor of C++ class will run automatically if object goes out of scope, guides us to write a class and put "block 1" of Code 1 into a constructor of class and "block 3" of Code 1 into destructor of that class. This way helps us to achieve an exception safe code which is named executive around sequence :

class scoped_resource_manager
{
public:
  scoped_resource_manager(resource_related_parameters)
{
     block 1 : acquires lock,allocate memory, open connections ....
}
~scoped_resource_manager()
{
     block 3 :  release lock, free memory , close  connection ...
}

}

void F()
{
 scoped_resource_manager resource_manager(resource_related_parameters);
  |----------------------------------------------------------------------------------------------------|

  |--2. ---- Sequences of statements                                                     |
  |----------------------------------------------------------------------------------------------------|

}

    ---------------- Code 4-----------------------
In Code 4, we are not worry if exception occurs in block 2 or not; all allocated resources will be released  when function returns or execution steps out of it's scope because of automatically running  of scoped_resource_manager class destructor.!

Thanks for C++ class destructors.
"Finally" here is a simple real world code sample for you :
 class ScopedConnection
{
 private :
  BaseDBProvider *mDB;
 public:
  ScopedConnection(BaseDBProvider *pDB)
  {
   mDB=pDB;
   mDB->Open();
                       mDB->StartTransaction();
                }
  ~ScopedConnection()
  {
                        mDB->DetachTransaction();
                  mDB->Close();
  }
};
void F()
{
 BaseDBProvider *bdp=DBFactory::GetDBProvider();
 ScopedConnection scoped_con(bdp);
 DBDataReader *dr;
 dr=bdp->ExcecuteReader(dbs);
 while(dr->ReadNext())
  ret->push_back(Load(dr));
 return ret;
}

scoped_ptr<T> and scoped_lock ( from boost library ) are also implemented to help us in such problems.