Don't abort if we call my_thread_end() multiple times
Fixed new introduced bug in my_time.c
This commit is contained in:
parent
3a35c30027
commit
0a673596a2
@ -1,189 +0,0 @@
|
|||||||
#
|
|
||||||
# Suppress some common (not fatal) errors in system libraries found by valgrind
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Pthread doesn't free all thread specific memory before program exists
|
|
||||||
#
|
|
||||||
{
|
|
||||||
pthread allocate_tls memory loss
|
|
||||||
Memcheck:Leak
|
|
||||||
fun:calloc
|
|
||||||
fun:_dl_allocate_tls
|
|
||||||
fun:allocate_stack
|
|
||||||
fun:pthread_create@@GLIBC_2.1
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
pthread allocate_dtv memory loss
|
|
||||||
Memcheck:Leak
|
|
||||||
fun:calloc
|
|
||||||
fun:allocate_dtv
|
|
||||||
fun:_dl_allocate_tls_storage
|
|
||||||
fun:__GI__dl_allocate_tls
|
|
||||||
fun:pthread_create
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
pthread allocate_dtv memory loss second
|
|
||||||
Memcheck:Leak
|
|
||||||
fun:calloc
|
|
||||||
fun:allocate_dtv
|
|
||||||
fun:_dl_allocate_tls
|
|
||||||
fun:pthread_create*
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
pthread allocate_dtv memory loss second
|
|
||||||
Memcheck:Leak
|
|
||||||
fun:calloc
|
|
||||||
fun:allocate_dtv
|
|
||||||
fun:_dl_allocate_tls
|
|
||||||
fun:pthread_create*
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
pthread memalign memory loss
|
|
||||||
Memcheck:Leak
|
|
||||||
fun:memalign
|
|
||||||
fun:_dl_allocate_tls_storage
|
|
||||||
fun:__GI__dl_allocate_tls
|
|
||||||
fun:pthread_create
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
pthread pthread_key_create
|
|
||||||
Memcheck:Leak
|
|
||||||
fun:malloc
|
|
||||||
fun:*
|
|
||||||
fun:*
|
|
||||||
fun:pthread_key_create
|
|
||||||
fun:my_thread_global_init
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
pthread strstr uninit
|
|
||||||
Memcheck:Cond
|
|
||||||
fun:strstr
|
|
||||||
obj:/lib/tls/libpthread.so.*
|
|
||||||
obj:/lib/tls/libpthread.so.*
|
|
||||||
fun:call_init
|
|
||||||
fun:_dl_init
|
|
||||||
obj:/lib/ld-*.so
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
pthread strstr uninit
|
|
||||||
Memcheck:Cond
|
|
||||||
fun:strstr
|
|
||||||
obj:/lib/tls/libpthread.so.*
|
|
||||||
obj:/lib/tls/libpthread.so.*
|
|
||||||
fun:call_init
|
|
||||||
fun:_dl_init
|
|
||||||
obj:/lib/ld-*.so
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
pthread errno
|
|
||||||
Memcheck:Leak
|
|
||||||
fun:calloc
|
|
||||||
fun:_dlerror_run
|
|
||||||
fun:dlsym
|
|
||||||
fun:__errno_location
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Warnings in libz becasue it works with aligned memory(?)
|
|
||||||
#
|
|
||||||
|
|
||||||
{
|
|
||||||
libz tr_flush_block
|
|
||||||
Memcheck:Cond
|
|
||||||
fun:_tr_flush_block
|
|
||||||
fun:deflate_slow
|
|
||||||
fun:deflate
|
|
||||||
fun:do_flush
|
|
||||||
fun:gzclose
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
libz tr_flush_block2
|
|
||||||
Memcheck:Cond
|
|
||||||
fun:_tr_flush_block
|
|
||||||
fun:deflate_slow
|
|
||||||
fun:deflate
|
|
||||||
fun:compress2
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
libz longest_match
|
|
||||||
Memcheck:Cond
|
|
||||||
fun:longest_match
|
|
||||||
fun:deflate_slow
|
|
||||||
fun:deflate
|
|
||||||
fun:do_flush
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
libz longest_match2
|
|
||||||
Memcheck:Cond
|
|
||||||
fun:longest_match
|
|
||||||
fun:deflate_slow
|
|
||||||
fun:deflate
|
|
||||||
fun:compress2
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
libz deflate
|
|
||||||
Memcheck:Cond
|
|
||||||
obj:*/libz.so.*
|
|
||||||
obj:*/libz.so.*
|
|
||||||
fun:deflate
|
|
||||||
fun:compress2
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
libz deflate2
|
|
||||||
Memcheck:Cond
|
|
||||||
obj:*/libz.so.*
|
|
||||||
obj:*/libz.so.*
|
|
||||||
fun:deflate
|
|
||||||
obj:*/libz.so.*
|
|
||||||
fun:gzflush
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
libz deflate3
|
|
||||||
Memcheck:Cond
|
|
||||||
obj:*/libz.so.*
|
|
||||||
obj:*/libz.so.*
|
|
||||||
fun:deflate
|
|
||||||
fun:do_flush
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
# Warning from my_thread_init becasue mysqld dies before kill thread exists
|
|
||||||
#
|
|
||||||
|
|
||||||
{
|
|
||||||
my_thread_init kill thread memory loss second
|
|
||||||
Memcheck:Leak
|
|
||||||
fun:calloc
|
|
||||||
fun:my_thread_init
|
|
||||||
fun:kill_server_thread
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
# Warning when printing stack trace (to suppress some not needed warnings)
|
|
||||||
#
|
|
||||||
|
|
||||||
{
|
|
||||||
vprintf on stacktrace
|
|
||||||
Memcheck:Cond
|
|
||||||
fun:vfprintf
|
|
||||||
fun:uffered_vfprintf
|
|
||||||
fun:vfprintf
|
|
||||||
fun:fprintf
|
|
||||||
fun:print_stacktrace
|
|
||||||
}
|
|
@ -120,20 +120,22 @@ my_bool my_thread_global_init(void)
|
|||||||
void my_thread_global_end(void)
|
void my_thread_global_end(void)
|
||||||
{
|
{
|
||||||
struct timespec abstime;
|
struct timespec abstime;
|
||||||
set_timespec(abstime, my_thread_end_wait_time);
|
|
||||||
my_bool all_threads_killed= 1;
|
my_bool all_threads_killed= 1;
|
||||||
|
|
||||||
|
set_timespec(abstime, my_thread_end_wait_time);
|
||||||
pthread_mutex_lock(&THR_LOCK_threads);
|
pthread_mutex_lock(&THR_LOCK_threads);
|
||||||
while (THR_thread_count)
|
while (THR_thread_count > 0)
|
||||||
{
|
{
|
||||||
int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
|
int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
|
||||||
&abstime);
|
&abstime);
|
||||||
if (error == ETIMEDOUT || error == ETIME)
|
if (error == ETIMEDOUT || error == ETIME)
|
||||||
{
|
{
|
||||||
if (THR_thread_count)
|
if (THR_thread_count)
|
||||||
fprintf(stderr,"error in my_thread_global_end(): %d threads didn't exit\n",
|
fprintf(stderr,
|
||||||
|
"Error in my_thread_global_end(): %d threads didn't exit\n",
|
||||||
THR_thread_count);
|
THR_thread_count);
|
||||||
all_threads_killed= 0;
|
all_threads_killed= 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&THR_LOCK_threads);
|
pthread_mutex_unlock(&THR_LOCK_threads);
|
||||||
@ -169,10 +171,23 @@ void my_thread_global_end(void)
|
|||||||
static long thread_id=0;
|
static long thread_id=0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We can't use mutex_locks here if we are using windows as
|
Allocate thread specific memory for the thread, used by mysys and dbug
|
||||||
we may have compiled the program with SAFE_MUTEX, in which
|
|
||||||
case the checking of mutex_locks will not work until
|
SYNOPSIS
|
||||||
the pthread_self thread specific variable is initialized.
|
my_thread_init()
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
We can't use mutex_locks here if we are using windows as
|
||||||
|
we may have compiled the program with SAFE_MUTEX, in which
|
||||||
|
case the checking of mutex_locks will not work until
|
||||||
|
the pthread_self thread specific variable is initialized.
|
||||||
|
|
||||||
|
This function may called multiple times for a thread, for example
|
||||||
|
if one uses my_init() followed by mysql_server_init().
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 Fatal error; mysys/dbug functions can't be used
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool my_thread_init(void)
|
my_bool my_thread_init(void)
|
||||||
@ -224,14 +239,26 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Deallocate memory used by the thread for book-keeping
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_thread_end()
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
This may be called multiple times for a thread.
|
||||||
|
This happens for example when one calls 'mysql_server_init()'
|
||||||
|
mysql_server_end() and then ends with a mysql_end().
|
||||||
|
*/
|
||||||
|
|
||||||
void my_thread_end(void)
|
void my_thread_end(void)
|
||||||
{
|
{
|
||||||
struct st_my_thread_var *tmp;
|
struct st_my_thread_var *tmp;
|
||||||
tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
|
tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
|
||||||
|
|
||||||
#ifdef EXTRA_DEBUG_THREADS
|
#ifdef EXTRA_DEBUG_THREADS
|
||||||
fprintf(stderr,"my_thread_end(): tmp=%p,thread_id=%ld\n",
|
fprintf(stderr,"my_thread_end(): tmp: 0x%lx thread_id=%ld\n",
|
||||||
tmp,pthread_self());
|
(long) tmp, pthread_self());
|
||||||
#endif
|
#endif
|
||||||
if (tmp && tmp->init)
|
if (tmp && tmp->init)
|
||||||
{
|
{
|
||||||
@ -253,15 +280,23 @@ void my_thread_end(void)
|
|||||||
#else
|
#else
|
||||||
tmp->init= 0;
|
tmp->init= 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Decrement counter for number of running threads. We are using this
|
||||||
|
in my_thread_global_end() to wait until all threads have called
|
||||||
|
my_thread_end and thus freed all memory they have allocated in
|
||||||
|
my_thread_init() and DBUG_xxxx
|
||||||
|
*/
|
||||||
|
pthread_mutex_lock(&THR_LOCK_threads);
|
||||||
|
DBUG_ASSERT(THR_thread_count != 0);
|
||||||
|
if (--THR_thread_count == 0)
|
||||||
|
pthread_cond_signal(&THR_COND_threads);
|
||||||
|
pthread_mutex_unlock(&THR_LOCK_threads);
|
||||||
}
|
}
|
||||||
/* The following free has to be done, even if my_thread_var() is 0 */
|
/* The following free has to be done, even if my_thread_var() is 0 */
|
||||||
#if !defined(__WIN__) || defined(USE_TLS)
|
#if !defined(__WIN__) || defined(USE_TLS)
|
||||||
pthread_setspecific(THR_KEY_mysys,0);
|
pthread_setspecific(THR_KEY_mysys,0);
|
||||||
#endif
|
#endif
|
||||||
pthread_mutex_lock(&THR_LOCK_threads);
|
|
||||||
if (--THR_thread_count == 0)
|
|
||||||
pthread_cond_signal(&THR_COND_threads);
|
|
||||||
pthread_mutex_unlock(&THR_LOCK_threads);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct st_my_thread_var *_my_thread_var(void)
|
struct st_my_thread_var *_my_thread_var(void)
|
||||||
|
@ -547,9 +547,9 @@ my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
|
|||||||
{
|
{
|
||||||
/* String given as one number; assume HHMMSS format */
|
/* String given as one number; assume HHMMSS format */
|
||||||
date[0]= 0;
|
date[0]= 0;
|
||||||
date[1]= ((ulong) value)/10000;
|
date[1]= (ulong) (value/10000);
|
||||||
date[2]= ((ulong) value)/100 % 100;
|
date[2]= (ulong) (value/100 % 100);
|
||||||
date[3]= ((ulong) value) % 100;
|
date[3]= (ulong) (value % 100);
|
||||||
state=4;
|
state=4;
|
||||||
goto fractional;
|
goto fractional;
|
||||||
}
|
}
|
||||||
|
@ -1039,7 +1039,6 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
|||||||
while (sql[i]=='(')
|
while (sql[i]=='(')
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Test if the query is a SELECT
|
Test if the query is a SELECT
|
||||||
(pre-space is removed in dispatch_command).
|
(pre-space is removed in dispatch_command).
|
||||||
@ -1051,7 +1050,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
|||||||
if ((my_toupper(system_charset_info, sql[i]) != 'S' ||
|
if ((my_toupper(system_charset_info, sql[i]) != 'S' ||
|
||||||
my_toupper(system_charset_info, sql[i + 1]) != 'E' ||
|
my_toupper(system_charset_info, sql[i + 1]) != 'E' ||
|
||||||
my_toupper(system_charset_info, sql[i + 2]) != 'L') &&
|
my_toupper(system_charset_info, sql[i + 2]) != 'L') &&
|
||||||
sql[0] != '/')
|
sql[i] != '/')
|
||||||
{
|
{
|
||||||
DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
|
DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -1743,9 +1743,9 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
|
|||||||
tz_leapcnt++;
|
tz_leapcnt++;
|
||||||
|
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
("time_zone_leap_second table: tz_leapcnt:%u tt_time: %lu offset: %ld",
|
("time_zone_leap_second table: tz_leapcnt: %u tt_time: %lu offset: %ld",
|
||||||
tz_leapcnt, (ulong) tz_lsis[tz_leapcnt-1].ls_trans,
|
tz_leapcnt, (ulong) tz_lsis[tz_leapcnt-1].ls_trans,
|
||||||
tz_lsis[tz_leapcnt-1].ls_corr));
|
tz_lsis[tz_leapcnt-1].ls_corr));
|
||||||
|
|
||||||
res= table->file->index_next(table->record[0]);
|
res= table->file->index_next(table->record[0]);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user