Make mlist a separate component.

Mlist is now made available as a separate component instead of
being a part of skygw_utils.
This commit is contained in:
Johan Wikman 2016-02-09 17:31:15 +02:00
parent eaddc4ea9d
commit 38db155fef
6 changed files with 508 additions and 470 deletions

View File

@ -1,4 +1,4 @@
add_library(maxscale-common SHARED adminusers.c atomic.c buffer.c config.c dbusers.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c modutil.c monitor.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c slist.c spinlock.c thread.c users.c utils.c ${CMAKE_SOURCE_DIR}/utils/skygw_utils.cc statistics.c)
add_library(maxscale-common SHARED adminusers.c atomic.c buffer.c config.c dbusers.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c mlist.c modutil.c monitor.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c slist.c spinlock.c thread.c users.c utils.c ${CMAKE_SOURCE_DIR}/utils/skygw_utils.cc statistics.c)
target_link_libraries(maxscale-common ${MARIADB_CONNECTOR_LIBRARIES} ${LZMA_LINK_FLAGS} ${PCRE2_LIBRARIES} ${CURL_LIBRARIES} ssl aio pthread crypt dl crypto inih z rt m stdc++)

View File

@ -28,6 +28,7 @@
#include <syslog.h>
#include <atomic.h>
#include <mlist.h>
#include <skygw_debug.h>
#include <skygw_types.h>
#include <skygw_utils.h>

421
server/core/mlist.c Normal file
View File

