1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

DBUG update and fixes

Fixed net_read crash in debug version
This commit is contained in:
holzboote@googlemail.com
2013-07-15 10:47:05 +02:00
parent d698bdddb8
commit d6f3bb4c9f
13 changed files with 2186 additions and 1751 deletions

View File

@@ -21,34 +21,48 @@
extern "C" { extern "C" {
#endif #endif
#if !defined(DBUG_OFF) && !defined(_lint) #if !defined(DBUG_OFF) && !defined(_lint)
extern int _db_on_,_no_db_;
extern FILE *_db_fp_;
extern char *_db_process_;
extern int _db_keyword_(const char *keyword);
extern void _db_setjmp_(void);
extern void _db_longjmp_(void);
extern void _db_push_(const char *control);
extern void _db_pop_(void);
extern void _db_enter_(const char *_func_,const char *_file_,uint _line_,
const char **_sfunc_,const char **_sfile_,
uint *_slevel_, char ***);
extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
uint *_slevel_);
extern void _db_pargs_(uint _line_,const char *keyword);
extern void _db_doprnt_ _VARARGS((const char *format,...));
extern void _db_dump_(uint _line_,const char *keyword,const char *memory,
uint length);
extern void _db_lock_file(void);
extern void _db_unlock_file(void);
#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \ struct _db_stack_frame_ {
char **_db_framep_; \ const char *func; /* function name of the previous stack frame */
_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \ const char *file; /* filename of the function of previous frame */
&_db_framep_) uint level; /* this nesting level, highest bit enables tracing */
struct _db_stack_frame_ *prev; /* pointer to the previous frame */
};
struct _db_code_state_;
extern my_bool _dbug_on_;
extern my_bool _db_keyword_(struct _db_code_state_ *, const char *, int);
extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len);
extern int _db_explain_init_(char *buf, size_t len);
extern int _db_is_pushed_(void);
extern void _db_setjmp_(void);
extern void _db_longjmp_(void);
extern void _db_process_(const char *name);
extern void _db_push_(const char *control);
extern void _db_pop_(void);
extern void _db_set_(const char *control);
extern void _db_set_init_(const char *control);
extern void _db_enter_(const char *_func_, const char *_file_, uint _line_,
struct _db_stack_frame_ *_stack_frame_);
extern void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_);
extern void _db_pargs_(uint _line_,const char *keyword);
extern void _db_doprnt_ _VARARGS((const char *format,...));
extern void _db_dump_(uint _line_,const char *keyword,
const unsigned char *memory, size_t length);
extern void _db_end_(void);
extern void _db_lock_file_(void);
extern void _db_unlock_file_(void);
extern FILE *_db_fp_(void);
extern void _db_flush_();
extern const char* _db_get_func_(void);
/*
#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
#define DBUG_LEAVE \ #define DBUG_LEAVE \
(_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)) (_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_))
#define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);} #define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
#define DBUG_VOID_RETURN {DBUG_LEAVE; return;} #define DBUG_VOID_RETURN {DBUG_LEAVE; return;}
#define DBUG_END() _db_end_ ()
#define DBUG_EXECUTE(keyword,a1) \ #define DBUG_EXECUTE(keyword,a1) \
{if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}} {if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}}
#define DBUG_PRINT(keyword,arglist) \ #define DBUG_PRINT(keyword,arglist) \
@@ -66,10 +80,49 @@ extern void _db_unlock_file(void);
#define DEBUGGER_ON _no_db_=0 #define DEBUGGER_ON _no_db_=0
#define DBUG_LOCK_FILE { _db_lock_file(); } #define DBUG_LOCK_FILE { _db_lock_file(); }
#define DBUG_UNLOCK_FILE { _db_unlock_file(); } #define DBUG_UNLOCK_FILE { _db_unlock_file(); }
#define DBUG_ASSERT(A) assert(A) */
#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
#define DBUG_LEAVE _db_return_ (__LINE__, &_db_stack_frame_)
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
#define DBUG_EXECUTE(keyword,a1) \
do {if (_db_keyword_(0, (keyword), 0)) { a1 }} while(0)
#define DBUG_EXECUTE_IF(keyword,a1) \
do {if (_db_keyword_(0, (keyword), 1)) { a1 }} while(0)
#define DBUG_EVALUATE(keyword,a1,a2) \
(_db_keyword_(0,(keyword), 0) ? (a1) : (a2))
#define DBUG_EVALUATE_IF(keyword,a1,a2) \
(_db_keyword_(0,(keyword), 1) ? (a1) : (a2))
#define DBUG_PRINT(keyword,arglist) \
do {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;} while(0)
#define DBUG_PUSH(a1) _db_push_ (a1)
#define DBUG_POP() _db_pop_ ()
#define DBUG_SET(a1) _db_set_ (a1)
#define DBUG_SET_INITIAL(a1) _db_set_init_ (a1)
#define DBUG_PROCESS(a1) _db_process_(a1)
#define DBUG_FILE _db_fp_()
#define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
#define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
#define DBUG_DUMP(keyword,a1,a2) _db_dump_(__LINE__,keyword,a1,a2)
#define DBUG_END() _db_end_ ()
#define DBUG_LOCK_FILE _db_lock_file_()
#define DBUG_UNLOCK_FILE _db_unlock_file_()
#define DBUG_ASSERT(A) assert(A) #define DBUG_ASSERT(A) assert(A)
#define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len))
#define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len))
#define DEBUGGER_OFF do { _dbug_on_= 0; } while(0)
#define DEBUGGER_ON do { _dbug_on_= 1; } while(0)
#ifndef _WIN32
#define DBUG_ABORT() (_db_flush_(), abort())
#else
#define DBUG_ABORT() (_db_flush_(), exit(3))
#endif
#else /* No debugger */ #else /* No debugger */
#define DBUG_ENTER(a1) #define DBUG_ENTER(a1)
#define DBUG_END() {}
#define DBUG_RETURN(a1) return(a1) #define DBUG_RETURN(a1) return(a1)
#define DBUG_VOID_RETURN return #define DBUG_VOID_RETURN return
#define DBUG_EXECUTE(keyword,a1) {} #define DBUG_EXECUTE(keyword,a1) {}

