A Handle is basically a container to store a pointer to some data and a user counter. The
user counter counts how many handles point to the same memory area. This allows the
memory area to be cleanly destroyed when the last handle pointing to it is destroyed (last
one to leave the room shuts off light).
The Handle class was implemented concurrency resistent. It can be used in
multi-threaded code without special care. The usage counter for example is allocated in
global memory (not on the current stack), thus the handle can be used to share data
among threads with a safe deallocation strategy: the last user deletes the data pointer.
Moreover this user counter is an atomic counter (see Section 7.1), which is thread safe
since all operations are performed atomically.
Handle needs a pointer to some memory area in its constructor. The easiest way to
construct a handle is as follows:
Handle<HDT> handle (new HDT);
Thus the data pointer is created during the construction of the handle. It is however
possible to create the data pointer outside the handle construction, but code gets often
hard to read because of asymetric new-delete pairs.
Synopsis
#include <lyric/Handle.hpp>
template <class HDT>
class Handle
{
public:
~Handle ();
Handle (HDT* data);
Handle (const Handle& handle);
Handle& operator = (const Handle& handle);
HDT* operator -> ();
HDT* operator -> () const;
HDT* dataptr () const;
};
Description
-
˜Handle () -
Destroys this handle, releasing resources as needed. If the data area pointer
stored in this handle is the last to point on the location, this data area is
returned to the system. The delete operator is applied on the data pointer.
-
Handle (HDT* data) -
Constructs this handle to be a pointer on the memory area given by data.
The data area usage counter is set to one.
The safest is to allocate the data area directly in the construction of this
handle with:
Handle<HDT> handle (new HDT);
-
Handle (const Handle& handle) -
Constructs this handle by cloning the given handle. At the end this handle
stores the pointer to the same data area as the given handle, and the users
count is increased (this handle and handle point to the same memory area,
sharing it).
-
Handle& operator = (const Handle& handle) -
Assigns handle to this handle, and returns a reference to this handle
for assignment chaining. Before the assignation this handle’s users count is
decreased and if this handle was the last user of the data area, the later
is properly destroyed. The the actuall assignment, cloning handle into this
handle takes place. At the end this handle stores the pointer to the same data
area as the given handle, and the users count is increased (this handle and
handle point to the same memory area, sharing it).
-
HDT* operator -> () -
Returns the pointer to the data area pointed to by this handle. If HDT is a
class or structure, all public members are accessible through the -> operator
as if this handle was a pointer to the structure or class.
-
HDT* operator -> () const -
Returns the pointer to the data area pointed to by this handle. If HDT is a
class or structure, all public members are accessible through the -> operator
as if this handle was a pointer to the structure or class.
-
HDT* dataptr () const -
Returns the pointer to the data area pointed to by this handle. This gives
direct access to the data pointed by the address stored in this handle.