51Degrees Device Detection C/C++  4.1

A device detection library that is used natively or by 51Degrees products

Pool

Detailed Description

Pool of handles to allow safe access to multiple threads.

Introduction

A Pool structure defines a pool of handles to a resource, and allows a safe way to access them in a multi-threaded environment.

Creation

The fiftyoneDegreesPoolInit method is used to initialise a pointer to a fiftyoneDegreesPool. A concurrency value is provided to indicate the maximum number of threads that will be in operation. If this value is lower than the actual number of threads the stack can be exhausted and a null pointer is returned instead of a valid item. The concurrency value must always be the same or greater than the number of threads. When compiled in single threaded operation a pool is not strictly required and the implementation maintains a simple stack for consistency of interface and to minimise divergent code.

Get & Release

Handles are retrieved from the pool via the fiftyoneDegreesPoolItemGet method. The handle MUST be returned with the fiftyoneDegreesPoolItemRelease method when it is finished with. The handle will always be open and ready for read only operation. If too many threads are accessing the pool simultaneously, meaning a handle cannot be secured, then a NULL pointer is returned.

Free

The items are closed when the pool is released via the fiftyoneDegreesPoolFree method. Any memory allocated by the implementation for the stack is freed.

Usage Example

void *state;
// Initialise a pool of resources and check that it was successful
&pool,
1,
state,
resourceCreate,
resourceFree,
exception) != NULL) {
// Get a resource from the pool
&pool,
exception);
// Check that there was a resource available
if (item != NULL) {
// Do something with the resource without being interrupted by other
// threads
// ...
// Release the resource back to the pool
}
// Free the pool of resources
}

Design

To improve performance in multi-threaded operation a non locking stack is used where a Compare and Swap (CAS) atomic operation is used to pop and push handles on and off the stack. The design was adapted from the following article (http://nullprogram.com/blog/2014/09/02/) which explains some of the challenges involved including the ABA problem (https://en.wikipedia.org/wiki/ABA_problem). It is for this reason the head structure is implemented as a union between the values and the exchange integer. Pointers are not used as the address space for the stack is continuous and always very small compared to the total addressable memory space.

Collaboration diagram for Pool:

Structs

struct  fiftyoneDegreesPoolItem
Pool item node in the stack of items. More...
union  fiftyoneDegreesPoolHead
The head of the stack used for pop and push operations. More...
struct  fiftyoneDegreesPool
Pool of resources stored as items in a stack. More...

Typedefs

typedef void *(*  fiftyoneDegreesPoolResourceCreate) (fiftyoneDegreesPool *pool, void *state, fiftyoneDegreesException *exception)
Used to create a new resource for use in the pool. More...
typedef size_t(*  fiftyoneDegreesPoolResourceSize) (void *state)
Used to determine the additional size beyond the pointer used for each resource added to the pool. More...
typedef void(*  fiftyoneDegreesPoolResourceFree) (fiftyoneDegreesPool *pool, void *resource)
Frees a resource previously created with fiftyoneDegreesPoolResourceCreate. More...

Functions

fiftyoneDegreesPool *  fiftyoneDegreesPoolInit (fiftyoneDegreesPool *pool, uint16_t concurrency, void *state, fiftyoneDegreesPoolResourceCreate resourceCreate, fiftyoneDegreesPoolResourceFree resourceFree, fiftyoneDegreesException *exception)
Initialises a pool data structure to support the number of concurrent requests that can be made to the pool for resources that can be reused. More...
fiftyoneDegreesPoolItem *  fiftyoneDegreesPoolItemGet (fiftyoneDegreesPool *pool, fiftyoneDegreesException *exception)
Gets the next free item from the pool for exclusive use by the caller. More...
void  fiftyoneDegreesPoolItemRelease (fiftyoneDegreesPoolItem *item)
Releases the item back to the pool it belongs ready to be reused by another operation. More...
void  fiftyoneDegreesPoolFree (fiftyoneDegreesPool *pool)
Releases the items used by the pool freeing the resources used by each item by calling the resourceFree method provided when the pool was created. More...
void  fiftyoneDegreesPoolReset (fiftyoneDegreesPool *pool)
Resets the pool without releasing any resources. More...

Typedef Documentation

◆ fiftyoneDegreesPoolResourceCreate

typedef void*(* fiftyoneDegreesPoolResourceCreate) (fiftyoneDegreesPool *pool, void *state, fiftyoneDegreesException *exception)

Used to create a new resource for use in the pool.

Parameters
pool - to create the resource for
state - pointer to data used by the method
exception - pointer to an exception data structure to be used if an exception occurs. See exceptions.h
Returns
pointer to the new resource

◆ fiftyoneDegreesPoolResourceSize

typedef size_t(* fiftyoneDegreesPoolResourceSize) (void *state)

Used to determine the additional size beyond the pointer used for each resource added to the pool.

Parameters
state - pointer to a state containing the resource and any additional data needed for the calculation
Returns
addition size to allocate per resource

Function Documentation

◆ fiftyoneDegreesPoolFree()

void fiftyoneDegreesPoolFree ( fiftyoneDegreesPool *   pool )

Releases the items used by the pool freeing the resources used by each item by calling the resourceFree method provided when the pool was created.

Parameters
pool - to be freed

◆ fiftyoneDegreesPoolInit()

fiftyoneDegreesPool* fiftyoneDegreesPoolInit ( fiftyoneDegreesPool *   pool,
uint16_t   concurrency,
void *   state,
fiftyoneDegreesPoolResourceCreate   resourceCreate,
fiftyoneDegreesPoolResourceFree   resourceFree,
fiftyoneDegreesException *   exception  
)

Initialises a pool data structure to support the number of concurrent requests that can be made to the pool for resources that can be reused.

The resourceCreate method is used to create a new resource for use in the pool which will be freed during when the release method is called on the pool using the resourceFree method.

Parameters
pool - data structure to be initialised.
concurrency - the number of resources the pool should contain.
state - passed to the create resource method.
resourceCreate - method used to create the resource to be added to items in the pool.
resourceFree - method used to free a resource from the pool when the pool is freed.
exception - pointer to an exception data structure to be used if an exception occurs. See exceptions.h.
Returns
a pointer to the pool if successful, otherwise NULL.

◆ fiftyoneDegreesPoolItemGet()

fiftyoneDegreesPoolItem* fiftyoneDegreesPoolItemGet ( fiftyoneDegreesPool *   pool,
fiftyoneDegreesException *   exception  
)

Gets the next free item from the pool for exclusive use by the caller.

Every item returned must be released when the caller has finished with it using the fiftyoneDegreesPoolItemRelease method.

Parameters
pool - to return items from.
exception - pointer to an exception data structure to be used if an exception occurs. See exceptions.h.
Returns
the next free item, or NULL if no items are available.

◆ fiftyoneDegreesPoolItemRelease()

void fiftyoneDegreesPoolItemRelease ( fiftyoneDegreesPoolItem *   item )

Releases the item back to the pool it belongs ready to be reused by another operation.

Parameters
item - to be released back to the pool

◆ fiftyoneDegreesPoolReset()

void fiftyoneDegreesPoolReset ( fiftyoneDegreesPool *   pool )

Resets the pool without releasing any resources.

Parameters
pool - to be reset
On This Page