View File

@@ -326,13 +326,6 @@ typedef unsigned short ushort;
#define DBUG_OFF #define DBUG_OFF
#endif #endif
#include <dbug.h>
#ifndef DBUG_OFF
#define dbug_assert(A) assert(A)
#else
#define dbug_assert(A)
#endif
#define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/ #define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/
#define ASCII_BITS_USED 8 /* Bit char used */ #define ASCII_BITS_USED 8 /* Bit char used */
#define NEAR_F /* No near function handling */ #define NEAR_F /* No near function handling */
@@ -1061,6 +1054,13 @@ do { doubleget_union _tmp; \
#define SO_EXT ".so" #define SO_EXT ".so"
#endif #endif
#include <dbug.h>
#ifndef DBUG_OFF
#define dbug_assert(A) assert(A)
#else
#define dbug_assert(A)
#endif
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
#ifdef _WIN32 #ifdef _WIN32
#define dlsym(lib, name) GetProcAddress((HMODULE)lib, name) #define dlsym(lib, name) GetProcAddress((HMODULE)lib, name)

View File

@@ -551,6 +551,7 @@ struct st_my_thread_var
}; };
extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
extern void **my_thread_var_dbug();
#define my_thread_var (_my_thread_var()) #define my_thread_var (_my_thread_var())
#define my_errno my_thread_var->thr_errno #define my_errno my_thread_var->thr_errno

View File

@@ -70,6 +70,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
* as read(2) and write(2). * as read(2) and write(2).
*/ */
size_t vio_read(Vio* vio, gptr buf, size_t size); size_t vio_read(Vio* vio, gptr buf, size_t size);
my_bool vio_read_peek(Vio *vio, size_t *bytes);
size_t vio_write(Vio* vio, const gptr buf, size_t size); size_t vio_write(Vio* vio, const gptr buf, size_t size);
/* /*
* Whenever the socket is set to blocking mode or not. * Whenever the socket is set to blocking mode or not.

File diff suppressed because it is too large Load Diff

View File

@@ -702,11 +702,8 @@ append_wild(char *to, char *end, const char *wild)
void STDCALL mysql_debug_end() void STDCALL mysql_debug_end()
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
if (_db_on_) DEBUGGER_OFF;
{ DBUG_POP();
DEBUGGER_OFF;
DBUG_POP();
}
#endif #endif
} }
@@ -715,8 +712,6 @@ mysql_debug(const char *debug __attribute__((unused)))
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
char *env; char *env;
if (_db_on_)
return; /* Already using debugging */
if (debug) if (debug)
{ {
DEBUGGER_ON; DEBUGGER_ON;
@@ -1193,7 +1188,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
result->rows++; result->rows++;
if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc, if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
sizeof(MYSQL_ROWS))) || sizeof(MYSQL_ROWS))) ||
!(cur->data= ((MYSQL_ROW) !(cur->data= ((MYSQL_ROW)
alloc_root(&result->alloc, alloc_root(&result->alloc,
(fields+1)*sizeof(char *)+pkt_len)))) (fields+1)*sizeof(char *)+pkt_len))))
{ {
@@ -1209,11 +1204,11 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
{ {
if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH) if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
{ /* null field */ { /* null field */
cur->data[field] = 0; cur->data[field] = 0;
} }
else else
{ {
cur->data[field] = to; cur->data[field] = to;
if (len > (ulong) (end_to - to)) if (len > (ulong) (end_to - to))
{ {
free_rows(result); free_rows(result);
@@ -1565,8 +1560,9 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql,const char *host, const char *user,
if (hPipe == INVALID_HANDLE_VALUE) if (hPipe == INVALID_HANDLE_VALUE)
#endif #endif
{ {
struct addrinfo hints, *save_res, *res= 0; struct addrinfo hints, *save_res= 0, *res= 0;
char server_port[NI_MAXSERV]; char server_port[NI_MAXSERV];
int gai_rc;
int rc; int rc;
unix_socket=0; /* This is not used */ unix_socket=0; /* This is not used */
@@ -1575,6 +1571,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql,const char *host, const char *user,
if (!host) if (!host)
host=LOCAL_HOST; host=LOCAL_HOST;
sprintf(host_info=buff,ER(CR_TCP_CONNECTION),host); sprintf(host_info=buff,ER(CR_TCP_CONNECTION),host);
bzero(&server_port, NI_MAXSERV);
DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host,port)); DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host,port));
@@ -1587,30 +1584,32 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql,const char *host, const char *user,
hints.ai_socktype= SOCK_STREAM; hints.ai_socktype= SOCK_STREAM;
/* Get the address information for the server using getaddrinfo() */ /* Get the address information for the server using getaddrinfo() */
if ((rc= getaddrinfo(host, server_port, &hints, &res))) gai_rc= getaddrinfo(host, server_port, &hints, &res);
if (gai_rc != 0)
{ {
my_set_error(mysql, CR_UNKNOWN_HOST, SQLSTATE_UNKNOWN, my_set_error(mysql, CR_UNKNOWN_HOST, SQLSTATE_UNKNOWN,
ER(CR_UNKNOWN_HOST), host, rc); ER(CR_UNKNOWN_HOST), host, gai_rc);
goto error; goto error;
} }
/* res is a linked list of addresses. If connect to an address fails we will not return /* res is a linked list of addresses. If connect to an address fails we will not return
an error, instead we will try the next address */ an error, instead we will try the next address */
for (save_res= res; save_res; save_res= save_res->ai_next) for (save_res= res; save_res; save_res= save_res->ai_next)
{ {
if ((sock= (my_socket)socket(save_res->ai_family, sock= socket(save_res->ai_family, save_res->ai_socktype,
save_res->ai_socktype, save_res->ai_protocol);
save_res->ai_protocol)) == SOCKET_ERROR) if (sock == SOCKET_ERROR)
/* we do error handling after for loop only for last call */ /* we do error handling after for loop only for last call */
continue; continue;
if (!(net->vio= vio_new(sock, VIO_TYPE_TCPIP, FALSE))) if (!(net->vio= vio_new(sock, VIO_TYPE_TCPIP, FALSE)))
{ {
my_set_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0); my_set_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
closesocket(sock);
freeaddrinfo(res); freeaddrinfo(res);
goto error; goto error;
} }
if (!(rc= connect2(sock, save_res->ai_addr, save_res->ai_addrlen, if (!(rc= connect2(sock, save_res->ai_addr, save_res->ai_addrlen,
mysql->options.connect_timeout))) mysql->options.connect_timeout)))
break; /* success! */ break; /* success! */
vio_delete(mysql->net.vio); vio_delete(mysql->net.vio);
@@ -1629,7 +1628,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql,const char *host, const char *user,
if (rc) if (rc)
{ {
my_set_error(mysql, CR_CONN_HOST_ERROR, SQLSTATE_UNKNOWN, ER(CR_CONN_HOST_ERROR), my_set_error(mysql, CR_CONN_HOST_ERROR, SQLSTATE_UNKNOWN, ER(CR_CONN_HOST_ERROR),
unix_socket, socket_errno); host, rc);
goto error; goto error;
} }
} }
@@ -2031,6 +2030,7 @@ static void mysql_close_options(MYSQL *mysql)
my_free(mysql->options.extension->default_auth, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.extension->default_auth, MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr)mysql->options.extension->db_driver, MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr)mysql->options.extension->db_driver, MYF(MY_ALLOW_ZERO_PTR));
} }
my_free((gptr)mysql->options.extension, MYF(MY_ALLOW_ZERO_PTR));
/* clear all pointer */ /* clear all pointer */
memset(&mysql->options, 0, sizeof(mysql->options)); memset(&mysql->options, 0, sizeof(mysql->options));
} }

