Merge branch 'develop' into firewall
This commit is contained in:
@ -160,4 +160,17 @@ configure_file(
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
|
||||
find_package(Doxygen)
|
||||
|
||||
if(DOXYGEN_FOUND)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/doxygate.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/doxygate"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(documentation
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxygate)
|
||||
|
||||
endif()
|
||||
|
1520
doxygate.in
Normal file
1520
doxygate.in
Normal file
File diff suppressed because it is too large
Load Diff
@ -338,6 +338,12 @@ static bool logmanager_init_nomutex(
|
||||
bool succp = false;
|
||||
|
||||
lm = (logmanager_t *)calloc(1, sizeof(logmanager_t));
|
||||
|
||||
if (lm == NULL)
|
||||
{
|
||||
err = 1;
|
||||
goto return_succp;
|
||||
}
|
||||
#if defined(SS_DEBUG)
|
||||
lm->lm_chk_top = CHK_NUM_LOGMANAGER;
|
||||
lm->lm_chk_tail = CHK_NUM_LOGMANAGER;
|
||||
@ -347,7 +353,15 @@ static bool logmanager_init_nomutex(
|
||||
simple_mutex_init(&msg_mutex, "Message mutex");
|
||||
#endif
|
||||
lm->lm_clientmes = skygw_message_init();
|
||||
lm->lm_logmes = skygw_message_init();
|
||||
lm->lm_logmes = skygw_message_init();
|
||||
|
||||
if (lm->lm_clientmes == NULL ||
|
||||
lm->lm_logmes == NULL)
|
||||
{
|
||||
err = 1;
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
lm->lm_enabled_logfiles |= LOGFILE_ERROR;
|
||||
lm->lm_enabled_logfiles |= LOGFILE_MESSAGE;
|
||||
#if defined(SS_DEBUG)
|
||||
@ -360,8 +374,10 @@ static bool logmanager_init_nomutex(
|
||||
fw->fwr_state = UNINIT;
|
||||
|
||||
/** Initialize configuration including log file naming info */
|
||||
if (!fnames_conf_init(fn, argc, argv)) {
|
||||
goto return_succp;
|
||||
if (!fnames_conf_init(fn, argc, argv))
|
||||
{
|
||||
err = 1;
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
/** Initialize logfiles */
|
||||
@ -388,7 +404,13 @@ static bool logmanager_init_nomutex(
|
||||
fw->fwr_thread = skygw_thread_init("filewriter thr",
|
||||
thr_filewriter_fun,
|
||||
(void *)fw);
|
||||
|
||||
|
||||
if (fw->fwr_thread == NULL)
|
||||
{
|
||||
err = 1;
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
if ((err = skygw_thread_start(fw->fwr_thread)) != 0)
|
||||
{
|
||||
goto return_succp;
|
||||
@ -402,9 +424,12 @@ static bool logmanager_init_nomutex(
|
||||
return_succp:
|
||||
if (err != 0)
|
||||
{
|
||||
/** This releases memory of all created objects */
|
||||
logmanager_done_nomutex();
|
||||
fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n");
|
||||
skygw_message_done(lm->lm_clientmes);
|
||||
skygw_message_done(lm->lm_logmes);
|
||||
|
||||
/** This releases memory of all created objects */
|
||||
logmanager_done_nomutex();
|
||||
fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n");
|
||||
}
|
||||
return succp;
|
||||
}
|
||||
@ -2076,8 +2101,8 @@ static bool logfile_init(
|
||||
fnames_conf_t* fn = &logmanager->lm_fnames_conf;
|
||||
/** string parts of which the file is composed of */
|
||||
strpart_t strparts[3];
|
||||
bool namecreatefail;
|
||||
bool nameconflicts;
|
||||
bool namecreatefail = false;
|
||||
bool nameconflicts = false;
|
||||
bool writable;
|
||||
|
||||
logfile->lf_state = INIT;
|
||||
@ -2406,9 +2431,16 @@ static bool filewriter_init(
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (fw->fwr_file[id] == NULL) {
|
||||
if (fw->fwr_file[id] == NULL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Error : opening %s failed, %s. Exiting "
|
||||
"MaxScale\n",
|
||||
lf->lf_full_file_name,
|
||||
strerror(errno));
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
if (lf->lf_enabled) {
|
||||
start_msg_str = strdup("---\tLogging is enabled.\n");
|
||||
} else {
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include <log_manager.h>
|
||||
#include <secrets.h>
|
||||
#include <mysql_client_server_protocol.h>
|
||||
#include <mysqld_error.h>
|
||||
|
||||
|
||||
#define USERS_QUERY_NO_ROOT " AND user NOT IN ('root')"
|
||||
#define LOAD_MYSQL_USERS_QUERY "SELECT user, host, password, concat(user,host,password,Select_priv) AS userdata, Select_priv AS anydb FROM mysql.user WHERE user IS NOT NULL AND user <> ''"
|
||||
@ -494,7 +496,7 @@ getUsers(SERVICE *service, USERS *users)
|
||||
|
||||
/* start with users and db grants for users */
|
||||
if (mysql_query(con, MYSQL_USERS_WITH_DB_COUNT)) {
|
||||
if (1142 != mysql_errno(con)) {
|
||||
if (mysql_errno(con) != ER_TABLEACCESS_DENIED_ERROR) {
|
||||
/* This is an error we cannot handle, return */
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
@ -897,13 +899,19 @@ static void *uh_keydup(void* key) {
|
||||
MYSQL_USER_HOST *current_key = (MYSQL_USER_HOST *)key;
|
||||
|
||||
if (key == NULL || rval == NULL || current_key == NULL || current_key->user == NULL) {
|
||||
if (rval) {
|
||||
free(rval);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rval->user = strdup(current_key->user);
|
||||
|
||||
if (rval->user == NULL)
|
||||
if (rval->user == NULL) {
|
||||
free(rval);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(&rval->ipv4, ¤t_key->ipv4, sizeof(struct sockaddr_in));
|
||||
memcpy(&rval->netmask, ¤t_key->netmask, sizeof(int));
|
||||
|
@ -175,7 +175,7 @@ void gw_daemonize(void) {
|
||||
int
|
||||
parse_bindconfig(char *config, unsigned short def_port, struct sockaddr_in *addr)
|
||||
{
|
||||
char *port, buf[1024];
|
||||
char *port, buf[1024 + 1];
|
||||
short pnum;
|
||||
struct hostent *hp;
|
||||
|
||||
|
@ -258,7 +258,9 @@ hashtable_add(HASHTABLE *table, void *key, void *value)
|
||||
|
||||
/* check succesfull key copy */
|
||||
if ( ptr->key == NULL) {
|
||||
free(ptr);
|
||||
hashtable_write_unlock(table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -269,9 +271,11 @@ hashtable_add(HASHTABLE *table, void *key, void *value)
|
||||
if ( ptr->value == NULL) {
|
||||
/* remove the key ! */
|
||||
table->kfreefn(ptr->key);
|
||||
free(ptr);
|
||||
|
||||
/* value not copied, return */
|
||||
hashtable_write_unlock(table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -279,6 +283,7 @@ hashtable_add(HASHTABLE *table, void *key, void *value)
|
||||
table->entries[hashkey % table->hashsize] = ptr;
|
||||
}
|
||||
hashtable_write_unlock(table);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,7 @@ static simple_mutex_t epoll_wait_mutex; /*< serializes calls to epoll_wait */
|
||||
#endif
|
||||
static int n_waiting = 0; /*< No. of threads in epoll_wait */
|
||||
static int process_pollq(int thread_id);
|
||||
static void poll_add_event_to_dcb(DCB* dcb, GWBUF* buf, __uint32_t ev);
|
||||
|
||||
|
||||
DCB *eventq = NULL;
|
||||
@ -1110,3 +1111,68 @@ int new_samples, new_nfds;
|
||||
if (next_sample >= n_avg_samples)
|
||||
next_sample = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add given GWBUF to DCB's readqueue and add a pending EPOLLIN event for DCB.
|
||||
* The event pretends that there is something to read for the DCB. Actually
|
||||
* the incoming data is stored in the DCB's readqueue where it is read.
|
||||
*
|
||||
* @param dcb DCB where the event and data are added
|
||||
* @param buf GWBUF including the data
|
||||
*
|
||||
*/
|
||||
void poll_add_epollin_event_to_dcb(
|
||||
DCB* dcb,
|
||||
GWBUF* buf)
|
||||
{
|
||||
__uint32_t ev;
|
||||
|
||||
ev = EPOLLIN;
|
||||
|
||||
poll_add_event_to_dcb(dcb, buf, ev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void poll_add_event_to_dcb(
|
||||
DCB* dcb,
|
||||
GWBUF* buf,
|
||||
__uint32_t ev)
|
||||
{
|
||||
/** Add buf to readqueue */
|
||||
spinlock_acquire(&dcb->authlock);
|
||||
dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, buf);
|
||||
spinlock_release(&dcb->authlock);
|
||||
|
||||
spinlock_acquire(&pollqlock);
|
||||
|
||||
/** Set event to DCB */
|
||||
if (DCB_POLL_BUSY(dcb))
|
||||
{
|
||||
dcb->evq.pending_events |= ev;
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb->evq.pending_events = ev;
|
||||
/** Add DCB to eventqueue if it isn't already there */
|
||||
if (eventq)
|
||||
{
|
||||
dcb->evq.prev = eventq->evq.prev;
|
||||
eventq->evq.prev->evq.next = dcb;
|
||||
eventq->evq.prev = dcb;
|
||||
dcb->evq.next = eventq;
|
||||
}
|
||||
else
|
||||
{
|
||||
eventq = dcb;
|
||||
dcb->evq.prev = dcb;
|
||||
dcb->evq.next = dcb;
|
||||
}
|
||||
pollStats.evq_length++;
|
||||
if (pollStats.evq_length > pollStats.evq_max)
|
||||
{
|
||||
pollStats.evq_max = pollStats.evq_length;
|
||||
}
|
||||
}
|
||||
spinlock_release(&pollqlock);
|
||||
}
|
@ -41,4 +41,11 @@ extern GWBUF *modutil_replace_SQL(GWBUF *, char *);
|
||||
extern char *modutil_get_query(GWBUF* buf);
|
||||
extern int modutil_send_mysql_err_packet(DCB *, int, int, int, const char *, const char *);
|
||||
|
||||
GWBUF *modutil_create_mysql_err_msg(
|
||||
int packet_number,
|
||||
int affected_rows,
|
||||
int merrno,
|
||||
const char *statemsg,
|
||||
const char *msg);
|
||||
|
||||
#endif
|
||||
|
@ -42,4 +42,6 @@ extern void poll_shutdown();
|
||||
extern GWBITMASK *poll_bitmask();
|
||||
extern void dprintPollStats(DCB *);
|
||||
extern void dShowThreads(DCB *dcb);
|
||||
void poll_add_epollin_event_to_dcb(DCB* dcb, GWBUF* buf);
|
||||
|
||||
#endif
|
||||
|
@ -74,6 +74,7 @@ typedef enum backend_type_t {
|
||||
struct router_instance;
|
||||
|
||||
typedef enum {
|
||||
TARGET_UNDEFINED = 0x00,
|
||||
TARGET_MASTER = 0x01,
|
||||
TARGET_SLAVE = 0x02,
|
||||
TARGET_NAMED_SERVER = 0x04,
|
||||
|
@ -71,6 +71,7 @@ static int gw_change_user(DCB *backend_dcb, SERVER *server, SESSION *in_session,
|
||||
static GWBUF* process_response_data (DCB* dcb, GWBUF* readbuf, int nbytes_to_process);
|
||||
extern char* create_auth_failed_msg( GWBUF* readbuf, char* hostaddr, uint8_t* sha1);
|
||||
extern char* create_auth_fail_str(char *username, char *hostaddr, char *sha1, char *db);
|
||||
static bool sescmd_response_complete(DCB* dcb);
|
||||
|
||||
|
||||
#if defined(NOT_USED)
|
||||
@ -194,7 +195,7 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
* If starting to auhenticate with backend server, lock dcb
|
||||
* to prevent overlapping processing of auth messages.
|
||||
*/
|
||||
if (backend_protocol->protocol_auth_state == MYSQL_CONNECTED)
|
||||
if (backend_protocol->protocol_auth_state == MYSQL_CONNECTED)
|
||||
{
|
||||
spinlock_acquire(&dcb->authlock);
|
||||
|
||||
@ -471,19 +472,26 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
}
|
||||
nbytes_read = gwbuf_length(read_buffer);
|
||||
|
||||
if (nbytes_read == 0)
|
||||
if (nbytes_read == 0 && dcb->dcb_readqueue == NULL)
|
||||
{
|
||||
goto return_rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss_dassert(read_buffer != NULL);
|
||||
ss_dassert(read_buffer != NULL || dcb->dcb_readqueue != NULL);
|
||||
}
|
||||
|
||||
/** Packet prefix was read earlier */
|
||||
if (dcb->dcb_readqueue)
|
||||
{
|
||||
read_buffer = gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
||||
if (read_buffer != NULL)
|
||||
{
|
||||
read_buffer = gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
read_buffer = dcb->dcb_readqueue;
|
||||
}
|
||||
nbytes_read = gwbuf_length(read_buffer);
|
||||
|
||||
if (nbytes_read < 5) /*< read at least command type */
|
||||
@ -494,7 +502,6 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
/** There is at least length and command type. */
|
||||
else
|
||||
{
|
||||
read_buffer = dcb->dcb_readqueue;
|
||||
dcb->dcb_readqueue = NULL;
|
||||
}
|
||||
}
|
||||
@ -516,6 +523,15 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
MYSQL_COM_UNDEFINED)
|
||||
{
|
||||
read_buffer = process_response_data(dcb, read_buffer, nbytes_read);
|
||||
/**
|
||||
* Received incomplete response to session command.
|
||||
* Store it to readqueue and return.
|
||||
*/
|
||||
if (!sescmd_response_complete(dcb))
|
||||
{
|
||||
rc = 0;
|
||||
goto return_rc;
|
||||
}
|
||||
}
|
||||
/*<
|
||||
* If dcb->session->client is freed already it may be NULL.
|
||||
@ -723,9 +739,6 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
|
||||
|
||||
default:
|
||||
{
|
||||
uint8_t* ptr = GWBUF_DATA(queue);
|
||||
int cmd = MYSQL_GET_COMMAND(ptr);
|
||||
|
||||
LOGIF(LD, (skygw_log_write(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [gw_MySQLWrite_backend] delayed write to "
|
||||
@ -741,6 +754,9 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
|
||||
if (GWBUF_IS_TYPE_SINGLE_STMT(queue) &&
|
||||
GWBUF_IS_TYPE_SESCMD(queue))
|
||||
{
|
||||
uint8_t* ptr = GWBUF_DATA(queue);
|
||||
int cmd = MYSQL_GET_COMMAND(ptr);
|
||||
|
||||
/** Record the command to backend's protocol */
|
||||
protocol_add_srv_command(backend_protocol, cmd);
|
||||
}
|
||||
@ -1183,8 +1199,8 @@ static int backend_write_delayqueue(DCB *dcb)
|
||||
* @param server The backend server pointer
|
||||
* @param in_session The current session data (MYSQL_session)
|
||||
* @param queue The GWBUF containing the COM_CHANGE_USER receveid
|
||||
* @return 0 on success and 1 on failure
|
||||
*/
|
||||
* @return 1 on success and 0 on failure
|
||||
*/
|
||||
static int gw_change_user(
|
||||
DCB *backend,
|
||||
SERVER *server,
|
||||
@ -1266,26 +1282,35 @@ static int gw_change_user(
|
||||
if (auth_ret != 0) {
|
||||
char *password_set = NULL;
|
||||
char *message = NULL;
|
||||
GWBUF* buf;
|
||||
|
||||
if (auth_token_len > 0)
|
||||
password_set = (char *)client_sha1;
|
||||
else
|
||||
password_set = "";
|
||||
|
||||
message=create_auth_fail_str(username,
|
||||
/**
|
||||
* Create an error message and make it look like legit reply
|
||||
* from backend server. Then make it look like an incoming event
|
||||
* so that thread gets new task of it, calls clientReply
|
||||
* which filters out duplicate errors from same cause and forward
|
||||
* reply to the client.
|
||||
*/
|
||||
message = create_auth_fail_str(username,
|
||||
backend->session->client->remote,
|
||||
password_set,
|
||||
"");
|
||||
/* send the error packet */
|
||||
modutil_send_mysql_err_packet(backend->session->client, 1, 0, 1045, "28000", message);
|
||||
|
||||
free(message);
|
||||
|
||||
rv = 1;
|
||||
/** TODO: Add custom message indicating that retry would probably help */
|
||||
buf = modutil_create_mysql_err_msg(1, 0, 1045, "28000", message);
|
||||
/** Set flags that help router to identify session commans reply */
|
||||
gwbuf_set_type(buf, GWBUF_TYPE_MYSQL);
|
||||
gwbuf_set_type(buf, GWBUF_TYPE_SESCMD_RESPONSE);
|
||||
gwbuf_set_type(buf, GWBUF_TYPE_RESPONSE_END);
|
||||
/** Create an incoming event for backend DCB */
|
||||
poll_add_epollin_event_to_dcb(backend, buf);
|
||||
rv = 0;
|
||||
} else {
|
||||
|
||||
rv = gw_send_change_user_to_backend(database, username, client_sha1, backend_protocol);
|
||||
|
||||
/*
|
||||
* Now copy new data into user session
|
||||
*/
|
||||
@ -1298,29 +1323,9 @@ static int gw_change_user(
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Session Change wrapper for func.write
|
||||
* The reply packet will be back routed to the right server
|
||||
* in the gw_read_backend_event checking the ROUTER_CHANGE_SESSION command in dcb->command
|
||||
*
|
||||
* @param
|
||||
* @return always 1
|
||||
*/
|
||||
/*
|
||||
static int gw_session(DCB *backend_dcb, void *data) {
|
||||
|
||||
GWBUF *queue = NULL;
|
||||
|
||||
queue = (GWBUF *) data;
|
||||
backend_dcb->func.write(backend_dcb, queue);
|
||||
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Move packets or parts of packets from redbuf to outbuf as the packet headers
|
||||
* Move packets or parts of packets from readbuf to outbuf as the packet headers
|
||||
* and lengths have been noticed and counted.
|
||||
* Session commands need to be marked so that they can be handled properly in
|
||||
* the router's clientReply.
|
||||
@ -1452,3 +1457,28 @@ static GWBUF* process_response_data (
|
||||
}
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
|
||||
static bool sescmd_response_complete(
|
||||
DCB* dcb)
|
||||
{
|
||||
int npackets_left;
|
||||
size_t nbytes_left;
|
||||
MySQLProtocol* p;
|
||||
bool succp;
|
||||
|
||||
p = DCB_PROTOCOL(dcb, MySQLProtocol);
|
||||
CHK_PROTOCOL(p);
|
||||
|
||||
protocol_get_response_status(p, &npackets_left, &nbytes_left);
|
||||
|
||||
if (npackets_left == 0)
|
||||
{
|
||||
succp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
succp = false;
|
||||
}
|
||||
return succp;
|
||||
}
|
@ -1221,7 +1221,7 @@ int gw_send_change_user_to_backend(
|
||||
* @param scramble_len The scrable size in bytes
|
||||
* @param username The current username in the authentication request
|
||||
* @param stage1_hash The SHA1(candidate_password) decoded by this routine
|
||||
* @return 0 on succesful check or != 0 on failure
|
||||
* @return 0 on succesful check or 1 on failure
|
||||
*
|
||||
*/
|
||||
int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_len, uint8_t *scramble, unsigned int scramble_len, char *username, uint8_t *stage1_hash) {
|
||||
@ -1321,7 +1321,12 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
|
||||
#endif
|
||||
|
||||
/* now compare SHA1(SHA1(gateway_password)) and check_hash: return 0 is MYSQL_AUTH_OK */
|
||||
return memcmp(password, check_hash, SHA_DIGEST_LENGTH);
|
||||
ret_val = memcmp(password, check_hash, SHA_DIGEST_LENGTH);
|
||||
|
||||
if (ret_val != 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1241,7 +1241,7 @@ static route_target_t get_route_target (
|
||||
target_t use_sql_variables_in,
|
||||
HINT* hint)
|
||||
{
|
||||
route_target_t target;
|
||||
route_target_t target = TARGET_UNDEFINED;
|
||||
/**
|
||||
* These queries are not affected by hints
|
||||
*/
|
||||
@ -1355,6 +1355,11 @@ static route_target_t get_route_target (
|
||||
}
|
||||
hint = hint->next;
|
||||
} /*< while (hint != NULL) */
|
||||
/** If nothing matches then choose the master */
|
||||
if ((target & (TARGET_ALL|TARGET_SLAVE|TARGET_MASTER)) == target)
|
||||
{
|
||||
target = TARGET_MASTER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -224,17 +224,27 @@ int skygw_rwlock_init(
|
||||
int err;
|
||||
|
||||
rwl = (skygw_rwlock_t *)calloc(1, sizeof(skygw_rwlock_t));
|
||||
rwl->srw_chk_top = CHK_NUM_RWLOCK;
|
||||
rwl->srw_chk_tail = CHK_NUM_RWLOCK;
|
||||
err = pthread_rwlock_init(rwl->srw_rwlock, NULL);
|
||||
ss_dassert(err == 0);
|
||||
|
||||
if (err != 0) {
|
||||
|
||||
if (rwl == NULL)
|
||||
{
|
||||
err = 1;
|
||||
goto return_err;
|
||||
}
|
||||
rwl->srw_chk_top = CHK_NUM_RWLOCK;
|
||||
rwl->srw_chk_tail = CHK_NUM_RWLOCK;
|
||||
err = pthread_rwlock_init(rwl->srw_rwlock, NULL);
|
||||
ss_dassert(err == 0);
|
||||
|
||||
if (err != 0)
|
||||
{
|
||||
free(rwl);
|
||||
ss_dfprintf(stderr,
|
||||
"* Creating pthread_rwlock failed : %s\n",
|
||||
strerror(err));
|
||||
goto return_err;
|
||||
}
|
||||
*rwlock = rwl;
|
||||
|
||||
return_err:
|
||||
return err;
|
||||
}
|
||||
@ -1013,6 +1023,7 @@ skygw_thread_t* skygw_thread_init(
|
||||
|
||||
if (th->sth_mutex == NULL) {
|
||||
thread_free_memory(th, th->sth_name);
|
||||
th = NULL;
|
||||
goto return_th;
|
||||
}
|
||||
th->sth_thrfun = sth_thrfun;
|
||||
@ -1396,6 +1407,12 @@ skygw_message_t* skygw_message_init(void)
|
||||
skygw_message_t* mes;
|
||||
|
||||
mes = (skygw_message_t*)calloc(1, sizeof(skygw_message_t));
|
||||
|
||||
if (mes == NULL)
|
||||
{
|
||||
err = 1;
|
||||
goto return_mes;
|
||||
}
|
||||
mes->mes_chk_top = CHK_NUM_MESSAGE;
|
||||
mes->mes_chk_tail = CHK_NUM_MESSAGE;
|
||||
err = pthread_mutex_init(&(mes->mes_mutex), NULL);
|
||||
@ -1406,6 +1423,7 @@ skygw_message_t* skygw_message_init(void)
|
||||
"%d, %s\n",
|
||||
err,
|
||||
strerror(errno));
|
||||
free(mes);
|
||||
mes = NULL;
|
||||
goto return_mes;
|
||||
}
|
||||
@ -1417,6 +1435,8 @@ skygw_message_t* skygw_message_init(void)
|
||||
"due error %d, %s\n",
|
||||
err,
|
||||
strerror(errno));
|
||||
pthread_mutex_destroy(&mes->mes_mutex);
|
||||
free(mes);
|
||||
mes = NULL;
|
||||
goto return_mes;
|
||||
}
|
||||
|
Reference in New Issue
Block a user