121 lines
4.1 KiB
C
121 lines
4.1 KiB
C
#pragma once
|
|
/*
|
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
|
*
|
|
* Use of this software is governed by the Business Source License included
|
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
|
*
|
|
* Change Date: 2019-07-01
|
|
*
|
|
* On the date above, in accordance with the Business Source License, use
|
|
* of this software will be governed by version 2 or later of the General
|
|
* Public License.
|
|
*/
|
|
|
|
/**
|
|
* @file listmanager.h The List Manager header file
|
|
*
|
|
*
|
|
* @verbatim
|
|
* Revision History
|
|
*
|
|
* Date Who Description
|
|
* 20/04/2016 Martin Brampton Initial implementation
|
|
*
|
|
* @endverbatim
|
|
*/
|
|
|
|
#include <maxscale/cdefs.h>
|
|
#include <maxscale/spinlock.h>
|
|
#include <maxscale/debug.h>
|
|
|
|
MXS_BEGIN_DECLS
|
|
|
|
struct dcb;
|
|
|
|
/*
|
|
* The possible types of list that could be supported. At present, only
|
|
* LIST_TYPE_RECYCLABLE is fully tested.
|
|
*/
|
|
typedef enum
|
|
{
|
|
LIST_TYPE_SIMPLE, /* A simple linked list with pointer to last entry */
|
|
LIST_TYPE_RECYCLABLE, /* A simple linked list, entries are recycled */
|
|
LIST_TYPE_DOUBLE, /* A doubly linked list, next and previous */
|
|
} list_type_t;
|
|
|
|
/*
|
|
* The list entry structure
|
|
*
|
|
* Each list entry must have this format, but will typically be extended
|
|
* well beyond these items. The "previous" field is only required for
|
|
* a doubly linked list, LIST_TYPE_DOUBLE.
|
|
*
|
|
* The first data to be used with the list manager is the DCB. Note that
|
|
* the first few fields in the DCB structure correspond exactly to the
|
|
* fields in the list entry structure. The pointers used need to be cast
|
|
* as appropriate in order to be able to use the same data as either a DCB
|
|
* or a list entry.
|
|
*
|
|
*/
|
|
#define LIST_ENTRY_FIELDS \
|
|
skygw_chk_t list_entry_chk_top; \
|
|
struct list_entry *next; \
|
|
struct list_entry *previous; \
|
|
bool entry_is_in_use; \
|
|
bool entry_is_ready; \
|
|
skygw_chk_t list_entry_chk_tail;
|
|
|
|
typedef struct list_entry
|
|
{
|
|
LIST_ENTRY_FIELDS
|
|
} list_entry_t;
|
|
|
|
/*
|
|
* The list configuration structure
|
|
*
|
|
* This provides the basis for a list. It can be declared and initialised
|
|
* statically, for example in server/core/dcb.c. It includes an anchor
|
|
* pointer for the list, a pointer to the last entry in the list and the
|
|
* last entry that was found to be free and reused.
|
|
*
|
|
* The count tells us the current number of entries in live use, and maximum
|
|
* is the highest number ever observed in live use. The freecount is the
|
|
* number of entries currently free and ready for reuse. The entry_size is
|
|
* the actual size of the real entries, e.g. the DCB structure (NOT the size
|
|
* of the list entry structure).
|
|
*
|
|
* A spinlock is declared for use during list manipulation operations.
|
|
*/
|
|
typedef struct
|
|
{
|
|
list_type_t list_type;
|
|
size_t entry_size;
|
|
SPINLOCK list_lock;
|
|
list_entry_t *all_entries;
|
|
list_entry_t *last_entry;
|
|
list_entry_t *last_free;
|
|
int count;
|
|
int maximum;
|
|
int freecount;
|
|
int num_malloc;
|
|
} LIST_CONFIG;
|
|
|
|
void list_initialise(LIST_CONFIG *list_config, list_type_t type_of_list, size_t entry_size);
|
|
bool list_pre_alloc(LIST_CONFIG *list_config, int num_entries, void (*init_struct)(void *));
|
|
list_entry_t *list_find_free(LIST_CONFIG *list_config, void (*init_struct)(void *));
|
|
void dprintListStats(struct dcb *pdcb, LIST_CONFIG *list_config, const char *listname);
|
|
void list_free_entry (LIST_CONFIG *list_config, list_entry_t *to_be_freed);
|
|
list_entry_t *list_start_iteration(LIST_CONFIG *list_config);
|
|
list_entry_t *list_iterate(LIST_CONFIG *list_config, list_entry_t *current_entry);
|
|
void list_terminate_iteration_early(LIST_CONFIG *list_config, list_entry_t *current_entry);
|
|
bool list_is_entry_in_use(LIST_CONFIG *list_config, list_entry_t *to_be_found);
|
|
void list_add_to_end(LIST_CONFIG *list_config, list_entry_t *new_entry);
|
|
void list_map(LIST_CONFIG *list_config, bool (*callback)(void *, ...));
|
|
|
|
/* The following UNTESTED! */
|
|
list_entry_t *list_remove_first(LIST_CONFIG *list_config);
|
|
list_entry_t *list_remove_last(LIST_CONFIG *list_config);
|
|
|
|
MXS_END_DECLS
|