mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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. server-tools/instance-manager/instance.cc: Use Manager::is_linux_threads() instead of global variable. server-tools/instance-manager/listener.cc: Use Thread::start(DETACHED) instead of Thread::start_detached(). server-tools/instance-manager/manager.cc: 1. Use Thread::start(DETACHED) instead of Thread::start_detached(); 2. Move checking of thread model to Manager from mysqlmanager.cc, because it is needed only for IM-main process. server-tools/instance-manager/manager.h: Move checking of thread model to Manager from mysqlmanager.cc, because it is needed only for IM-main process. server-tools/instance-manager/mysqlmanager.cc: Move checking of thread model to Manager from mysqlmanager.cc, because it is needed only for IM-main process. server-tools/instance-manager/priv.cc: Move checking of thread model to Manager from mysqlmanager.cc, because it is needed only for IM-main process. server-tools/instance-manager/priv.h: Move checking of thread model to Manager from mysqlmanager.cc, because it is needed only for IM-main process. server-tools/instance-manager/thread_registry.cc: Add support of joinable threads to Thread class. server-tools/instance-manager/thread_registry.h: Add support of joinable threads to Thread class.
This commit is contained in:
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user