Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/tl/refnode.h File Reference

Reference counting template; can be used to turn any class into ref counting resources. More...

#include <lib/sconfig.h>
#include <lib/threads/atomic.h>

Include dependency graph for refnode.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Classes

struct  _RefNode_VoidNSPC
 Internally used by RefNode template:. More...

class  InternalRefNodeBase
 FIXME This is the base class for the internally used (unique resource) class. This version is not thread-safe at all. More...

class  InternalRefNodeBase_ThreadSave
 This is the base class for the internally used (unique resource) class. This version is thread-safe. More...

class  RefNode
 This is the reference counting C++-safe type for the user. More...


Defines

#define _TemplateLibrary_RefNode_H_   1


Detailed Description

Reference counting template; can be used to turn any class into ref counting resources.

Author:
Wolfgang Wieser ] wwieser (a) gmx <*> de [

HOW IT IS MEANT TO WORK

You have some resource which needs to be shared using reference counting. Then, put this into the "internal class" which you derive from InternalRefNodeBase (which will add an integer for reference counting as the only overhead). Let's say the shared resource is

   class _IBuffer : InternalRefNodeBase
   {
       char *allocated;
       size_t size;
       public:
           int BoFoo(char *x,int y);
           int pubval;
         ...
   };

Now, we need to create such an object once and want to have it shared:

   _IBuffer *internal_b=new _IBuffer(...);
   RefNode<_IBuffer> b(internal_b);

Now, we can savely go on using the RefNode<_IBuffer>:

   RefNode<_IBuffer> c=b;

In order to avoid all that template typing, I recommend to use a typedef:

   typedef RefNode<_IBuffer> Buffer;

Access to all elements in the internal ref node can easily be obtained through the overloaded operator->():

   c->BoFoo("hello",5);
   c->pubval=123;
   (*c).foo();

Of course, you should never delete the internal class directly. It will delete itself automatically once all references to it are deleted, i.e. the reference counter gets zero.

There is a second parameter type in the RefNode template: NSPC. This can be used to include a namespace class. For example one might have the following class:

   class _IBuffer : InternalRefNodeBase
   {
       public: enum Flags { UseMMap, UseMalloc };
       private:
           char *allocated;
           // etc... (see above)
   };

In this case, one would of course like to be able to write

   Buffer::Flags f=Buffer::UseMMap; 
instead of the "internal"
   _IBuffer::Flags f=_IBuffer::UseMMap; 

To easily solve this problem, put the enum into a "namespace class" and use it as second argument to the RefNode template:

   class _IBufferNamespace
   {
       public: enum Flags { UseMMap, UseMalloc };
   };
   class _IBuffer : InternalRefNodeBase, public _IBufferNamespace
   {
       char *allocated;
       // etc... (see above)
   };
   typedef RefNode<_IBuffer,_IBufferNamespace> Buffer;
   
   // And now we can use: 
   Buffer::Flags = Buffer::UseMMap;

Note:
Reference counting is an easy way to control the life of an object. But it is unable to detect cyclic loops of unreferenced objects. E.g. A holds a reference of B and B holds a reference of A but nobody else holds a reference to neither A nor B, these objects should get deleted but will NOT. If such cases can happen in your program, you may not use reference counting but some more advanced garbage collection algorithm.
Attention:
In order to gracefully deal with NULL refs, the public methods of the internal class should check for NULL refs by checking if the "this" pointer is NULL, e.g.
   class _IBuffer : InternalRefNodeBase
   {
       private:
           size_t len;
       public:
           ssize_t length()
               {  return(this ? len : -1);  }
   };

THREADS:

Definition in file refnode.h.


Define Documentation

#define _TemplateLibrary_RefNode_H_   1
 

Definition at line 19 of file refnode.h.


Generated on Sat Feb 19 22:34:51 2005 for Ray by doxygen 1.3.5