From 42fd48da99b2ba2641697ebb567af555fb270e9e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 29 Nov 2006 22:14:08 +0200 Subject: Ignore some generated files Don't return from my_thread_global_end() until all threads have called my_thread_end() Bug#24387: Valgrind: my_thread_init (handle_sl sql, handle_one_conn, handle_slave_io) BitKeeper/etc/ignore: added *.gcda *.gcno include/my_pthread.h: Added my_thread_end_wait_time Removed not used thread variables mysys/my_thr_init.c: Add thread counters. Don't return from my_thread_global_end() until all threads have called my_thread_end() (Or a timeout (5 seconds) has elapsed) This fixed some valgrind warnings Bug#24387: Valgrind: my_thread_init (handle_sl sql, handle_one_conn, handle_slave_io) --- mysys/my_thr_init.c | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'mysys/my_thr_init.c') diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 4d23d01cd82..7800edd700d 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -30,7 +30,10 @@ pthread_key(struct st_my_thread_var, THR_KEY_mysys); #endif /* USE_TLS */ pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open, THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap, - THR_LOCK_net, THR_LOCK_charset; + THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads; +pthread_cond_t THR_COND_threads; +uint THR_thread_count= 0; +uint my_thread_end_wait_time= 5; #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) pthread_mutex_t LOCK_localtime_r; #endif @@ -79,7 +82,7 @@ my_bool my_thread_global_init(void) #endif #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP /* - Set mutex type to "errorcheck" a.k.a "adaptive" + Set mutex type to "errorcheck" */ pthread_mutexattr_init(&my_errorcheck_mutexattr); pthread_mutexattr_settype(&my_errorcheck_mutexattr, @@ -94,6 +97,8 @@ my_bool my_thread_global_init(void) 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_charset,MY_MUTEX_INIT_FAST); + pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST); + pthread_cond_init (&THR_COND_threads, NULL); #if defined( __WIN__) || defined(OS2) win_pthread_init(); #endif @@ -114,6 +119,25 @@ my_bool my_thread_global_init(void) void my_thread_global_end(void) { + struct timespec abstime; + set_timespec(abstime, my_thread_end_wait_time); + my_bool all_threads_killed= 1; + + pthread_mutex_lock(&THR_LOCK_threads); + while (THR_thread_count) + { + int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads, + &abstime); + if (error == ETIMEDOUT || error == ETIME) + { + if (THR_thread_count) + fprintf(stderr,"error in my_thread_global_end(): %d threads didn't exit\n", + THR_thread_count); + all_threads_killed= 0; + } + } + pthread_mutex_unlock(&THR_LOCK_threads); + pthread_key_delete(THR_KEY_mysys); #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP pthread_mutexattr_destroy(&my_fast_mutexattr); @@ -129,6 +153,11 @@ void my_thread_global_end(void) pthread_mutex_destroy(&THR_LOCK_heap); pthread_mutex_destroy(&THR_LOCK_net); pthread_mutex_destroy(&THR_LOCK_charset); + if (all_threads_killed) + { + pthread_mutex_destroy(&THR_LOCK_threads); + pthread_cond_destroy (&THR_COND_threads); + } #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) pthread_mutex_destroy(&LOCK_localtime_r); #endif @@ -154,9 +183,6 @@ my_bool my_thread_init(void) #ifdef EXTRA_DEBUG_THREADS fprintf(stderr,"my_thread_init(): thread_id=%ld\n",pthread_self()); #endif -#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX) - pthread_mutex_lock(&THR_LOCK_lock); -#endif #if !defined(__WIN__) || defined(USE_TLS) if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys)) @@ -174,7 +200,7 @@ my_bool my_thread_init(void) } pthread_setspecific(THR_KEY_mysys,tmp); -#else +#else /* defined(__WIN__) && !(defined(USE_TLS) */ /* Skip initialization if the thread specific variable is already initialized */ @@ -182,7 +208,6 @@ my_bool my_thread_init(void) goto end; tmp= &THR_KEY_mysys; #endif - tmp->id= ++thread_id; #if defined(__WIN__) && defined(EMBEDDED_LIBRARY) tmp->thread_self= (pthread_t)getpid(); #endif @@ -190,10 +215,11 @@ my_bool my_thread_init(void) pthread_cond_init(&tmp->suspend, NULL); tmp->init= 1; + pthread_mutex_lock(&THR_LOCK_threads); + tmp->id= ++thread_id; + ++THR_thread_count; + pthread_mutex_unlock(&THR_LOCK_threads); end: -#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX) - pthread_mutex_unlock(&THR_LOCK_lock); -#endif return error; } @@ -232,6 +258,10 @@ void my_thread_end(void) #if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS) pthread_setspecific(THR_KEY_mysys,0); #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) -- cgit v1.2.1 From 7191e775394db0392b78b07e2662c766eeace59c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 30 Nov 2006 18:25:05 +0200 Subject: Fixed portability issue in my_thr_init.c (was added in my last push) Fixed compiler warnings (detected by VC++): - Removed not used variables - Added casts - Fixed wrong assignments to bool - Fixed wrong calls with bool arguments - Added missing argument to store(longlong), which caused wrong store method to be called. client/mysqldump.c: Removed compiler warning heap/hp_clear.c: Removed compiler warning include/my_global.h: Removed compiler warning include/my_tree.h: Changed memory limits from int to ulong (Allowed me to get rid of some compiler warnings) myisam/mi_create.c: Removed compiler warning myisam/myisampack.c: Removed compiler warning mysys/base64.c: Removed compiler warning mysys/my_thr_init.c: Fixed portability issue (detected on windows) Added DBUG_ASSERT to detect if we call my_thread_end() too many times Don't wait if THR_thread_count == -1 (error condition) mysys/tree.c: Removed compiler warning sql/field.cc: Removed compiler warning Fixed wrong parameter to check_date() Added missing argument to store(longlong) sql/ha_archive.cc: Removed compiler warning sql/ha_federated.cc: Removed compiler warning sql/ha_innodb.cc: Removed not used variable sql/handler.cc: Removed not used variable Fixed wrong if (we didn't detect if rollback or commit failed). Not critical as value is not yet used sql/item.cc: Removed compiler warning sql/item_func.cc: Removed compiler warning sql/item_strfunc.cc: Removed compiler warning sql/item_timefunc.cc: Removed compiler warning sql/log.cc: Removed compiler warning sql/mysql_priv.h: Removed compiler warning sql/opt_range.cc: Removed compiler warning sql/password.c: Removed compiler warning sql/set_var.cc: Removed compiler warning sql/slave.cc: Removed compiler warning sql/sp.cc: Removed compiler warning sql/sp_cache.cc: Removed compiler warning sql/sp_head.cc: Removed compiler warning Adjusted argument to reserve() to not use up too much memory that we are probably not going to need sql/sql_acl.cc: Added missing argument to store(longlong) sql/sql_base.cc: Removed compiler warning sql/sql_db.cc: Removed compiler warning sql/sql_delete.cc: Removed compiler warning sql/sql_handler.cc: Removed not used variable sql/sql_lex.h: Removed not used variable sql/sql_prepare.cc: Removed not used variable sql/sql_rename.cc: Removed not used variable sql/sql_select.cc: Fixed that select_options are not 'cut' Removed some not used variables Removed compiler warnings by adding cast sql/sql_show.cc: Removed not used variables Added missing argument to store(longlong) Removed compiler warnings sql/sql_trigger.cc: Removed not used variables Added cast to remove compiler warnings sql/sql_update.cc: Fixed wrong set of bool variable sql/sql_view.cc: Removed not used variables Added cast to get rid of compiler warnings sql-common/client.c: Fixed compiler warning sql-common/my_time.c: Fixed wrong argument to check_date() Added casts to get rid of compiler warnings sql/sql_yacc.yy: Removed not used variable sql/uniques.cc: Changes memory size from uint to ulong Added casts to get rid of compiler warnings strings/ctype-simple.c: Fixed cast to get rid of compiler warnings --- mysys/my_thr_init.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'mysys/my_thr_init.c') diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 7800edd700d..0e921bbe8a0 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -120,20 +120,21 @@ my_bool my_thread_global_init(void) void my_thread_global_end(void) { struct timespec abstime; - set_timespec(abstime, my_thread_end_wait_time); my_bool all_threads_killed= 1; + set_timespec(abstime, my_thread_end_wait_time); 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, &abstime); if (error == ETIMEDOUT || error == ETIME) { 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); all_threads_killed= 0; + break; } } pthread_mutex_unlock(&THR_LOCK_threads); @@ -228,10 +229,11 @@ void my_thread_end(void) { struct st_my_thread_var *tmp; tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); + DBUG_ASSERT(tmp); #ifdef EXTRA_DEBUG_THREADS - fprintf(stderr,"my_thread_end(): tmp=%p,thread_id=%ld\n", - tmp,pthread_self()); + fprintf(stderr,"my_thread_end(): tmp: 0x%lx thread_id=%ld\n", + (long) tmp, pthread_self()); #endif if (tmp && tmp->init) { @@ -253,15 +255,24 @@ void my_thread_end(void) #else tmp->init= 0; #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 */ #if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS) pthread_setspecific(THR_KEY_mysys,0); #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) -- cgit v1.2.1 From 25226de9ea52d06667c2c7fbd99f5cd014764241 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 30 Nov 2006 21:56:03 +0200 Subject: Fixed compiler warnings Don't assert if my_thread_end() is called twice (common case) client/mysql.cc: Removed not used variables client/mysqldump.c: Fixed compiler warnings client/mysqltest.c: Fixed compiler warnings cmd-line-utils/readline/bind.c: Fixed compiler warnings cmd-line-utils/readline/histfile.c: Fixed compiler warnings extra/replace.c: Fixed compiler warning on windows extra/yassl/taocrypt/include/algebra.hpp: Fixed compiler warnings heap/hp_write.c: Fixed compiler warnings innobase/os/os0file.c: Fixed compiler warnings libmysql/libmysql.c: Call my_end()/my_thread_end last. my_end() calls free_charsets(), which allowed me to move the call myisam/myisampack.c: Fixed compiler warnings myisammrg/myrg_rkey.c: Fixed compiler warnings mysys/my_thr_init.c: More comments Don't assert if my_thread_end() is called twice (common case) ndb/src/mgmapi/mgmapi.cpp: Fixed compiler warnings ndb/src/ndbapi/Ndb.cpp: Fixed compiler warnings ndb/src/ndbapi/NdbScanOperation.cpp: Fixed compiler warnings ndb/src/ndbapi/NdbTransaction.cpp: Fixed compiler warnings ndb/src/ndbapi/Ndblist.cpp: Fixed compiler warnings server-tools/instance-manager/guardian.cc: Removed not used variable server-tools/instance-manager/portability.h: Removed duplicated symbol sql/gen_lex_hash.cc: Fixed compiler warning sql/ha_archive.cc: Fixed compiler warnings sql/ha_ndbcluster.cc: Fixed compiler warnings sql/mysqld.cc: Fixed compiler warnings sql/sql_cache.cc: Fixed compiler warnings Fixed DBUG_PRINT strings to be consistent with 5.1 sql/tztime.cc: Fixed compiler warnings sql/uniques.cc: Fixed compiler warnings --- mysys/my_thr_init.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'mysys/my_thr_init.c') diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 0e921bbe8a0..fcae18d4686 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -98,7 +98,7 @@ my_bool my_thread_global_init(void) pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST); - pthread_cond_init (&THR_COND_threads, NULL); + pthread_cond_init(&THR_COND_threads, NULL); #if defined( __WIN__) || defined(OS2) win_pthread_init(); #endif @@ -131,7 +131,8 @@ void my_thread_global_end(void) if (error == ETIMEDOUT || error == ETIME) { 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); all_threads_killed= 0; break; @@ -170,10 +171,23 @@ void my_thread_global_end(void) static long thread_id=0; /* - 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. + Allocate thread specific memory for the thread, used by mysys and dbug + + SYNOPSIS + 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) @@ -225,11 +239,22 @@ 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) { struct st_my_thread_var *tmp; tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); - DBUG_ASSERT(tmp); #ifdef EXTRA_DEBUG_THREADS fprintf(stderr,"my_thread_end(): tmp: 0x%lx thread_id=%ld\n", @@ -272,7 +297,6 @@ void my_thread_end(void) #if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS) pthread_setspecific(THR_KEY_mysys,0); #endif - } struct st_my_thread_var *_my_thread_var(void) -- cgit v1.2.1