View File

@@ -162,10 +162,10 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
#endif #endif
} }
#ifdef THREAD #ifdef THREAD
pthread_mutex_destroy(&THR_LOCK_keycache);
pthread_mutex_destroy(&THR_LOCK_malloc); pthread_mutex_destroy(&THR_LOCK_malloc);
pthread_mutex_destroy(&THR_LOCK_open); pthread_mutex_destroy(&THR_LOCK_open);
DBUG_POP(); /* Must be done before my_thread_end */ pthread_mutex_destroy(&THR_LOCK_net);
DBUG_END(); /* Must be done before my_thread_end */
my_thread_end(); my_thread_end();
my_thread_global_end(); my_thread_global_end();
#endif #endif
@@ -244,7 +244,6 @@ static void my_win_init(void)
/* Crea la stringa d'ambiente */ /* Crea la stringa d'ambiente */
setEnvString(EnvString, NameValueBuffer, DataValueBuffer) ; setEnvString(EnvString, NameValueBuffer, DataValueBuffer) ;
/* Inserisce i dati come variabili d'ambiente */
my_env=strdup(EnvString); /* variable for putenv must be allocated ! */ my_env=strdup(EnvString); /* variable for putenv must be allocated ! */
putenv(my_env) ; putenv(my_env) ;

View File

