diff options
author | anozdrin/alik@booka. <> | 2006-11-21 17:31:03 +0300 |
---|---|---|
committer | anozdrin/alik@booka. <> | 2006-11-21 17:31:03 +0300 |
commit | ff0325f1625f2802d0080b506f164ca3aa9c1126 (patch) | |
tree | 6c79fe045d0eb04480800567a480ab43b9ad1d4f /server-tools | |
parent | 1efc86208071a7ed110c99276180c53ef2f7e20b (diff) | |
download | mariadb-git-ff0325f1625f2802d0080b506f164ca3aa9c1126.tar.gz |
Polishing:
1) add support for joinable threads to Thread class;
2) move checking of thread model to Manager from mysqlmanager.cc,
because it is needed only for IM-main process.
Diffstat (limited to 'server-tools')
-rw-r--r-- | server-tools/instance-manager/instance.cc | 4 | ||||
-rw-r--r-- | server-tools/instance-manager/listener.cc | 2 | ||||
-rw-r--r-- | server-tools/instance-manager/manager.cc | 80 | ||||
-rw-r--r-- | server-tools/instance-manager/manager.h | 12 | ||||
-rw-r--r-- | server-tools/instance-manager/mysqlmanager.cc | 28 | ||||
-rw-r--r-- | server-tools/instance-manager/priv.cc | 8 | ||||
-rw-r--r-- | server-tools/instance-manager/priv.h | 8 | ||||
-rw-r--r-- | server-tools/instance-manager/thread_registry.cc | 52 | ||||
-rw-r--r-- | server-tools/instance-manager/thread_registry.h | 29 |
9 files changed, 146 insertions, 77 deletions
diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc index 84986c8c5ec..42a7fc94fdb 100644 --- a/server-tools/instance-manager/instance.cc +++ b/server-tools/instance-manager/instance.cc @@ -105,7 +105,7 @@ static int wait_process(My_process_info *pi) couldn't use wait(), because it could return in any wait() in the program. */ - if (linuxthreads) + if (Manager::is_linux_threads()) wait(NULL); /* LinuxThreads were detected */ else waitpid(*pi, NULL, 0); @@ -564,7 +564,7 @@ int Instance::start() instance_monitor= new Instance_monitor(this); - if (instance_monitor == NULL || instance_monitor->start_detached()) + if (instance_monitor == NULL || instance_monitor->start(Thread::DETACHED)) { delete instance_monitor; log_error("Instance::start(): failed to create the monitoring thread" diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc index b66dbab8eae..2b2b37f519f 100644 --- a/server-tools/instance-manager/listener.cc +++ b/server-tools/instance-manager/listener.cc @@ -323,7 +323,7 @@ void Listener::handle_new_mysql_connection(struct st_vio *vio) Mysql_connection *mysql_connection= new Mysql_connection(thread_registry, user_map, vio, ++total_connection_count); - if (mysql_connection == NULL || mysql_connection->start_detached()) + if (mysql_connection == NULL || mysql_connection->start(Thread::DETACHED)) { log_error("handle_one_mysql_connection() failed"); delete mysql_connection; diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc index a55adbed950..faafcbee435 100644 --- a/server-tools/instance-manager/manager.cc +++ b/server-tools/instance-manager/manager.cc @@ -93,6 +93,65 @@ int my_sigwait(const sigset_t *set, int *sig) #endif +/********************************************************************** + Implementation of checking the actual thread model. +***********************************************************************/ + +namespace { /* no-indent */ + +class ThreadModelChecker: public Thread +{ +public: + ThreadModelChecker() + :main_pid(getpid()) + { } + +public: + inline bool is_linux_threads() const + { + return linux_threads; + } + +protected: + virtual void run() + { + linux_threads= main_pid != getpid(); + } + +private: + pid_t main_pid; + bool linux_threads; +}; + +bool check_if_linux_threads(bool *linux_threads) +{ + ThreadModelChecker checker; + + if (checker.start() || checker.join()) + return TRUE; + + *linux_threads= checker.is_linux_threads(); + + return FALSE; +} + +} + + +/********************************************************************** + Manager implementation +***********************************************************************/ + +Guardian *Manager::p_guardian; +Instance_map *Manager::p_instance_map; +Thread_registry *Manager::p_thread_registry; +User_map *Manager::p_user_map; + +#ifndef __WIN__ +bool Manager::linux_threads; +#endif // __WIN__ + + void Manager::stop_all_threads() { /* @@ -106,14 +165,6 @@ void Manager::stop_all_threads() p_thread_registry->deliver_shutdown(); } -/********************************************************************** - Manager implementation -***********************************************************************/ - -Guardian *Manager::p_guardian; -Instance_map *Manager::p_instance_map; -Thread_registry *Manager::p_thread_registry; -User_map *Manager::p_user_map; /* manager - entry point to the main instance manager process: start @@ -132,6 +183,15 @@ int Manager::main() bool shutdown_complete= FALSE; pid_t manager_pid= getpid(); + if (check_if_linux_threads(&linux_threads)) + { + log_error("Error: can not check if Linux Threads are used."); + return 1; + } + + log_info("Detected threads model: %s.", + (const char *) (linux_threads ? "LINUX threads" : "POSIX threads")); + Thread_registry thread_registry; /* All objects created in the manager() function live as long as @@ -228,7 +288,7 @@ int Manager::main() permitted to process instances. And before flush_instances() has completed, there are no instances to guard. */ - if (guardian.start_detached()) + if (guardian.start(Thread::DETACHED)) { log_error("Error: can not start Guardian thread."); goto err; @@ -255,7 +315,7 @@ int Manager::main() /* Initialize the Listener. */ - if (listener.start_detached()) + if (listener.start(Thread::DETACHED)) { log_error("Error: can not start Listener thread."); stop_all_threads(); diff --git a/server-tools/instance-manager/manager.h b/server-tools/instance-manager/manager.h index 8f3dbfefb7b..a77809cca6d 100644 --- a/server-tools/instance-manager/manager.h +++ b/server-tools/instance-manager/manager.h @@ -39,6 +39,10 @@ public: static Thread_registry *get_thread_registry() { return p_thread_registry; } static User_map *get_user_map() { return p_user_map; } +#ifndef __WIN__ + static bool is_linux_threads() { return linux_threads; } +#endif // __WIN__ + private: static void stop_all_threads(); @@ -47,6 +51,14 @@ private: static Instance_map *p_instance_map; static Thread_registry *p_thread_registry; static User_map *p_user_map; + +#ifndef __WIN__ + /* + This flag is set if Instance Manager is running on the system using + LinuxThreads. + */ + static bool linux_threads; +#endif // __WIN__ }; #endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H diff --git a/server-tools/instance-manager/mysqlmanager.cc b/server-tools/instance-manager/mysqlmanager.cc index e4cdedc0e0e..cecbdafb0c4 100644 --- a/server-tools/instance-manager/mysqlmanager.cc +++ b/server-tools/instance-manager/mysqlmanager.cc @@ -71,7 +71,6 @@ static void daemonize(const char *log_file_name); static void angel(); static struct passwd *check_user(const char *user); static int set_user(const char *user, struct passwd *user_info); -static bool check_if_linuxthreads(); #endif @@ -111,9 +110,6 @@ int main(int argc, char *argv[]) } } - if (check_if_linuxthreads()) - goto main_end; /* out of resources */ - if (Options::Daemon::run_as_service) { /* forks, and returns only in child */ @@ -395,28 +391,4 @@ spawn: exit(0); } } - -extern "C" { -static void *check_if_linuxthreads_thread_func(void *arg) -{ - pid_t main_pid= *(pid_t*) arg; - linuxthreads= getpid() != main_pid; - return NULL; -} -} /* extern "C" */ - - -static bool check_if_linuxthreads() -{ - pid_t pid= getpid(); - pthread_t thread_id; - int rc; - - rc= pthread_create(&thread_id, NULL, check_if_linuxthreads_thread_func, - (void*) &pid); - if (rc == 0) - rc= pthread_join(thread_id, NULL); - - return test(rc); -} #endif diff --git a/server-tools/instance-manager/priv.cc b/server-tools/instance-manager/priv.cc index 08af904a311..c3828e9ad24 100644 --- a/server-tools/instance-manager/priv.cc +++ b/server-tools/instance-manager/priv.cc @@ -22,14 +22,6 @@ #include "log.h" -#ifndef __WIN__ -/* - This flag is set if mysqlmanager has detected that it is running on the - system using LinuxThreads -*/ -bool linuxthreads; -#endif - /* The following string must be less then 80 characters, as mysql_connection.cc relies on it diff --git a/server-tools/instance-manager/priv.h b/server-tools/instance-manager/priv.h index 702769e0b07..4d434213781 100644 --- a/server-tools/instance-manager/priv.h +++ b/server-tools/instance-manager/priv.h @@ -50,14 +50,6 @@ const int MAX_VERSION_LENGTH= 160; const int MAX_INSTANCE_NAME_SIZE= FN_REFLEN; -#ifndef __WIN__ -/* - This flag is set if mysqlmanager has detected that it is running on the - system using LinuxThreads -*/ -extern bool linuxthreads; -#endif - extern const LEX_STRING mysqlmanager_version; /* MySQL client-server protocol version: substituted from configure */ diff --git a/server-tools/instance-manager/thread_registry.cc b/server-tools/instance-manager/thread_registry.cc index b913cb718b5..abd1b864fb9 100644 --- a/server-tools/instance-manager/thread_registry.cc +++ b/server-tools/instance-manager/thread_registry.cc @@ -25,8 +25,6 @@ #include <signal.h> -#include "log.h" - #ifndef __WIN__ /* Kick-off signal handler */ @@ -87,8 +85,8 @@ Thread_registry::~Thread_registry() void Thread_registry::register_thread(Thread_info *info, bool send_signal_on_shutdown) { - log_info("Thread_registry: registering thread %d...", - (int) info->thread_id); + DBUG_PRINT("info", ("Thread_registry: registering thread %d...", + (int) info->thread_id)); info->init(send_signal_on_shutdown); @@ -118,8 +116,8 @@ void Thread_registry::register_thread(Thread_info *info, void Thread_registry::unregister_thread(Thread_info *info) { - log_info("Thread_registry: unregistering thread %d...", - (int) info->thread_id); + DBUG_PRINT("info", ("Thread_registry: unregistering thread %d...", + (int) info->thread_id)); pthread_mutex_lock(&LOCK_thread_registry); info->prev->next= info->next; @@ -127,7 +125,7 @@ void Thread_registry::unregister_thread(Thread_info *info) if (head.next == &head) { - log_info("Thread_registry: thread registry is empty!"); + DBUG_PRINT("info", ("Thread_registry: thread registry is empty!")); pthread_cond_signal(&COND_thread_registry_is_empty); } @@ -231,6 +229,7 @@ void Thread_registry::deliver_shutdown() wait_for_threads_to_unregister(); +#ifndef DBUG_OFF /* Print out threads, that didn't stopped. Thread_registry destructor will probably abort the program if there is still any alive thread. @@ -238,15 +237,16 @@ void Thread_registry::deliver_shutdown() if (head.next != &head) { - log_info("Thread_registry: non-stopped threads:"); + DBUG_PRINT("info", ("Thread_registry: non-stopped threads:")); for (Thread_info *info= head.next; info != &head; info= info->next) - log_info(" - %ld", (long int) info->thread_id); + DBUG_PRINT("info", (" - %lu", (unsigned long) info->thread_id)); } else { - log_info("Thread_registry: all threads stopped."); + DBUG_PRINT("info", ("Thread_registry: all threads stopped.")); } +#endif // DBUG_OFF pthread_mutex_unlock(&LOCK_thread_registry); } @@ -278,13 +278,13 @@ void Thread_registry::wait_for_threads_to_unregister() set_timespec(shutdown_time, 1); - log_info("Thread_registry: joining threads..."); + DBUG_PRINT("info", ("Thread_registry: joining threads...")); while (true) { if (head.next == &head) { - log_info("Thread_registry: emptied."); + DBUG_PRINT("info", ("Thread_registry: emptied.")); return; } @@ -294,7 +294,7 @@ void Thread_registry::wait_for_threads_to_unregister() if (error == ETIMEDOUT || error == ETIME) { - log_info("Thread_registry: threads shutdown timed out."); + DBUG_PRINT("info", ("Thread_registry: threads shutdown timed out.")); return; } } @@ -362,17 +362,33 @@ void *Thread::thread_func(void *arg) } -bool Thread::start_detached() +bool Thread::start(enum_thread_type thread_type) { - pthread_t thd_id; pthread_attr_t attr; int rc; pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - rc= set_stacksize_and_create_thread(&thd_id, &attr, - Thread::thread_func, this); + + if (thread_type == DETACHED) + { + detached = TRUE; + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + } + else + { + detached = FALSE; + } + + rc= set_stacksize_and_create_thread(&id, &attr, Thread::thread_func, this); pthread_attr_destroy(&attr); return rc != 0; } + + +bool Thread::join() +{ + DBUG_ASSERT(!detached); + + return pthread_join(id, NULL) != 0; +} diff --git a/server-tools/instance-manager/thread_registry.h b/server-tools/instance-manager/thread_registry.h index 034ac1b0ca8..b9ece271c21 100644 --- a/server-tools/instance-manager/thread_registry.h +++ b/server-tools/instance-manager/thread_registry.h @@ -86,17 +86,42 @@ private: class Thread { public: - Thread() {} - bool start_detached(); + enum enum_thread_type + { + DETACHED, + JOINABLE + }; +public: + Thread() + { } + +public: + inline bool is_detached() const; + + bool start(enum_thread_type thread_type = JOINABLE); + bool join(); + protected: virtual void run()= 0; virtual ~Thread(); + +private: + pthread_t id; + bool detached; + private: static void *thread_func(void *arg); + +private: Thread(const Thread & /* rhs */); /* not implemented */ Thread &operator=(const Thread & /* rhs */); /* not implemented */ }; +inline bool Thread::is_detached() const +{ + return detached; +} + /** Thread_registry - contains handles for each worker thread to deliver |