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_; struct _db_stack_frame_ {
extern char *_db_process_; const char *func; /* function name of the previous stack frame */
extern int _db_keyword_(const char *keyword); const char *file; /* filename of the function of previous frame */
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_setjmp_(void);
extern void _db_longjmp_(void); extern void _db_longjmp_(void);
extern void _db_process_(const char *name);
extern void _db_push_(const char *control); extern void _db_push_(const char *control);
extern void _db_pop_(void); 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_, extern void _db_enter_(const char *_func_, const char *_file_, uint _line_,
const char **_sfunc_,const char **_sfile_, struct _db_stack_frame_ *_stack_frame_);
uint *_slevel_, char ***); extern void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_);
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_pargs_(uint _line_,const char *keyword);
extern void _db_doprnt_ _VARARGS((const char *format,...)); extern void _db_doprnt_ _VARARGS((const char *format,...));
extern void _db_dump_(uint _line_,const char *keyword,const char *memory, extern void _db_dump_(uint _line_,const char *keyword,
uint length); const unsigned char *memory, size_t length);
extern void _db_lock_file(void); extern void _db_end_(void);
extern void _db_unlock_file(void); 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_; \ extern FILE *_db_fp_(void);
char **_db_framep_; \ extern void _db_flush_();
_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \ extern const char* _db_get_func_(void);
&_db_framep_) /*
#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; DEBUGGER_OFF;
DBUG_POP(); 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;
@@ -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,10 +1584,11 @@ 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;
} }
@@ -1598,14 +1596,15 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql,const char *host, const char *user,
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;
} }
@@ -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

@@ -408,9 +408,8 @@ void TERMINATE (FILE *file)
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;
} }

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());
} }