@@ -30,9 +30,8 @@ pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
#else #else
pthread_key(struct st_my_thread_var, THR_KEY_mysys); pthread_key(struct st_my_thread_var, THR_KEY_mysys);
#endif /* USE_TLS */ #endif /* USE_TLS */
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache, pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap, THR_LOCK_lock, THR_LOCK_net, THR_LOCK_mysys;
THR_LOCK_net, THR_LOCK_charset;
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
pthread_mutex_t LOCK_ssl_config; pthread_mutex_t LOCK_ssl_config;
#endif #endif
@@ -48,6 +47,7 @@ pthread_mutexattr_t my_fast_mutexattr;
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
pthread_mutexattr_t my_errchk_mutexattr; pthread_mutexattr_t my_errchk_mutexattr;
#endif #endif
my_bool THR_KEY_mysys_initialized= FALSE;
/* FIXME Note. TlsAlloc does not set an auto destructor, so /* FIXME Note. TlsAlloc does not set an auto destructor, so
the function my_thread_global_free must be called from the function my_thread_global_free must be called from
@@ -69,18 +69,14 @@ my_bool my_thread_global_init(void)
pthread_mutexattr_setkind_np(&my_errchk_mutexattr, pthread_mutexattr_setkind_np(&my_errchk_mutexattr,
PTHREAD_MUTEX_ERRORCHECK_NP); PTHREAD_MUTEX_ERRORCHECK_NP);
#endif #endif
THR_KEY_mysys_initialized= TRUE;
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
pthread_mutex_init(&LOCK_ssl_config,MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_ssl_config,MY_MUTEX_INIT_FAST);
#endif #endif
pthread_mutex_init(&THR_LOCK_malloc,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_malloc,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_keycache,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW);
pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_SLOW);
pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST);
#ifdef _WIN32 #ifdef _WIN32
/* win_pthread_init(); */ /* win_pthread_init(); */
#endif #endif
@@ -163,6 +159,7 @@ void my_thread_end(void)
#if !defined(DBUG_OFF) #if !defined(DBUG_OFF)
if (tmp->dbug) if (tmp->dbug)
{ {
DBUG_POP();
free(tmp->dbug); free(tmp->dbug);
tmp->dbug=0; tmp->dbug=0;
} }
@@ -183,7 +180,6 @@ struct st_my_thread_var *_my_thread_var(void)
struct st_my_thread_var *tmp= struct st_my_thread_var *tmp=
my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
#if defined(USE_TLS) #if defined(USE_TLS)
/* This can only happen in a .DLL */
if (!tmp) if (!tmp)
{ {
my_thread_init(); my_thread_init();
@@ -230,6 +226,22 @@ const char *my_thread_name(void)
} }
return tmp->name; return tmp->name;
} }
extern void **my_thread_var_dbug()
{
struct st_my_thread_var *tmp;
/*
Instead of enforcing DBUG_ASSERT(THR_KEY_mysys_initialized) here,
which causes any DBUG_ENTER and related traces to fail when
used in init / cleanup code, we are more tolerant:
using DBUG_ENTER / DBUG_PRINT / DBUG_RETURN
when the dbug instrumentation is not in place will do nothing.
*/
if (! THR_KEY_mysys_initialized)
return NULL;
tmp= _my_thread_var();
return tmp && tmp->initialized ? &tmp->dbug : 0;
}
#endif /* DBUG_OFF */ #endif /* DBUG_OFF */
#endif /* THREAD */ #endif /* THREAD */

View File

