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) DBUG_ENTER("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"); #ifdef DEBUG_SOCKET
while ((available= net_check_if_data_available(net->vio)) > 0) DBUG_ASSERT(net_check_if_data_available(net->vio) < 2);
{
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)
{
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

@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -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());
} }