@ -0,0 +1,421 @@
/*
* This file is distributed as part of the MariaDB Corporation MaxScale. It is free
* software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation,
* version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright MariaDB Corporation Ab 2013-2014
*/
#include <mlist.h>
static void mlist_free_memory(mlist_t* ml, char* name);
static mlist_node_t* mlist_node_init(void* data, mlist_cursor_t* cursor);
//static mlist_node_t* mlist_node_get_next(mlist_node_t* curr_node);
//static mlist_node_t* mlist_get_first(mlist_t* list);
//static mlist_cursor_t* mlist_get_cursor(mlist_t* list);
/**
* @node Cut off nodes of the list.
*
* Parameters:
* @param ml - <usage>
* <description>
*
* @return Pointer to the first of the detached nodes.
*
*
* @details (write detailed description here)
*
*/
mlist_node_t* mlist_detach_nodes(mlist_t* ml)
{
mlist_node_t* node;
CHK_MLIST(ml);
node = ml->mlist_first;
ml->mlist_first = NULL;
ml->mlist_last = NULL;
ml->mlist_nodecount = 0;
return node;
}
/**
* @node Create a list with rwlock and optional read-only cursor
*
* Parameters:
* @param listp - <usage>
* <description>
*
* @param cursor - <usage>
* <description>
*
* @param name - <usage>
* <description>
*
* @return Address of mlist_t struct.
*
*
* @details Cursor must protect its reads with read lock, and after
* acquiring read lock reader must check whether the list is deleted
* (mlist_deleted).
*
*/
mlist_t* mlist_init(mlist_t* listp, mlist_cursor_t** cursor, char* name,
void (*datadel)(void*), int maxnodes)
{
mlist_cursor_t* c;
mlist_t* list;
if (cursor != NULL)
{
ss_dassert(*cursor == NULL);
}
/** listp is not NULL if caller wants flat list */
if (listp == NULL)
{
list = (mlist_t*) calloc(1, sizeof (mlist_t));
}
else
{
/** Caller wants list flat, memory won't be freed */
list = listp;
list->mlist_flat = true;
}
ss_dassert(list != NULL);
if (list == NULL)
{
fprintf(stderr, "* Allocating memory for mlist failed\n");
mlist_free_memory(list, name);
goto return_list;
}
list->mlist_chk_top = CHK_NUM_MLIST;
list->mlist_chk_tail = CHK_NUM_MLIST;
/** Set size limit for list. 0 means unlimited */
list->mlist_nodecount_max = maxnodes;
/** Set data deletion callback fun */
list->mlist_datadel = datadel;
if (name != NULL)
{
list->mlist_name = name;
}
/** Create mutex, return NULL if fails. */
if (simple_mutex_init(&list->mlist_mutex, "writebuf mutex") == NULL)
{
ss_dfprintf(stderr, "* Creating rwlock for mlist failed\n");
mlist_free_memory(list, name);
list = NULL;
goto return_list;
}
/** Create cursor for reading the list */
if (cursor != NULL)
{
c = mlist_cursor_init(list);
if (c == NULL)
{
simple_mutex_done(&list->mlist_mutex);
mlist_free_memory(list, name);
list = NULL;
goto return_list;
}
CHK_MLIST_CURSOR(c);
*cursor = c;
}
list->mlist_versno = 2; /*< vresno != 0 means that list is initialized */
CHK_MLIST(list);
return_list:
return list;
}
/**
* @node Free mlist memory allocations. name must be explicitly
* set if mlist has one.
*
* Parameters:
* @param ml - <usage>
* <description>
*
* @param name - <usage>
* <description>
*
* @return void
*
*
* @details (write detailed description here)
*
*/
static void mlist_free_memory(mlist_t* ml, char* name)
{
mlist_node_t* node;
/** name */
if (name != NULL)
{
free(name);
}
if (ml != NULL)
{
/** list data */
while (ml->mlist_first != NULL)
{
/** Scan list and free nodes and data inside nodes */
node = ml->mlist_first->mlnode_next;
mlist_node_done(ml->mlist_first);
ml->mlist_first = node;
}
/** list structure */
if (!ml->mlist_flat)
{
free(ml);
}
}
}
void* mlist_node_get_data(mlist_node_t* node)
{
CHK_MLIST_NODE(node);
return node->mlnode_data;
}
void mlist_node_done(mlist_node_t* n)
{
CHK_MLIST_NODE(n);
if (n->mlnode_data != NULL)
{
if (n->mlnode_list->mlist_datadel != NULL)
{
(n->mlnode_list->mlist_datadel(n->mlnode_data));
}
free(n->mlnode_data);
}
free(n);
}
/**
* @node Mark list as deleted and free the memory.
*
* Parameters:
* @param list - <usage>
* <description>
*
* @return void
*
*
* @details (write detailed description here)
*
*/
void mlist_done(mlist_t* list)
{
CHK_MLIST(list);
simple_mutex_lock(&list->mlist_mutex, true);
list->mlist_deleted = true;
simple_mutex_unlock(&list->mlist_mutex);
simple_mutex_done(&list->mlist_mutex);
mlist_free_memory(list, list->mlist_name);
}
/**
* @node Adds data to list by allocating node for it. Checks list size limit.
*
* Parameters:
* @param list - <usage>
* <description>
*
* @param data - <usage>
* <description>
*
* @return true, if succeed, false, if list had node limit and it is full.
*
*
* @details (write detailed description here)
*
*/
bool mlist_add_data_nomutex(mlist_t* list, void* data)
{
bool succp;
succp = mlist_add_node_nomutex(list, mlist_node_init(data, NULL));
return succp;
}
static mlist_node_t* mlist_node_init(void* data, mlist_cursor_t* cursor)
{
mlist_node_t* node;
node = (mlist_node_t*) calloc(1, sizeof (mlist_node_t));
node->mlnode_chk_top = CHK_NUM_MLIST_NODE;
node->mlnode_chk_tail = CHK_NUM_MLIST_NODE;
node->mlnode_data = data;
CHK_MLIST_NODE(node);
if (cursor != NULL)
{
cursor->mlcursor_pos = node;
}
return node;
}
mlist_node_t* mlist_detach_first(mlist_t* ml)
{
mlist_node_t* node;
CHK_MLIST(ml);
node = ml->mlist_first;
CHK_MLIST_NODE(node);
ml->mlist_first = node->mlnode_next;
node->mlnode_next = NULL;
ml->mlist_nodecount -= 1;
if (ml->mlist_nodecount == 0)
{
ml->mlist_last = NULL;
}
else
{
CHK_MLIST_NODE(ml->mlist_first);
}
CHK_MLIST(ml);
return (node);
}
/**
* @node Add new node to end of list if there is space for it.
*
* Parameters:
* @param list - <usage>
* <description>
*
* @param newnode - <usage>
* <description>
*
* @param add_last - <usage>
* <description>
*
* @return true, if succeede, false, if list size limit was exceeded.
*
*
* @details (write detailed description here)
*
*/
bool mlist_add_node_nomutex(mlist_t* list, mlist_node_t* newnode)
{
bool succp = false;
CHK_MLIST(list);
CHK_MLIST_NODE(newnode);
ss_dassert(!list->mlist_deleted);
/** List is full already. */
if (list->mlist_nodecount == list->mlist_nodecount_max)
{
goto return_succp;
}
/** Find location for new node */
if (list->mlist_last != NULL)
{
ss_dassert(!list->mlist_last->mlnode_deleted);
CHK_MLIST_NODE(list->mlist_last);
CHK_MLIST_NODE(list->mlist_first);
ss_dassert(list->mlist_last->mlnode_next == NULL);
list->mlist_last->mlnode_next = newnode;
}
else
{
list->mlist_first = newnode;
}
list->mlist_last = newnode;
newnode->mlnode_list = list;
list->mlist_nodecount += 1;
succp = true;
return_succp:
CHK_MLIST(list);
return succp;
}
/**
* mlist_cursor_t
*/
mlist_cursor_t* mlist_cursor_init(mlist_t* list)
{
CHK_MLIST(list);
mlist_cursor_t* c;
/** acquire shared lock to the list */
simple_mutex_lock(&list->mlist_mutex, true);
c = (mlist_cursor_t *) calloc(1, sizeof (mlist_cursor_t));
if (c == NULL)
{
simple_mutex_unlock(&list->mlist_mutex);
goto return_cursor;
}
c->mlcursor_chk_top = CHK_NUM_MLIST_CURSOR;
c->mlcursor_chk_tail = CHK_NUM_MLIST_CURSOR;
c->mlcursor_list = list;
/** Set cursor position if list is not empty */
if (list->mlist_first != NULL)
{
c->mlcursor_pos = list->mlist_first;
}
simple_mutex_unlock(&list->mlist_mutex);
CHK_MLIST_CURSOR(c);
return_cursor:
return c;
}
void* mlist_cursor_get_data_nomutex(mlist_cursor_t* mc)
{
CHK_MLIST_CURSOR(mc);
return (mc->mlcursor_pos->mlnode_data);
}
bool mlist_cursor_move_to_first(mlist_cursor_t* mc)
{
bool succp = false;
mlist_t* list;
CHK_MLIST_CURSOR(mc);
list = mc->mlcursor_list;
CHK_MLIST(list);
simple_mutex_lock(&list->mlist_mutex, true);
if (mc->mlcursor_list->mlist_deleted)
{
simple_mutex_unlock(&list->mlist_mutex);
return false;
}
/** Set position point to first node */
mc->mlcursor_pos = list->mlist_first;
if (mc->mlcursor_pos != NULL)
{
CHK_MLIST_NODE(mc->mlcursor_pos);
succp = true;
}
simple_mutex_unlock(&list->mlist_mutex);
return succp;
}