@@ -174,22 +174,19 @@ static my_bool net_realloc(NET *net, size_t length)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
#if !defined(DBUG_OFF1) || defined(USE_NET_CLEAR) #ifdef DEBUG_SOCKET
static int net_check_if_data_available(Vio *vio) static ssize_t net_check_if_data_available(Vio *vio)
{ {
my_socket sd= vio->sd; ssize_t length= 0;
fd_set sockset;
struct timeval tv;
int rc;
FD_ZERO(&sockset); if (vio->type != VIO_TYPE_SOCKET &&
FD_SET(sd, &sockset); vio->type != VIO_TYPE_TCPIP)
memset(&tv, 0, sizeof(tv));
rc= select((int)(sd + 1), &sockset, NULL, NULL, &tv);
if (rc <= 0)
return 0; return 0;
return FD_ISSET(sd, &sockset);
if (vio_read_peek(vio, (size_t *)&length))
return -1;
return length;
} }
#endif #endif
@@ -197,45 +194,12 @@ static int net_check_if_data_available(Vio *vio)
void net_clear(NET *net) void net_clear(NET *net)
{ {
#if !defined(DBUG_OFF1) || defined(USE_NET_CLEAR)
int available= 0;
size_t count; /* One may get 'unused' warning */
bool is_blocking=vio_is_blocking(net->vio);
DBUG_ENTER("net_clear"); DBUG_ENTER("net_clear");
while ((available= net_check_if_data_available(net->vio)) > 0)
{
if ((long)(count= vio_read(net->vio, (char *)net->buff, net->max_packet)) > 0)
{
DBUG_PRINT("info",("skipped %d bytes from file: %s",
count,vio_description(net->vio)));
}
else
{
DBUG_PRINT("info", ("socket disconnected"));
net->error= 2;
break;
}
}
if (available == -1) #ifdef DEBUG_SOCKET
{ DBUG_ASSERT(net_check_if_data_available(net->vio) < 2);
if (is_blocking)
vio_blocking(net->vio, FALSE);
if (!vio_is_blocking(net->vio)) /* Safety if SSL */
{
while ( (count = vio_read(net->vio, (char*) (net->buff),
net->max_packet)) > 0)
DBUG_PRINT("info",("skipped %d bytes from file: %s",
count,vio_description(net->vio)));
if (is_blocking)
vio_blocking(net->vio, TRUE);
}
}
#else
DBUG_ENTER("net_clear");
#endif #endif
net->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */ net->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */
net->write_pos=net->buff; net->write_pos=net->buff;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;

View File

@@ -61,7 +61,7 @@
/* /*
* Memory sub-system, written by Bjorn Benson * Memory sub-system, written by Bjorn Benson
Fixed to use my_sys scheme by Michael Widenius Fixed to use my_sys scheme by Michael Widenius
*/ */
#ifndef SAFEMALLOC #ifndef SAFEMALLOC
@@ -82,10 +82,10 @@ ulonglong safemalloc_mem_limit = ~(ulonglong)0;
#define uDataSize tInt._uDataSize #define uDataSize tInt._uDataSize
#define lSpecialValue tInt._lSpecialValue #define lSpecialValue tInt._lSpecialValue
/* Static functions prototypes */ /* Static functions prototypes */
static int check_ptr(const char *where, unsigned char *ptr, const char *sFile, static int check_ptr(const char *where, unsigned char *ptr, const char *sFile,
uint uLine); uint uLine);
static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine); static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
/* /*
@@ -97,11 +97,11 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
*/ */
#define ALLOC_VAL (uchar) 0xA5 /* NEW'ed memory is filled with this */ #define ALLOC_VAL (uchar) 0xA5 /* NEW'ed memory is filled with this */
/* value so that references to it will */ /* value so that references to it will */
/* end up being very strange. */ /* end up being very strange. */
#define FREE_VAL (uchar) 0x8F /* FREE'ed memory is filled with this */ #define FREE_VAL (uchar) 0x8F /* FREE'ed memory is filled with this */
/* value so that references to it will */ /* value so that references to it will */
/* also end up being strange. */ /* also end up being strange. */
#define MAGICKEY 0x14235296 /* A magic value for underrun key */ #define MAGICKEY 0x14235296 /* A magic value for underrun key */
#define MAGICEND0 0x68 /* Magic values for overrun keys */ #define MAGICEND0 0x68 /* Magic values for overrun keys */
@@ -109,11 +109,11 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
#define MAGICEND2 0x7A /* " */ #define MAGICEND2 0x7A /* " */
#define MAGICEND3 0x15 /* " */ #define MAGICEND3 0x15 /* " */
/* Warning: do not change the MAGICEND? values to */ /* Warning: do not change the MAGICEND? values to */
/* something with the high bit set. Various C */ /* something with the high bit set. Various C */
/* compilers (like the 4.2bsd one) do not do the */ /* compilers (like the 4.2bsd one) do not do the */
/* sign extension right later on in this code and */ /* sign extension right later on in this code and */
/* you will get erroneous errors. */ /* you will get erroneous errors. */
/* /*
@@ -123,87 +123,87 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
gptr _mymalloc (size_t uSize, const char *sFile, uint uLine, myf MyFlags) gptr _mymalloc (size_t uSize, const char *sFile, uint uLine, myf MyFlags)
{ {
struct remember *pTmp; struct remember *pTmp;
DBUG_ENTER("_mymalloc"); DBUG_ENTER("_mymalloc");
DBUG_PRINT("enter",("Size: %u",uSize)); DBUG_PRINT("enter",("Size: %u",uSize));
if (!sf_malloc_quick) if (!sf_malloc_quick)
(void) _sanity (sFile, uLine); (void) _sanity (sFile, uLine);
if(uSize + lCurMemory > safemalloc_mem_limit) if(uSize + lCurMemory > safemalloc_mem_limit)
pTmp = 0; pTmp = 0;
else else
/* Allocate the physical memory */ /* Allocate the physical memory */
pTmp = (struct remember *) malloc ( pTmp = (struct remember *) malloc (
sizeof (struct irem) /* remember data */ sizeof (struct irem) /* remember data */
+ sf_malloc_prehunc + sf_malloc_prehunc
+ uSize /* size requested */ + uSize /* size requested */
+ 4 /* overrun mark */ + 4 /* overrun mark */
+ sf_malloc_endhunc + sf_malloc_endhunc
); );
/* Check if there isn't anymore memory avaiable */ /* Check if there isn't anymore memory avaiable */
if (pTmp == NULL) if (pTmp == NULL)
{
if (MyFlags & MY_FAE)
error_handler_hook=fatal_error_handler_hook;
if (MyFlags & (MY_FAE+MY_WME))
{ {
if (MyFlags & MY_FAE) char buff[SC_MAXWIDTH];
error_handler_hook=fatal_error_handler_hook; my_errno=errno;
if (MyFlags & (MY_FAE+MY_WME)) sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile);
{ my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
char buff[SC_MAXWIDTH]; sprintf(buff,"needed %ld byte (%ldk), memory in use: %lu bytes (%ldk)",
my_errno=errno; (long) uSize, (long) ((uSize + 1023L) / 1024L),
sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile); (long) lMaxMemory, (long) (lMaxMemory + 1023L) / 1024L);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
sprintf(buff,"needed %ld byte (%ldk), memory in use: %lu bytes (%ldk)",
(long) uSize, (long) ((uSize + 1023L) / 1024L),
(long) lMaxMemory, (long) (lMaxMemory + 1023L) / 1024L);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
}
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
lMaxMemory,uLine, sFile));
if (MyFlags & MY_FAE)
exit(1);
DBUG_RETURN ((gptr) NULL);
} }
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
lMaxMemory,uLine, sFile));
if (MyFlags & MY_FAE)
exit(1);
DBUG_RETURN ((gptr) NULL);
}
/* Fill up the structure */ /* Fill up the structure */
*((long*) ((char*) &pTmp -> lSpecialValue+sf_malloc_prehunc)) = MAGICKEY; *((long*) ((char*) &pTmp -> lSpecialValue+sf_malloc_prehunc)) = MAGICKEY;
pTmp -> aData[uSize + sf_malloc_prehunc+0] = MAGICEND0; pTmp -> aData[uSize + sf_malloc_prehunc+0] = MAGICEND0;
pTmp -> aData[uSize + sf_malloc_prehunc+1] = MAGICEND1; pTmp -> aData[uSize + sf_malloc_prehunc+1] = MAGICEND1;
pTmp -> aData[uSize + sf_malloc_prehunc+2] = MAGICEND2; pTmp -> aData[uSize + sf_malloc_prehunc+2] = MAGICEND2;
pTmp -> aData[uSize + sf_malloc_prehunc+3] = MAGICEND3; pTmp -> aData[uSize + sf_malloc_prehunc+3] = MAGICEND3;
pTmp -> sFileName = (my_string) sFile; pTmp -> sFileName = (my_string) sFile;
pTmp -> uLineNum = uLine; pTmp -> uLineNum = uLine;
pTmp -> uDataSize = uSize; pTmp -> uDataSize = uSize;
pTmp -> pPrev = NULL; pTmp -> pPrev = NULL;
/* Add this remember structure to the linked list */ /* Add this remember structure to the linked list */
pthread_mutex_lock(&THR_LOCK_malloc); pthread_mutex_lock(&THR_LOCK_malloc);
if ((pTmp->pNext=pRememberRoot)) if ((pTmp->pNext=pRememberRoot))
{ {
pRememberRoot -> pPrev = pTmp; pRememberRoot -> pPrev = pTmp;
} }
pRememberRoot = pTmp; pRememberRoot = pTmp;
/* Keep the statistics */ /* Keep the statistics */
lCurMemory += uSize; lCurMemory += uSize;
if (lCurMemory > lMaxMemory) { if (lCurMemory > lMaxMemory) {
lMaxMemory = lCurMemory; lMaxMemory = lCurMemory;
} }
cNewCount++; cNewCount++;
pthread_mutex_unlock(&THR_LOCK_malloc); pthread_mutex_unlock(&THR_LOCK_malloc);
/* Set the memory to the aribtrary wierd value */ /* Set the memory to the aribtrary wierd value */
if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick) if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
bfill(&pTmp -> aData[sf_malloc_prehunc],uSize, bfill(&pTmp -> aData[sf_malloc_prehunc],uSize,
(char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL)); (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
/* Return a pointer to the real data */ /* Return a pointer to the real data */
DBUG_PRINT("exit",("ptr: %lx",&(pTmp -> aData[sf_malloc_prehunc]))); DBUG_PRINT("exit",("ptr: %lx",&(pTmp -> aData[sf_malloc_prehunc])));
if (sf_min_adress > (unsigned char *)&(pTmp -> aData[sf_malloc_prehunc])) if (sf_min_adress > (unsigned char *)&(pTmp -> aData[sf_malloc_prehunc]))
sf_min_adress = &(pTmp -> aData[sf_malloc_prehunc]); sf_min_adress = &(pTmp -> aData[sf_malloc_prehunc]);
if (sf_max_adress < (unsigned char *)&(pTmp -> aData[sf_malloc_prehunc])) if (sf_max_adress < (unsigned char *)&(pTmp -> aData[sf_malloc_prehunc]))
sf_max_adress = &(pTmp -> aData[sf_malloc_prehunc]); sf_max_adress = &(pTmp -> aData[sf_malloc_prehunc]);
DBUG_RETURN ((gptr) &(pTmp -> aData[sf_malloc_prehunc])); DBUG_RETURN ((gptr) &(pTmp -> aData[sf_malloc_prehunc]));
} }
/* /*
@@ -212,7 +212,7 @@ gptr _mymalloc (size_t uSize, const char *sFile, uint uLine, myf MyFlags)
*/ */
gptr _myrealloc (register gptr pPtr, register size_t uSize, gptr _myrealloc (register gptr pPtr, register size_t uSize,
const char *sFile, uint uLine, myf MyFlags) const char *sFile, uint uLine, myf MyFlags)
{ {
struct remember *pRec; struct remember *pRec;
gptr ptr; gptr ptr;
@@ -228,14 +228,14 @@ gptr _myrealloc (register gptr pPtr, register size_t uSize,
DBUG_RETURN((gptr) NULL); DBUG_RETURN((gptr) NULL);
pRec = (struct remember *) ((char*) pPtr - sizeof (struct irem)- pRec = (struct remember *) ((char*) pPtr - sizeof (struct irem)-
sf_malloc_prehunc); sf_malloc_prehunc);
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY) != MAGICKEY)
{ {
fprintf (stderr, "Reallocating unallocated data at line %d, '%s'\n", fprintf (stderr, "Reallocating unallocated data at line %d, '%s'\n",
uLine, sFile); uLine, sFile);
DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'", DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'",
uLine, sFile)); uLine, sFile));
(void) fflush(stderr); (void) fflush(stderr);
DBUG_RETURN((gptr) NULL); DBUG_RETURN((gptr) NULL);
} }
@@ -277,7 +277,7 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
/* Calculate the address of the remember structure */ /* Calculate the address of the remember structure */
pRec = (struct remember *) ((unsigned char*) pPtr-sizeof(struct irem)- pRec = (struct remember *) ((unsigned char*) pPtr-sizeof(struct irem)-
sf_malloc_prehunc); sf_malloc_prehunc);
/* Check to make sure that we have a real remember structure */ /* Check to make sure that we have a real remember structure */
/* Note: this test could fail for four reasons: */ /* Note: this test could fail for four reasons: */
@@ -290,7 +290,7 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
!= MAGICKEY) != MAGICKEY)
{ {
fprintf (stderr, "Freeing unallocated data at line %d, '%s'\n", fprintf (stderr, "Freeing unallocated data at line %d, '%s'\n",
uLine, sFile); uLine, sFile);
DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile)); DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile));
(void) fflush(stderr); (void) fflush(stderr);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@@ -323,15 +323,15 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* Check if we have a wrong pointer */ /* Check if we have a wrong pointer */
static int check_ptr(const char *where, unsigned char *ptr, const char *sFile, static int check_ptr(const char *where, unsigned char *ptr, const char *sFile,
uint uLine) uint uLine)
{ {
if (!ptr) if (!ptr)
{ {
fprintf (stderr, "%s NULL pointer at line %d, '%s'\n", fprintf (stderr, "%s NULL pointer at line %d, '%s'\n",
where,uLine, sFile); where,uLine, sFile);
DBUG_PRINT("safe",("Null pointer at line %d '%s'", uLine, sFile)); DBUG_PRINT("safe",("Null pointer at line %d '%s'", uLine, sFile));
(void) fflush(stderr); (void) fflush(stderr);
return 1; return 1;
@@ -340,9 +340,9 @@ static int check_ptr(const char *where, unsigned char *ptr, const char *sFile,
if ((long) ptr & (MY_ALIGN(1,sizeof(char *))-1)) if ((long) ptr & (MY_ALIGN(1,sizeof(char *))-1))
{ {
fprintf (stderr, "%s wrong aligned pointer at line %d, '%s'\n", fprintf (stderr, "%s wrong aligned pointer at line %d, '%s'\n",
where,uLine, sFile); where,uLine, sFile);
DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'", DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'",
uLine,sFile)); uLine,sFile));
(void) fflush(stderr); (void) fflush(stderr);
return 1; return 1;
} }
@@ -350,9 +350,9 @@ static int check_ptr(const char *where, unsigned char *ptr, const char *sFile,
if (ptr < sf_min_adress || ptr > sf_max_adress) if (ptr < sf_min_adress || ptr > sf_max_adress)
{ {
fprintf (stderr, "%s pointer out of range at line %d, '%s'\n", fprintf (stderr, "%s pointer out of range at line %d, '%s'\n",
where,uLine, sFile); where,uLine, sFile);
DBUG_PRINT("safe",("Pointer out of range at line %d '%s'", DBUG_PRINT("safe",("Pointer out of range at line %d '%s'",
uLine,sFile)); uLine,sFile));
(void) fflush(stderr); (void) fflush(stderr);
return 1; return 1;
} }
@@ -401,17 +401,16 @@ void TERMINATE (FILE *file)
{ {
if (file) if (file)
{ {
fprintf (file, fprintf (file,
"\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'\n", "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'\n",
pPtr -> uDataSize, pPtr -> uDataSize,
(ulong) &(pPtr -> aData[sf_malloc_prehunc]), (ulong) &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr -> sFileName); pPtr -> uLineNum, pPtr -> sFileName);
(void) fflush(file); (void) fflush(file);
} }
DBUG_PRINT("safe", DBUG_PRINT("safe", ("%6u bytes at 0x%09lx, allocated at line %4u in '%s'",
("%6u bytes at 0x%09lx, allocated at line %4d in '%s'", pPtr -> uDataSize, (ulong) &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uDataSize, &(pPtr -> aData[sf_malloc_prehunc]), pPtr -> uLineNum, pPtr->sFileName));
pPtr -> uLineNum, pPtr -> sFileName));
pPtr = pPtr -> pNext; pPtr = pPtr -> pNext;
} }
} }
@@ -419,20 +418,20 @@ void TERMINATE (FILE *file)
if (file) if (file)
{ {
fprintf (file, "Maximum memory usage: %zu bytes (%ldk)\n", fprintf (file, "Maximum memory usage: %zu bytes (%ldk)\n",
lMaxMemory, (lMaxMemory + 1023L) / 1024L); lMaxMemory, (lMaxMemory + 1023L) / 1024L);
(void) fflush(file); (void) fflush(file);
} }
DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)", DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)",
lMaxMemory, (lMaxMemory + 1023L) / 1024L)); lMaxMemory, (lMaxMemory + 1023L) / 1024L));
pthread_mutex_unlock(&THR_LOCK_malloc); pthread_mutex_unlock(&THR_LOCK_malloc);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* Returns 0 if chunk is ok */ /* Returns 0 if chunk is ok */
static int _checkchunk (register struct remember *pRec, const char *sFile, static int _checkchunk (register struct remember *pRec, const char *sFile,
uint uLine) uint uLine)
{ {
reg1 size_t uSize; reg1 size_t uSize;
reg2 my_string magicp; reg2 my_string magicp;
@@ -443,13 +442,13 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
!= MAGICKEY) != MAGICKEY)
{ {
fprintf (stderr, "Memory allocated at %s:%d was underrun,", fprintf (stderr, "Memory allocated at %s:%d was underrun,",
pRec -> sFileName, pRec -> uLineNum); pRec -> sFileName, pRec -> uLineNum);
fprintf (stderr, " discovered at %s:%d\n", sFile, uLine); fprintf (stderr, " discovered at %s:%d\n", sFile, uLine);
(void) fflush(stderr); (void) fflush(stderr);
DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d", DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]), &(pRec -> aData[sf_malloc_prehunc]),
pRec -> sFileName, pRec -> sFileName,
pRec -> uLineNum)); pRec -> uLineNum));
flag=1; flag=1;
} }
@@ -462,20 +461,20 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
*magicp++ != MAGICEND3) *magicp++ != MAGICEND3)
{ {
fprintf (stderr, "Memory allocated at %s:%d was overrun,", fprintf (stderr, "Memory allocated at %s:%d was overrun,",
pRec -> sFileName, pRec -> uLineNum); pRec -> sFileName, pRec -> uLineNum);
fprintf (stderr, " discovered at '%s:%d'\n", sFile, uLine); fprintf (stderr, " discovered at '%s:%d'\n", sFile, uLine);
(void) fflush(stderr); (void) fflush(stderr);
DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d", DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]), &(pRec -> aData[sf_malloc_prehunc]),
pRec -> sFileName, pRec -> sFileName,
pRec -> uLineNum)); pRec -> uLineNum));
flag=1; flag=1;
} }
return(flag); return(flag);
} }
/* Returns how many wrong chunks */ /* Returns how many wrong chunks */
int _sanity (const char *sFile, uint uLine) int _sanity (const char *sFile, uint uLine)
{ {
@@ -500,10 +499,10 @@ int _sanity (const char *sFile, uint uLine)
} /* _sanity */ } /* _sanity */
/* malloc and copy */ /* malloc and copy */
gptr _my_memdup(const unsigned char *from, size_t length, const char *sFile, uint uLine, gptr _my_memdup(const unsigned char *from, size_t length, const char *sFile, uint uLine,
myf MyFlags) myf MyFlags)
{ {
gptr ptr; gptr ptr;
if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0) if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0)
@@ -513,7 +512,7 @@ gptr _my_memdup(const unsigned char *from, size_t length, const char *sFile, uin
my_string _my_strdup(const char *from, const char *sFile, uint uLine, my_string _my_strdup(const char *from, const char *sFile, uint uLine,
myf MyFlags) myf MyFlags)
{ {
gptr ptr; gptr ptr;
size_t length= strlen(from)+1; size_t length= strlen(from)+1;

View File

@@ -228,6 +228,28 @@ size_t vio_read(Vio * vio, gptr buf, size_t size)
DBUG_RETURN(r); DBUG_RETURN(r);
} }
/*
Return data from the beginning of the receive queue without removing
that data from the queue. A subsequent receive call will return the same data.
*/
my_bool vio_read_peek(Vio *vio, size_t *bytes)
{
#ifdef _WIN32
if (ioctlsocket(vio->sd, FIONREAD, bytes))
return TRUE;
#else
char buffer[1024];
ssize_t length;
vio_blocking(vio, 0);
length= recv(vio->sd, &buffer, sizeof(buffer), MSG_PEEK);
if (length < 0)
return TRUE;
*bytes= length;
#endif
return FALSE;
}
size_t vio_write(Vio * vio, const gptr buf, size_t size) size_t vio_write(Vio * vio, const gptr buf, size_t size)
{ {

View File

@@ -80,7 +80,7 @@ static int use_utf8(MYSQL *my)
FAIL_IF(strcmp(row[0], "utf8"), "wrong character set"); FAIL_IF(strcmp(row[0], "utf8"), "wrong character set");
} }
FAIL_IF(mysql_errno(my), mysql_error(my)); FAIL_IF(mysql_errno(my), mysql_error(my));
mysql_free_result(res);
return OK; return OK;
} }
@@ -573,7 +573,6 @@ struct my_tests_st my_tests[] = {
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc > 1) if (argc > 1)
get_options(argc, argv); get_options(argc, argv);

