Storing Data in iClient

After much deliberation, we have decided to include a method with which to store a data element in an iClient instance. This has been requested many times by users of gnuworld, and we believe we have finally developed a simple and efficient mechanism to accomplish this goal.

Introduction

Each xClient may store at most one data element into each iClient. The data element is stored as a pointer to void (void*). This means that an xClient may store any type of data it wishes into an iClient. This data is referred to as customData.

Note: Because custom data elements are stored into iClient's by pointer, each of these data elements must be persistent throughout the life of the xClient to which it belongs. The most usual method for this is by allocating the data element on the heap.

The key used to store and retrieve these data elements is a pointer to the xClient in question. At most one data element per iClient may be stored by an xClient.

 

Adding custom data elements to an iClient

The following method is used to insert a custom data element into an iClient:

bool iClient::setCustomData( xClient*, void* )

The first argument is a pointer to the xClient which is requesting the custom data storage. This argument must NOT be NULL. The second argument is a pointer to the custom data which is being stored. This variable may point to NULL.

The method returns true if the addition succeeded, false otherwise. Reasons for failure include:

Important: Do NOT attempt to use a false xClient pointer to add a custom data element into the iClient. This will cause the system to crash if that iClient quits from the network (including a net split). The reason for this is described below, in the section on safe deallocation.

Removing custom data elements from an iClient

This method is used to remove a previously inserted data element from the iClient:

void* iClient::removeCustomData( xClient* )
 

The method argument is a pointer to the xClient which owns the custom data element to be returned. This pointer is used as a key to find the correct data element.

If the data element for the given xClient is found, it is removed from the iClient's internal table, and a pointer to that data element is returned. If the data element is not found, then NULL is returned.

Important: The xClient argument to this method must NOT be NULL.

Retrieving custom data elements from an iClient

The following method may be used to retrieve a custom data element from an iClient:

void* iClient::getCustomData( xClient* ) const

The method argument of type xClient is used as a key to find the custom data element in question. Only the data element for the owning xClient may be retrieved.

If the data element for the given xClient is found, then it is returned. Otherwise, NULL is returned.

Note that this method is const. This means that it may operate on an iClient instance declared as const.

Important: The xClient argument to this method must NOT be NULL.

Safe Deallocation

In order to prevent memory leaks, a deallocation mechanism has been installed into the iClient/xClient custom data system. This is primarily because xClients are not notified of individual iClient quits when a netsplit occurs.

For this reason, whenever an iClient quits from the network, for whatever reason, it calls a safe custom data deallocation method on each xClient which is storing an element inside of it. This makes life much simpler for the xClient, because it doesn't have to attempt to figure out which clients are quitting during a netsplit; the iClient will request a safe deallocation from the xClient.

This is done via a method in the xClient class. Any xClient subclasses which use custom data elements in iClients MUST overload this method to prevent memory leaks.

void xClient::deleteCustomData( iClient*, void* )

This method is called on any xClient which is storing a custom data element inside of the given iClient (argument 1). The second argument is the custom data element in question.

Important: Do NOT attempt to call iClient::removeCustomData on the iClient passed as first argument. This because the iClient is in the process of deallocation, and the deleteCustomData() method is actually being called during the iClient's destructor. Calling any methods on the iClient would be unsafe.

This is also the reason that false xClient pointers MUST NOT be used to facilitate additional custom data storage in an iClient (in that case, pass a structure of data). An iClient may quit at any time, and sometimes without the knowledge of an xClient. When an iClient does quit, it will attempt to call the deleteCustomData method of every xClient storing data inside of it. If a false xClient pointer is passed, the iClient will attempt to invoke that method on invalid data, and crash the system.