84
server/include/mlist.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef _MLIST_H
#define _MLIST_H
/*
* This file is distributed as part of the MariaDB Corporation MaxScale. It is free
* software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation,
* version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright MariaDB Corporation Ab 2016
*/
#include <skygw_utils.h>
EXTERN_C_BLOCK_BEGIN
typedef struct mlist_node_st mlist_node_t;
typedef struct mlist_st
{
skygw_chk_t mlist_chk_top;
char* mlist_name;
void (*mlist_datadel)(void *); /**< clean-up function for data */
simple_mutex_t mlist_mutex; /**< protect node updates and clean-up */
bool mlist_uselock;
bool mlist_islocked;
bool mlist_deleted;
size_t mlist_nodecount;
size_t mlist_nodecount_max; /**< size limit. 0 == no limit */
size_t mlist_versno;
bool mlist_flat;
mlist_node_t* mlist_first;
mlist_node_t* mlist_last;
skygw_chk_t mlist_chk_tail;
} mlist_t;
typedef struct mlist_cursor_st
{
skygw_chk_t mlcursor_chk_top;
mlist_t* mlcursor_list;
mlist_node_t* mlcursor_pos;
pthread_t* mlcursor_owner_thr;
skygw_chk_t mlcursor_chk_tail;
} mlist_cursor_t;
struct mlist_node_st
{
skygw_chk_t mlnode_chk_top;
mlist_t* mlnode_list;
mlist_node_t* mlnode_next;
void* mlnode_data;
bool mlnode_deleted;
skygw_chk_t mlnode_chk_tail;
};
mlist_t* mlist_init(mlist_t* mlist,
mlist_cursor_t** cursor,
char* name,
void (*datadel)(void*),
int maxnodes);
void mlist_done(mlist_t* list);
bool mlist_add_data_nomutex(mlist_t* list, void* data);
bool mlist_add_node_nomutex(mlist_t* list, mlist_node_t* newnode);
mlist_node_t* mlist_detach_first(mlist_t* ml);
mlist_node_t* mlist_detach_nodes(mlist_t* ml);
void* mlist_node_get_data(mlist_node_t* node);
void mlist_node_done(mlist_node_t* n);
mlist_cursor_t* mlist_cursor_init(mlist_t* ml);
void* mlist_cursor_get_data_nomutex(mlist_cursor_t* c);
bool mlist_cursor_move_to_first(mlist_cursor_t* c);
EXTERN_C_BLOCK_END
#endif