View File

@@ -33,6 +33,7 @@ static int basic_connect(MYSQL *mysql)
mysql_free_result(res); mysql_free_result(res);
mysql_close(my); mysql_close(my);
return OK; return OK;
} }
@@ -44,7 +45,7 @@ int thread_conc27(void);
DWORD WINAPI thread_conc27(void); DWORD WINAPI thread_conc27(void);
#endif #endif
#define THREAD_NUM 100 #define THREAD_NUM 150
static int test_conc_27(MYSQL *mysql) static int test_conc_27(MYSQL *mysql)
{ {
@@ -100,7 +101,7 @@ static int test_conc_27(MYSQL *mysql)
FAIL_IF(!row, "can't fetch row"); FAIL_IF(!row, "can't fetch row");
diag("row=%s", row[0]); diag("row=%s", row[0]);
FAIL_IF(atoi(row[0]) != 100, "expected value 100"); FAIL_IF(atoi(row[0]) != THREAD_NUM, "expected value THREAD_NUM");
mysql_free_result(res); mysql_free_result(res);
return OK; return OK;
@@ -113,10 +114,13 @@ DWORD WINAPI thread_conc27(void)
#endif #endif
{ {
MYSQL *mysql; MYSQL *mysql;
int rc; int rc, i;
char *hname[]= {"localhost", "127.0.0.1", NULL};
mysql_thread_init(); mysql_thread_init();
mysql= mysql_init(NULL); mysql= mysql_init(NULL);
if(!mysql_real_connect(mysql, hostname, username, password, schema, i= rand() % 3;
diag("Connecting to %s", hname[i]);
if(!mysql_real_connect(mysql, hname[i], username, password, schema,
port, socketname, 0)) port, socketname, 0))
{ {
diag("Error: %s", mysql_error(mysql)); diag("Error: %s", mysql_error(mysql));
@@ -128,8 +132,8 @@ DWORD WINAPI thread_conc27(void)
rc= mysql_query(mysql, "UPDATE t_conc27 SET a=a+1"); rc= mysql_query(mysql, "UPDATE t_conc27 SET a=a+1");
check_mysql_rc(rc, mysql); check_mysql_rc(rc, mysql);
pthread_mutex_unlock(&LOCK_test); pthread_mutex_unlock(&LOCK_test);
mysql_close(mysql);
mysql_thread_end(); mysql_thread_end();
mysql_close(mysql);
end: end:
mysql_thread_end(); mysql_thread_end();
return 0; return 0;
@@ -146,9 +150,6 @@ int main(int argc, char **argv)
{ {
mysql_library_init(0,0,NULL); mysql_library_init(0,0,NULL);
mysql_thread_init();
mysql_thread_end();
mysql_library_end();
if (argc > 1) if (argc > 1)
get_options(argc, argv); get_options(argc, argv);
@@ -157,5 +158,6 @@ int main(int argc, char **argv)
run_tests(my_tests); run_tests(my_tests);
mysql_server_end();
return(exit_status()); return(exit_status());
} }