mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / server-tools / instance-manager / thread_registry.h
blob79076933dc9d9765cb18937cd897ac5ebefe5eb4
1 /* Copyright (c) 2004-2007 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_THREAD_REGISTRY_H
17 #define INCLUDES_MYSQL_INSTANCE_MANAGER_THREAD_REGISTRY_H
20 A multi-threaded application shall nicely work with signals.
22 This means it shall, first of all, shut down nicely on ``quit'' signals:
23 stop all running threads, cleanup and exit.
25 Note, that a thread can't be shut down nicely if it doesn't want to be.
26 That's why to perform clean shutdown, all threads constituting a process
27 must observe certain rules. Here we use the rules, described in Butenhof
28 book 'Programming with POSIX threads', namely:
29 - all user signals are handled in 'signal thread' in synchronous manner
30 (by means of sigwait). To guarantee that the signal thread is the only who
31 can receive user signals, all threads block them, and signal thread is
32 the only who calls sigwait() with an apporpriate sigmask.
33 To propogate a signal to the workers the signal thread sets
34 a variable, corresponding to the signal. Additionally the signal thread
35 sends each worker an internal signal (by means of pthread_kill) to kick it
36 out from possible blocking syscall, and possibly pthread_cond_signal if
37 some thread is blocked in pthread_cond_[timed]wait.
38 - a worker handles only internal 'kick' signal (the handler does nothing).
39 In case when a syscall returns 'EINTR' the worker checks all
40 signal-related variables and behaves accordingly.
41 Also these variables shall be checked from time to time in long
42 CPU-bounded operations, and before/after pthread_cond_wait. (It's supposed
43 that a worker thread either waits in a syscall/conditional variable, or
44 computes something.)
45 - to guarantee signal deliverence, there should be some kind of feedback,
46 e. g. all workers shall account in the signal thread Thread Repository and
47 unregister from it on exit.
49 Configuration reload (on SIGHUP) and thread timeouts/alarms can be handled
50 in manner, similar to ``quit'' signals.
53 #include <my_global.h>
54 #include <my_pthread.h>
56 #if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
57 #pragma interface
58 #endif
60 /**
61 Thread_info - repository entry for each worker thread
62 All entries comprise double-linked list like:
63 0 -- entry -- entry -- entry - 0
64 Double-linked list is used to unregister threads easy.
67 class Thread_info
69 public:
70 Thread_info() {}
71 friend class Thread_registry;
72 private:
73 void init(bool send_signal_on_shutdown);
74 private:
75 pthread_cond_t *current_cond;
76 Thread_info *prev, *next;
77 pthread_t thread_id;
78 bool send_signal_on_shutdown;
82 /**
83 A base class for a detached thread.
86 class Thread
88 public:
89 enum enum_thread_type
91 DETACHED,
92 JOINABLE
94 public:
95 Thread()
96 { }
98 public:
99 inline bool is_detached() const;
101 bool start(enum_thread_type thread_type = JOINABLE);
102 bool join();
104 protected:
105 virtual void run()= 0;
106 virtual ~Thread();
108 private:
109 pthread_t id;
110 bool detached;
112 private:
113 static void *thread_func(void *arg);
115 private:
116 Thread(const Thread & /* rhs */); /* not implemented */
117 Thread &operator=(const Thread & /* rhs */); /* not implemented */
120 inline bool Thread::is_detached() const
122 return detached;
127 Thread_registry - contains handles for each worker thread to deliver
128 signal information to workers.
131 class Thread_registry
133 public:
134 Thread_registry();
135 ~Thread_registry();
137 void register_thread(Thread_info *info, bool send_signal_on_shutdown= TRUE);
138 void unregister_thread(Thread_info *info);
139 void deliver_shutdown();
140 void request_shutdown();
141 inline bool is_shutdown();
142 int cond_wait(Thread_info *info, pthread_cond_t *cond,
143 pthread_mutex_t *mutex);
144 int cond_timedwait(Thread_info *info, pthread_cond_t *cond,
145 pthread_mutex_t *mutex, struct timespec *wait_time);
146 int get_error_status();
147 void set_error_status();
149 private:
150 void interrupt_threads();
151 void wait_for_threads_to_unregister();
153 private:
154 Thread_info head;
155 bool shutdown_in_progress;
156 pthread_mutex_t LOCK_thread_registry;
157 pthread_cond_t COND_thread_registry_is_empty;
158 pthread_t sigwait_thread_pid;
159 bool error_status;
161 private:
162 Thread_registry(const Thread_registry &);
163 Thread_registry &operator =(const Thread_registry &);
167 inline bool Thread_registry::is_shutdown()
169 pthread_mutex_lock(&LOCK_thread_registry);
170 bool res= shutdown_in_progress;
171 pthread_mutex_unlock(&LOCK_thread_registry);
172 return res;
176 #endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_THREAD_REGISTRY_H */