View File

@ -37,24 +37,12 @@
#include <random_jkiss.h>
#include <pcre2.h>
#if defined(MLIST)
static mlist_node_t* mlist_node_init(void* data, mlist_cursor_t* cursor);
//static mlist_node_t* mlist_node_get_next(mlist_node_t* curr_node);
//static mlist_node_t* mlist_get_first(mlist_t* list);
//static mlist_cursor_t* mlist_get_cursor(mlist_t* list);
#endif /* MLIST */
static bool file_write_header(skygw_file_t* file);
static void simple_mutex_free_memory(simple_mutex_t* sm);
static void mlist_free_memory(mlist_t* ml, char* name);
static void thread_free_memory(skygw_thread_t* th, char* name);
/** End of static function declarations */
/** mutexed list, mlist */
#if defined(MLIST)
/** mutexed list */
int skygw_rwlock_rdlock(skygw_rwlock_t* rwlock)
{
@ -172,404 +160,6 @@ return_err:
return err;
}
/**
* @node Cut off nodes of the list.
*
* Parameters:
* @param ml - <usage>
* <description>
*
* @return Pointer to the first of the detached nodes.
*
*
* @details (write detailed description here)
*
*/
mlist_node_t* mlist_detach_nodes(mlist_t* ml)
{
mlist_node_t* node;
CHK_MLIST(ml);
node = ml->mlist_first;
ml->mlist_first = NULL;
ml->mlist_last = NULL;
ml->mlist_nodecount = 0;
return node;
}
/**
* @node Create a list with rwlock and optional read-only cursor
*
* Parameters:
* @param listp - <usage>
* <description>
*
* @param cursor - <usage>
* <description>
*
* @param name - <usage>
* <description>
*
* @return Address of mlist_t struct.
*
*
* @details Cursor must protect its reads with read lock, and after
* acquiring read lock reader must check whether the list is deleted
* (mlist_deleted).
*
*/
mlist_t* mlist_init(mlist_t* listp, mlist_cursor_t** cursor, char* name,
void (*datadel)(void*), int maxnodes)
{
mlist_cursor_t* c;
mlist_t* list;
if (cursor != NULL)
{
ss_dassert(*cursor == NULL);
}
/** listp is not NULL if caller wants flat list */
if (listp == NULL)
{
list = (mlist_t*) calloc(1, sizeof (mlist_t));
}
else
{
/** Caller wants list flat, memory won't be freed */
list = listp;
list->mlist_flat = true;
}
ss_dassert(list != NULL);
if (list == NULL)
{
fprintf(stderr, "* Allocating memory for mlist failed\n");
mlist_free_memory(list, name);
goto return_list;
}
list->mlist_chk_top = CHK_NUM_MLIST;
list->mlist_chk_tail = CHK_NUM_MLIST;
/** Set size limit for list. 0 means unlimited */
list->mlist_nodecount_max = maxnodes;
/** Set data deletion callback fun */
list->mlist_datadel = datadel;
if (name != NULL)
{
list->mlist_name = name;
}
/** Create mutex, return NULL if fails. */
if (simple_mutex_init(&list->mlist_mutex, "writebuf mutex") == NULL)
{
ss_dfprintf(stderr, "* Creating rwlock for mlist failed\n");
mlist_free_memory(list, name);
list = NULL;
goto return_list;
}
/** Create cursor for reading the list */
if (cursor != NULL)
{
c = mlist_cursor_init(list);
if (c == NULL)
{
simple_mutex_done(&list->mlist_mutex);
mlist_free_memory(list, name);
list = NULL;
goto return_list;
}
CHK_MLIST_CURSOR(c);
*cursor = c;
}
list->mlist_versno = 2; /*< vresno != 0 means that list is initialized */
CHK_MLIST(list);
return_list:
return list;
}
/**
* @node Free mlist memory allocations. name must be explicitly
* set if mlist has one.
*
* Parameters:
* @param ml - <usage>
* <description>
*
* @param name - <usage>
* <description>
*
* @return void
*
*
* @details (write detailed description here)
*
*/
static void mlist_free_memory(mlist_t* ml, char* name)
{
mlist_node_t* node;
/** name */
if (name != NULL)
{
free(name);
}
if (ml != NULL)
{
/** list data */
while (ml->mlist_first != NULL)
{
/** Scan list and free nodes and data inside nodes */
node = ml->mlist_first->mlnode_next;
mlist_node_done(ml->mlist_first);
ml->mlist_first = node;
}
/** list structure */
if (!ml->mlist_flat)
{
free(ml);
}
}
}
void mlist_node_done(mlist_node_t* n)
{
CHK_MLIST_NODE(n);
if (n->mlnode_data != NULL)
{
if (n->mlnode_list->mlist_datadel != NULL)
{
(n->mlnode_list->mlist_datadel(n->mlnode_data));
}
free(n->mlnode_data);
}
free(n);
}
void* mlist_node_get_data(mlist_node_t* node)
{
CHK_MLIST_NODE(node);
return node->mlnode_data;
}
mlist_cursor_t* mlist_cursor_init(mlist_t* list)
{
CHK_MLIST(list);
mlist_cursor_t* c;
/** acquire shared lock to the list */
simple_mutex_lock(&list->mlist_mutex, true);
c = (mlist_cursor_t *) calloc(1, sizeof (mlist_cursor_t));
if (c == NULL)
{
simple_mutex_unlock(&list->mlist_mutex);
goto return_cursor;
}
c->mlcursor_chk_top = CHK_NUM_MLIST_CURSOR;
c->mlcursor_chk_tail = CHK_NUM_MLIST_CURSOR;
c->mlcursor_list = list;
/** Set cursor position if list is not empty */
if (list->mlist_first != NULL)
{
c->mlcursor_pos = list->mlist_first;
}
simple_mutex_unlock(&list->mlist_mutex);
CHK_MLIST_CURSOR(c);
return_cursor:
return c;
}
/**
* @node Mark list as deleted and free the memory.
*
* Parameters:
* @param list - <usage>
* <description>
*
* @return void
*
*
* @details (write detailed description here)
*
*/
void mlist_done(mlist_t* list)
{
CHK_MLIST(list);
simple_mutex_lock(&list->mlist_mutex, true);
list->mlist_deleted = true;
simple_mutex_unlock(&list->mlist_mutex);
simple_mutex_done(&list->mlist_mutex);
mlist_free_memory(list, list->mlist_name);
}
void* mlist_cursor_get_data_nomutex(mlist_cursor_t* mc)
{
CHK_MLIST_CURSOR(mc);
return (mc->mlcursor_pos->mlnode_data);
}
/**
* @node Adds data to list by allocating node for it. Checks list size limit.
*
* Parameters:
* @param list - <usage>
* <description>
*
* @param data - <usage>
* <description>
*
* @return true, if succeed, false, if list had node limit and it is full.
*
*
* @details (write detailed description here)
*
*/
bool mlist_add_data_nomutex(mlist_t* list, void* data)
{
bool succp;
succp = mlist_add_node_nomutex(list, mlist_node_init(data, NULL));
return succp;
}
static mlist_node_t* mlist_node_init(void* data, mlist_cursor_t* cursor)
{
mlist_node_t* node;
node = (mlist_node_t*) calloc(1, sizeof (mlist_node_t));
node->mlnode_chk_top = CHK_NUM_MLIST_NODE;
node->mlnode_chk_tail = CHK_NUM_MLIST_NODE;
node->mlnode_data = data;
CHK_MLIST_NODE(node);
if (cursor != NULL)
{
cursor->mlcursor_pos = node;
}
return node;
}
mlist_node_t* mlist_detach_first(mlist_t* ml)
{
mlist_node_t* node;
CHK_MLIST(ml);
node = ml->mlist_first;
CHK_MLIST_NODE(node);
ml->mlist_first = node->mlnode_next;
node->mlnode_next = NULL;
ml->mlist_nodecount -= 1;
if (ml->mlist_nodecount == 0)
{
ml->mlist_last = NULL;
}
else
{
CHK_MLIST_NODE(ml->mlist_first);
}
CHK_MLIST(ml);
return (node);
}
/**
* @node Add new node to end of list if there is space for it.
*
* Parameters:
* @param list - <usage>
* <description>
*
* @param newnode - <usage>
* <description>
*
* @param add_last - <usage>
* <description>
*
* @return true, if succeede, false, if list size limit was exceeded.
*
*
* @details (write detailed description here)
*
*/
bool mlist_add_node_nomutex(mlist_t* list, mlist_node_t* newnode)
{
bool succp = false;
CHK_MLIST(list);
CHK_MLIST_NODE(newnode);
ss_dassert(!list->mlist_deleted);
/** List is full already. */
if (list->mlist_nodecount == list->mlist_nodecount_max)
{
goto return_succp;
}
/** Find location for new node */
if (list->mlist_last != NULL)
{
ss_dassert(!list->mlist_last->mlnode_deleted);
CHK_MLIST_NODE(list->mlist_last);
CHK_MLIST_NODE(list->mlist_first);
ss_dassert(list->mlist_last->mlnode_next == NULL);
list->mlist_last->mlnode_next = newnode;
}
else
{
list->mlist_first = newnode;
}
list->mlist_last = newnode;
newnode->mlnode_list = list;
list->mlist_nodecount += 1;
succp = true;
return_succp:
CHK_MLIST(list);
return succp;
}
bool mlist_cursor_move_to_first(mlist_cursor_t* mc)
{
bool succp = false;
mlist_t* list;
CHK_MLIST_CURSOR(mc);
list = mc->mlcursor_list;
CHK_MLIST(list);
simple_mutex_lock(&list->mlist_mutex, true);
if (mc->mlcursor_list->mlist_deleted)
{
simple_mutex_unlock(&list->mlist_mutex);
return false;
}
/** Set position point to first node */
mc->mlcursor_pos = list->mlist_first;
if (mc->mlcursor_pos != NULL)
{
CHK_MLIST_NODE(mc->mlcursor_pos);
succp = true;
}
simple_mutex_unlock(&list->mlist_mutex);
return succp;
}
#endif /* MLIST */
/** End of mlist */
size_t get_timestamp_len(void)
{
return timestamp_len;

View File

@ -8,7 +8,6 @@
#define STRERROR_BUFLEN 512
#endif
#define MLIST
#ifndef MIN
#define MIN(a,b) (a<b ? a : b)
#endif
@ -22,7 +21,6 @@
#define DISKWRITE_LATENCY (5*MSEC_USEC)
typedef struct mlist_node_st mlist_node_t;
typedef struct skygw_file_st skygw_file_t;
typedef struct skygw_thread_st skygw_thread_t;
typedef struct skygw_message_st skygw_message_t;
@ -46,41 +44,6 @@ typedef struct skygw_rwlock_st {
} skygw_rwlock_t;
typedef struct mlist_st {
skygw_chk_t mlist_chk_top;
char* mlist_name;
void (*mlist_datadel)(void *); /**< clean-up function for data */
simple_mutex_t mlist_mutex; /**< protect node updates and clean-up */
bool mlist_uselock;
bool mlist_islocked;
bool mlist_deleted;
size_t mlist_nodecount;
size_t mlist_nodecount_max; /**< size limit. 0 == no limit */
size_t mlist_versno;
bool mlist_flat;
mlist_node_t* mlist_first;
mlist_node_t* mlist_last;
skygw_chk_t mlist_chk_tail;
} mlist_t;
typedef struct mlist_cursor_st {
skygw_chk_t mlcursor_chk_top;
mlist_t* mlcursor_list;
mlist_node_t* mlcursor_pos;
pthread_t* mlcursor_owner_thr;
skygw_chk_t mlcursor_chk_tail;
} mlist_cursor_t;
struct mlist_node_st {
skygw_chk_t mlnode_chk_top;
mlist_t* mlnode_list;
mlist_node_t* mlnode_next;
void* mlnode_data;
bool mlnode_deleted;
skygw_chk_t mlnode_chk_tail;
};
typedef enum { THR_INIT, THR_RUNNING, THR_STOPPED, THR_DONE } skygw_thr_state_t;
typedef enum { MES_RC_FAIL, MES_RC_SUCCESS, MES_RC_TIMEOUT } skygw_mes_rc_t;
@ -133,27 +96,6 @@ void utils_end();
EXTERN_C_BLOCK_END
mlist_t* mlist_init(mlist_t* mlist,
mlist_cursor_t** cursor,
char* name,
void (*datadel)(void*),
int maxnodes);
void mlist_done(mlist_t* list);
bool mlist_add_data_nomutex(mlist_t* list, void* data);
bool mlist_add_node_nomutex(mlist_t* list, mlist_node_t* newnode);
void* mlist_node_get_data(mlist_node_t* node);
mlist_node_t* mlist_detach_nodes(mlist_t* ml);
mlist_node_t* mlist_detach_first(mlist_t* ml);
void mlist_node_done(mlist_node_t* n);
int mlist_cursor_done(mlist_cursor_t* c);
mlist_cursor_t* mlist_cursor_init(mlist_t* ml);
void mlist_cursor_add_data(mlist_cursor_t* c, void* data);
void* mlist_cursor_get_data_nomutex(mlist_cursor_t* c);
bool mlist_cursor_move_to_first(mlist_cursor_t* c);
bool mlist_cursor_step_ahead(mlist_cursor_t* c);
/** Skygw thread routines */
skygw_thread_t* skygw_thread_init(
const char* name,