brand release-1.0beta-refresh merged
brand release-1.0beta-refresh merged
This commit is contained in:
@ -38,12 +38,30 @@
|
||||
* 10/06/2013 Mark Riddoch Initial implementation
|
||||
* 11/07/2013 Mark Riddoch Addition of reference count in the gwbuf
|
||||
* 16/07/2013 Massimiliano Pinto Added command type for the queue
|
||||
* 10/07/2014 Mark Riddoch Addition of hints
|
||||
* 15/07/2014 Mark Riddoch Added buffer properties
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <skygw_debug.h>
|
||||
#include <hint.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
|
||||
EXTERN_C_BLOCK_BEGIN
|
||||
|
||||
/**
|
||||
* Buffer properties - used to store properties related to the buffer
|
||||
* contents. This may be added at any point during the processing of the
|
||||
* data, especially in the protocol stage of the processing.
|
||||
*/
|
||||
typedef struct buf_property {
|
||||
char *name;
|
||||
char *value;
|
||||
struct buf_property *next;
|
||||
} BUF_PROPERTY;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GWBUF_TYPE_UNDEFINED = 0x00,
|
||||
@ -52,7 +70,8 @@ typedef enum
|
||||
GWBUF_TYPE_SINGLE_STMT = 0x04,
|
||||
GWBUF_TYPE_SESCMD_RESPONSE = 0x08,
|
||||
GWBUF_TYPE_RESPONSE_END = 0x10,
|
||||
GWBUF_TYPE_SESCMD = 0x20
|
||||
GWBUF_TYPE_SESCMD = 0x20,
|
||||
GWBUF_TYPE_HTTP = 0x40
|
||||
} gwbuf_type_t;
|
||||
|
||||
#define GWBUF_IS_TYPE_UNDEFINED(b) (b->gwbuf_type == 0)
|
||||
@ -73,6 +92,35 @@ typedef struct {
|
||||
int refcount; /*< Reference count on the buffer */
|
||||
} SHARED_BUF;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GWBUF_INFO_NONE = 0x0,
|
||||
GWBUF_INFO_PARSED = 0x1
|
||||
} gwbuf_info_t;
|
||||
|
||||
#define GWBUF_IS_PARSED(b) (b->gwbuf_info & GWBUF_INFO_PARSED)
|
||||
|
||||
/**
|
||||
* A structure for cleaning up memory allocations of structures which are
|
||||
* referred to by GWBUF and deallocated in gwbuf_free but GWBUF doesn't
|
||||
* know what they are.
|
||||
* All functions on the list are executed before freeing memory of GWBUF struct.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GWBUF_PARSING_INFO
|
||||
} bufobj_id_t;
|
||||
|
||||
typedef struct buffer_object_st buffer_object_t;
|
||||
|
||||
struct buffer_object_st {
|
||||
bufobj_id_t bo_id;
|
||||
void* bo_data;
|
||||
void (*bo_donefun_fp)(void *);
|
||||
buffer_object_t* bo_next;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The buffer structure used by the descriptor control blocks.
|
||||
*
|
||||
@ -82,12 +130,17 @@ typedef struct {
|
||||
* be copied within the gateway.
|
||||
*/
|
||||
typedef struct gwbuf {
|
||||
SPINLOCK gwbuf_lock;
|
||||
struct gwbuf *next; /*< Next buffer in a linked chain of buffers */
|
||||
struct gwbuf *tail; /*< Last buffer in a linked chain of buffers */
|
||||
void *start; /*< Start of the valid data */
|
||||
void *end; /*< First byte after the valid data */
|
||||
SHARED_BUF *sbuf; /*< The shared buffer with the real data */
|
||||
int command;/*< The command type for the queue */
|
||||
buffer_object_t *gwbuf_bufobj; /*< List of objects referred to by GWBUF */
|
||||
gwbuf_info_t gwbuf_info; /*< Info bits */
|
||||
gwbuf_type_t gwbuf_type; /*< buffer's data type information */
|
||||
HINT *hint; /*< Hint data for this buffer */
|
||||
BUF_PROPERTY *properties; /*< Buffer properties */
|
||||
} GWBUF;
|
||||
|
||||
/*<
|
||||
@ -121,4 +174,18 @@ extern unsigned int gwbuf_length(GWBUF *head);
|
||||
extern GWBUF *gwbuf_clone_portion(GWBUF *head, size_t offset, size_t len);
|
||||
extern GWBUF *gwbuf_clone_transform(GWBUF *head, gwbuf_type_t type);
|
||||
extern void gwbuf_set_type(GWBUF *head, gwbuf_type_t type);
|
||||
extern int gwbuf_add_property(GWBUF *buf, char *name, char *value);
|
||||
extern char *gwbuf_get_property(GWBUF *buf, char *name);
|
||||
extern GWBUF *gwbuf_make_contiguous(GWBUF *);
|
||||
extern int gwbuf_add_hint(GWBUF *, HINT *);
|
||||
|
||||
void gwbuf_add_buffer_object(GWBUF* buf,
|
||||
bufobj_id_t id,
|
||||
void* data,
|
||||
void (*donefun_fp)(void *));
|
||||
void* gwbuf_get_buffer_object_data(GWBUF* buf, bufobj_id_t id);
|
||||
|
||||
EXTERN_C_BLOCK_END
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -39,13 +39,22 @@
|
||||
enum {MAX_PARAM_LEN=256};
|
||||
|
||||
typedef enum {
|
||||
UNDEFINED_TYPE = 0x00,
|
||||
STRING_TYPE = 0x01,
|
||||
COUNT_TYPE = 0x02,
|
||||
PERCENT_TYPE = 0x04,
|
||||
BOOL_TYPE = 0x08
|
||||
UNDEFINED_TYPE = 0x00,
|
||||
STRING_TYPE = 0x01,
|
||||
COUNT_TYPE = 0x02,
|
||||
PERCENT_TYPE = 0x04,
|
||||
BOOL_TYPE = 0x08,
|
||||
SQLVAR_TARGET_TYPE = 0x10
|
||||
} config_param_type_t;
|
||||
|
||||
typedef enum {
|
||||
TYPE_UNDEFINED = 0,
|
||||
TYPE_MASTER,
|
||||
TYPE_ALL
|
||||
} target_t;
|
||||
|
||||
enum {MAX_RLAG_NOT_AVAILABLE=-1, MAX_RLAG_UNDEFINED=-2};
|
||||
|
||||
#define PARAM_IS_TYPE(p,t) ((p) & (t))
|
||||
|
||||
/**
|
||||
@ -59,6 +68,7 @@ typedef struct config_parameter {
|
||||
int valcount; /*< int */
|
||||
int valpercent; /*< int */
|
||||
bool valbool; /*< bool */
|
||||
target_t valtarget; /*< sql variable route target */
|
||||
} qfd;
|
||||
config_param_type_t qfd_param_type;
|
||||
struct config_parameter *next; /**< Next pointer in the linked list */
|
||||
@ -97,9 +107,21 @@ bool config_set_qualified_param(
|
||||
config_param_type_t type);
|
||||
|
||||
|
||||
int config_get_valint(
|
||||
bool config_get_valint(
|
||||
int* val,
|
||||
CONFIG_PARAMETER* param,
|
||||
const char* name, /*< if NULL examine current param only */
|
||||
config_param_type_t ptype);
|
||||
|
||||
bool config_get_valbool(
|
||||
bool* val,
|
||||
CONFIG_PARAMETER* param,
|
||||
const char* name, /*< if NULL examine current param only */
|
||||
config_param_type_t ptype);
|
||||
|
||||
bool config_get_valtarget(
|
||||
target_t* val,
|
||||
CONFIG_PARAMETER* param,
|
||||
const char* name, /*< if NULL examine current param only */
|
||||
config_param_type_t ptype);
|
||||
#endif
|
||||
|
||||
@ -53,6 +53,7 @@ struct service;
|
||||
* 07/02/2014 Massimiliano Pinto Added ipv4 data struct into for dcb
|
||||
* 07/05/2014 Mark Riddoch Addition of callback mechanism
|
||||
* 08/05/2014 Mark Riddoch Addition of writeq high and low watermarks
|
||||
* 27/08/2014 Mark Ridddoch Addition of write event queuing
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -107,12 +108,16 @@ typedef struct gw_protocol {
|
||||
* The statitics gathered on a descriptor control block
|
||||
*/
|
||||
typedef struct dcbstats {
|
||||
int n_reads; /*< Number of reads on this descriptor */
|
||||
int n_writes; /*< Number of writes on this descriptor */
|
||||
int n_accepts; /*< Number of accepts on this descriptor */
|
||||
int n_buffered; /*< Number of buffered writes */
|
||||
int n_high_water; /*< Number of crosses of high water mark */
|
||||
int n_low_water; /*< Number of crosses of low water mark */
|
||||
int n_reads; /*< Number of reads on this descriptor */
|
||||
int n_writes; /*< Number of writes on this descriptor */
|
||||
int n_accepts; /*< Number of accepts on this descriptor */
|
||||
int n_buffered; /*< Number of buffered writes */
|
||||
int n_high_water; /*< Number of crosses of high water mark */
|
||||
int n_low_water; /*< Number of crosses of low water mark */
|
||||
int n_busypolls; /*< Number of read polls whiel reading */
|
||||
int n_readrechecks; /*< Number of rechecks for reads */
|
||||
int n_busywrpolls; /*< Number of write polls while writing */
|
||||
int n_writerechecks;/*< Number of rechecks for writes */
|
||||
} DCBSTATS;
|
||||
|
||||
/**
|
||||
@ -231,6 +236,13 @@ typedef struct dcb {
|
||||
DCBMM memdata; /**< The data related to DCB memory management */
|
||||
SPINLOCK cb_lock; /**< The lock for the callbacks linked list */
|
||||
DCB_CALLBACK *callbacks; /**< The list of callbacks for the DCB */
|
||||
SPINLOCK pollinlock;
|
||||
int pollinbusy;
|
||||
int readcheck;
|
||||
|
||||
SPINLOCK polloutlock;
|
||||
int polloutbusy;
|
||||
int writecheck;
|
||||
|
||||
unsigned int high_water; /**< High water mark */
|
||||
unsigned int low_water; /**< Low water mark */
|
||||
@ -259,6 +271,8 @@ int fail_accept_errno;
|
||||
#define DCB_BELOW_LOW_WATER(x) ((x)->low_water && (x)->writeqlen < (x)->low_water)
|
||||
#define DCB_ABOVE_HIGH_WATER(x) ((x)->high_water && (x)->writeqlen > (x)->high_water)
|
||||
|
||||
void dcb_pollin(DCB *, int);
|
||||
void dcb_pollout(DCB *, int);
|
||||
DCB *dcb_get_zombies(void);
|
||||
int gw_write(
|
||||
#if defined(SS_DEBUG)
|
||||
@ -289,7 +303,7 @@ void dcb_hashtable_stats(DCB *, void *); /**< Print statisitics */
|
||||
void dcb_add_to_zombieslist(DCB* dcb);
|
||||
int dcb_add_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *),
|
||||
void *);
|
||||
int dcb_remove_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON),
|
||||
int dcb_remove_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *),
|
||||
void *);
|
||||
int dcb_isvalid(DCB *); /* Check the DCB is in the linked list */
|
||||
|
||||
|
||||
@ -84,12 +84,17 @@ typedef struct hashtable {
|
||||
SPINLOCK spin; /**< Internal spinlock for the hashtable */
|
||||
int n_readers; /**< Number of clients reading the table */
|
||||
int writelock; /**< The table is locked by a writer */
|
||||
bool ht_isflat; /**< Indicates whether hashtable is in stack or heap */
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t ht_chk_tail;
|
||||
#endif
|
||||
} HASHTABLE;
|
||||
|
||||
extern HASHTABLE *hashtable_alloc(int, int (*hashfn)(), int (*cmpfn)());
|
||||
HASHTABLE *hashtable_alloc_flat(HASHTABLE* target,
|
||||
int size,
|
||||
int (*hashfn)(),
|
||||
int (*cmpfn)());
|
||||
/**< Allocate a hashtable */
|
||||
extern void hashtable_memory_fns(HASHTABLE *, HASHMEMORYFN, HASHMEMORYFN, HASHMEMORYFN, HASHMEMORYFN);
|
||||
/**< Provide an interface to control key/value memory
|
||||
|
||||
69
server/include/hint.h
Normal file
69
server/include/hint.h
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef _HINT_H
|
||||
#define _HINT_H
|
||||
/*
|
||||
* This file is distributed as part of 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 SkySQL Ab 2014
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hint.h The generic hint data that may be attached to buffers
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 10/07/14 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <skygw_debug.h>
|
||||
|
||||
|
||||
/**
|
||||
* The types of hint that are supported by the generic hinting mechanism.
|
||||
*/
|
||||
typedef enum {
|
||||
HINT_ROUTE_TO_MASTER = 1,
|
||||
HINT_ROUTE_TO_SLAVE,
|
||||
HINT_ROUTE_TO_NAMED_SERVER,
|
||||
HINT_ROUTE_TO_UPTODATE_SERVER,
|
||||
HINT_ROUTE_TO_ALL, /*< not implemented yet */
|
||||
HINT_PARAMETER
|
||||
} HINT_TYPE;
|
||||
|
||||
/**
|
||||
* A generic hint.
|
||||
*
|
||||
* A hint has a type associated with it and may optionally have hint
|
||||
* specific data.
|
||||
* Multiple hints may be attached to a single buffer.
|
||||
*/
|
||||
typedef struct hint {
|
||||
HINT_TYPE type; /*< The Type of hint */
|
||||
void *data; /*< Type specific data */
|
||||
void *value; /*< Parameter value for hint */
|
||||
unsigned int dsize; /*< Size of the hint data */
|
||||
struct hint *next; /*< Another hint for this buffer */
|
||||
} HINT;
|
||||
|
||||
extern HINT *hint_alloc(HINT_TYPE, void *, unsigned int);
|
||||
extern HINT *hint_create_parameter(HINT *, char *, char *);
|
||||
extern HINT *hint_create_route(HINT *, HINT_TYPE, char *);
|
||||
extern void hint_free(HINT *);
|
||||
extern HINT *hint_dup(HINT *);
|
||||
bool hint_exists(HINT **, HINT_TYPE);
|
||||
#endif
|
||||
50
server/include/housekeeper.h
Normal file
50
server/include/housekeeper.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef _HOUSEKEEPER_H
|
||||
#define _HOUSEKEEPER_H
|
||||
/*
|
||||
* This file is distributed as part of the SkySQL Gateway. 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 SkySQL Ab 2014
|
||||
*/
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* @file housekeeper.h A mechanism to have task run periodically
|
||||
*
|
||||
* @verbatim
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 29/08/14 Mark Riddoch Initial implementation
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
/**
|
||||
* The housekeeper task list
|
||||
*/
|
||||
typedef struct hktask {
|
||||
char *name; /*< A simple task name */
|
||||
void (*task)(void *data); /*< The task to call */
|
||||
void *data; /*< Data to pass the task */
|
||||
int frequency; /*< How often to call the tasks (seconds) */
|
||||
time_t nextdue; /*< When the task should be next run */
|
||||
struct hktask
|
||||
*next; /*< Next task in the list */
|
||||
} HKTASK;
|
||||
|
||||
extern void hkinit();
|
||||
extern int hktask_add(char *name, void (*task)(void *), void *data, int frequency);
|
||||
extern int hktask_remove(char *name);
|
||||
#endif
|
||||
@ -36,4 +36,6 @@ extern int modutil_is_SQL(GWBUF *);
|
||||
extern int modutil_extract_SQL(GWBUF *, char **, int *);
|
||||
extern int modutil_MySQL_Query(GWBUF *, char **, int *, int *);
|
||||
extern GWBUF *modutil_replace_SQL(GWBUF *, char *);
|
||||
char* modutil_get_query(GWBUF* buf);
|
||||
|
||||
#endif
|
||||
|
||||
@ -31,6 +31,8 @@
|
||||
* 25/07/13 Mark Riddoch Addition of diagnotics
|
||||
* 23/05/14 Mark Riddoch Addition of routine to find monitors by name
|
||||
* 23/05/14 Massimiliano Pinto Addition of defaultId and setInterval
|
||||
* 23/06/14 Massimiliano Pinto Addition of replicationHeartbeat
|
||||
* 28/08/14 Massimiliano Pinto Addition of detectStaleMaster
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -70,6 +72,7 @@ typedef struct {
|
||||
void (*setInterval)(void *, unsigned long);
|
||||
void (*defaultId)(void *, unsigned long);
|
||||
void (*replicationHeartbeat)(void *, int);
|
||||
void (*detectStaleMaster)(void *, int);
|
||||
} MONITOR_OBJECT;
|
||||
|
||||
/**
|
||||
@ -110,4 +113,5 @@ extern void monitorList(DCB *);
|
||||
extern void monitorSetId(MONITOR *, unsigned long);
|
||||
extern void monitorSetInterval (MONITOR *, unsigned long);
|
||||
extern void monitorSetReplicationHeartbeat(MONITOR *, int);
|
||||
extern void monitorDetectStaleMaster(MONITOR *, int);
|
||||
#endif
|
||||
|
||||
@ -41,4 +41,5 @@ extern void poll_waitevents(void *);
|
||||
extern void poll_shutdown();
|
||||
extern GWBITMASK *poll_bitmask();
|
||||
extern void dprintPollStats(DCB *);
|
||||
extern void dShowThreads(DCB *dcb);
|
||||
#endif
|
||||
|
||||
@ -38,6 +38,8 @@
|
||||
* 03/06/14 Mark Riddoch Addition of maintainance mode
|
||||
* 20/06/14 Massimiliano Pinto Addition of master_id, depth, slaves fields
|
||||
* 26/06/14 Mark Riddoch Adidtion of server parameters
|
||||
* 30/07/14 Massimiliano Pinto Addition of NDB status for MySQL Cluster
|
||||
* 30/08/14 Massimiliano Pinto Addition of SERVER_STALE_STATUS
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -95,12 +97,15 @@ typedef struct server {
|
||||
*
|
||||
* These are a bitmap of attributes that may be applied to a server
|
||||
*/
|
||||
#define SERVER_RUNNING 0x0001 /**<< The server is up and running */
|
||||
#define SERVER_MASTER 0x0002 /**<< The server is a master, i.e. can handle writes */
|
||||
#define SERVER_SLAVE 0x0004 /**<< The server is a slave, i.e. can handle reads */
|
||||
#define SERVER_JOINED 0x0008 /**<< The server is joined in a Galera cluster */
|
||||
#define SERVER_MAINT 0x1000 /**<< Server is in maintenance mode */
|
||||
#define SERVER_SLAVE_OF_EXTERNAL_MASTER 0x0080 /**<< Server is slave of a Master outside the provided replication topology */
|
||||
#define SERVER_RUNNING 0x0001 /**<< The server is up and running */
|
||||
#define SERVER_MASTER 0x0002 /**<< The server is a master, i.e. can handle writes */
|
||||
#define SERVER_SLAVE 0x0004 /**<< The server is a slave, i.e. can handle reads */
|
||||
#define SERVER_JOINED 0x0008 /**<< The server is joined in a Galera cluster */
|
||||
#define SERVER_NDB 0x0010 /**<< The server is part of a MySQL cluster setup */
|
||||
#define SERVER_MAINT 0x0020 /**<< Server is in maintenance mode */
|
||||
#define SERVER_SLAVE_OF_EXTERNAL_MASTER 0x0040 /**<< Server is slave of a Master outside the provided replication topology */
|
||||
#define SERVER_STALE_STATUS 0x0080 /**<< Server stale status, monitor didn't update it */
|
||||
#define SERVER_AUTH_ERROR 0x1000 /**<< Authentication erorr from monitor */
|
||||
|
||||
/**
|
||||
* Is the server running - the macro returns true if the server is marked as running
|
||||
@ -131,15 +136,21 @@ typedef struct server {
|
||||
#define SERVER_IS_JOINED(server) \
|
||||
(((server)->status & (SERVER_RUNNING|SERVER_JOINED|SERVER_MAINT)) == (SERVER_RUNNING|SERVER_JOINED))
|
||||
|
||||
/**
|
||||
* Is the server a SQL node in MySQL Cluster? The server must be running and with NDB status
|
||||
*/
|
||||
#define SERVER_IS_NDB(server) \
|
||||
(((server)->status & (SERVER_RUNNING|SERVER_NDB|SERVER_MAINT)) == (SERVER_RUNNING|SERVER_NDB))
|
||||
|
||||
/**
|
||||
* Is the server in maintenance mode.
|
||||
*/
|
||||
#define SERVER_IN_MAINT(server) ((server)->status & SERVER_MAINT)
|
||||
|
||||
/** server is not master, slave or joined */
|
||||
#define SERVER_NOT_IN_CLUSTER(s) (((s)->status & (SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED)) == 0)
|
||||
#define SERVER_NOT_IN_CLUSTER(s) (((s)->status & (SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED|SERVER_NDB)) == 0)
|
||||
|
||||
#define SERVER_IS_IN_CLUSTER(s) (((s)->status & (SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED)) != 0)
|
||||
#define SERVER_IS_IN_CLUSTER(s) (((s)->status & (SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED|SERVER_NDB)) != 0)
|
||||
|
||||
#define SERVER_IS_RELAY_SERVER(server) \
|
||||
(((server)->status & (SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE|SERVER_MAINT)) == (SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE))
|
||||
|
||||
@ -137,7 +137,7 @@ typedef struct service {
|
||||
struct service *next; /**< The next service in the linked list */
|
||||
} SERVICE;
|
||||
|
||||
typedef enum count_spec_t {COUNT_ATLEAST=0, COUNT_EXACT, COUNT_ATMOST} count_spec_t;
|
||||
typedef enum count_spec_t {COUNT_NONE=0, COUNT_ATLEAST, COUNT_EXACT, COUNT_ATMOST} count_spec_t;
|
||||
|
||||
#define SERVICE_STATE_ALLOC 1 /**< The service has been allocated */
|
||||
#define SERVICE_STATE_STARTED 2 /**< The service has been started */
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
/**
|
||||
* @file spinlock.h
|
||||
*
|
||||
* Spinlock implementation for ther gateway.
|
||||
* Spinlock implementation for MaxScale.
|
||||
*
|
||||
* Spinlocks are cheap locks that can be used to protect short code blocks, they are
|
||||
* generally wasteful as any blocked threads will spin, consuming CPU cycles, waiting
|
||||
@ -31,12 +31,28 @@
|
||||
#include <thread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define SPINLOCK_PROFILE 1
|
||||
|
||||
/**
|
||||
* The spinlock structure.
|
||||
*
|
||||
* In normal builds the structure merely contains a lock value which
|
||||
* is 0 if the spinlock is not taken and greater than zero if it is held.
|
||||
*
|
||||
* In builds with the SPINLOCK_PROFILE option set this structure also holds
|
||||
* a number of profile related fields that count the number of spins, number
|
||||
* of waiting threads and the number of times the lock has been acquired.
|
||||
*/
|
||||
typedef struct spinlock {
|
||||
int lock;
|
||||
#if DEBUG
|
||||
int spins;
|
||||
int acquired;
|
||||
THREAD owner;
|
||||
int lock; /*< Is the lock held? */
|
||||
#if SPINLOCK_PROFILE
|
||||
int spins; /*< Number of spins on this lock */
|
||||
int maxspins; /*< Max no of spins to acquire lock */
|
||||
int acquired; /*< No. of times lock was acquired */
|
||||
int waiting; /*< No. of threads acquiring this lock */
|
||||
int max_waiting; /*< Max no of threads waiting for lock */
|
||||
int contended; /*< No. of times acquire was contended */
|
||||
THREAD owner; /*< Last owner of this lock */
|
||||
#endif
|
||||
} SPINLOCK;
|
||||
|
||||
@ -47,8 +63,8 @@ typedef struct spinlock {
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#define SPINLOCK_INIT { 0, 0, 0, NULL }
|
||||
#if SPINLOCK_PROFILE
|
||||
#define SPINLOCK_INIT { 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
#else
|
||||
#define SPINLOCK_INIT { 0 }
|
||||
#endif
|
||||
@ -59,4 +75,6 @@ extern void spinlock_init(SPINLOCK *lock);
|
||||
extern void spinlock_acquire(SPINLOCK *lock);
|
||||
extern int spinlock_acquire_nowait(SPINLOCK *lock);
|
||||
extern void spinlock_release(SPINLOCK *lock);
|
||||
extern void spinlock_stats(SPINLOCK *lock,
|
||||
void (*reporter)(void *, char *, int), void *hdl);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user