Merge lp:~jan-kneschke/mysql-proxy/threaded-io into lp:mysql-proxy
- threaded-io
- Merge into trunk
Proposed by
Jan Kneschke
Status: | Merged |
---|---|
Merged at revision: | 662 |
Proposed branch: | lp:~jan-kneschke/mysql-proxy/threaded-io |
Merge into: | lp:mysql-proxy |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~jan-kneschke/mysql-proxy/threaded-io |
Related bugs: | |
Related blueprints: |
Threading the network-io
(Essential)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jan Kneschke (community) | Approve | ||
Review via email: mp+6773@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Jan Kneschke (jan-kneschke) wrote : | # |
Revision history for this message
Jan Kneschke (jan-kneschke) wrote : | # |
* rebased to the 0.7.1 changes
* make check passes
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/Makefile.am' |
2 | --- src/Makefile.am 2009-05-12 19:20:06 +0000 |
3 | +++ src/Makefile.am 2009-05-25 08:57:34 +0000 |
4 | @@ -67,14 +67,15 @@ |
5 | chassis-plugin.c \ |
6 | chassis-log.c \ |
7 | chassis-mainloop.c \ |
8 | + chassis-event-thread.c \ |
9 | chassis-keyfile.c \ |
10 | chassis-path.c \ |
11 | chassis-stats.c |
12 | |
13 | |
14 | libmysql_chassis_la_LDFLAGS = -export-dynamic -no-undefined -dynamic |
15 | -libmysql_chassis_la_CPPFLAGS = $(MYSQL_CFLAGS) $(EVENT_CFLAGS) $(GLIB_CFLAGS) $(LUA_CFLAGS) $(GMODULE_CFLAGS) |
16 | -libmysql_chassis_la_LIBADD = $(EVENT_LIBS) $(GLIB_LIBS) $(LUA_LIBS) $(GMODULE_LIBS) |
17 | +libmysql_chassis_la_CPPFLAGS = $(MYSQL_CFLAGS) $(EVENT_CFLAGS) $(GLIB_CFLAGS) $(LUA_CFLAGS) $(GMODULE_CFLAGS) $(GTHREAD_CFLAGS) |
18 | +libmysql_chassis_la_LIBADD = $(EVENT_LIBS) $(GLIB_LIBS) $(LUA_LIBS) $(GMODULE_LIBS) $(GTHREAD_LIBS) |
19 | |
20 | |
21 | noinst_HEADERS=\ |
22 | @@ -96,6 +97,7 @@ |
23 | chassis-keyfile.h \ |
24 | chassis-mainloop.h \ |
25 | chassis-path.h \ |
26 | + chassis-event-thread.h \ |
27 | glib-ext.h \ |
28 | lua-load-factory.h \ |
29 | lua-scope.h \ |
30 | |
31 | === added file 'src/chassis-event-thread.c' |
32 | --- src/chassis-event-thread.c 1970-01-01 00:00:00 +0000 |
33 | +++ src/chassis-event-thread.c 2009-05-25 08:57:34 +0000 |
34 | @@ -0,0 +1,287 @@ |
35 | +/* $%BEGINLICENSE%$ |
36 | + Copyright (C) 2007-2008 MySQL AB, 2008 Sun Microsystems, Inc |
37 | + |
38 | + This program is free software; you can redistribute it and/or modify |
39 | + it under the terms of the GNU General Public License as published by |
40 | + the Free Software Foundation; version 2 of the License. |
41 | + |
42 | + This program is distributed in the hope that it will be useful, |
43 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
44 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
45 | + GNU General Public License for more details. |
46 | + |
47 | + You should have received a copy of the GNU General Public License |
48 | + along with this program; if not, write to the Free Software |
49 | + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
50 | + |
51 | + $%ENDLICENSE%$ */ |
52 | + |
53 | +#include <glib.h> |
54 | +#include <errno.h> |
55 | + |
56 | +#ifdef HAVE_CONFIG_H |
57 | +#include "config.h" |
58 | +#endif |
59 | + |
60 | +#ifdef HAVE_UNISTD_H |
61 | +#include <unistd.h> /* for write() */ |
62 | +#endif |
63 | + |
64 | +#include "chassis-event-thread.h" |
65 | + |
66 | +#define C(x) x, sizeof(x) - 1 |
67 | + |
68 | +chassis_event_op_t *chassis_event_op_new() { |
69 | + chassis_event_op_t *e; |
70 | + |
71 | + e = g_new0(chassis_event_op_t, 1); |
72 | + |
73 | + return e; |
74 | +} |
75 | + |
76 | +void chassis_event_op_free(chassis_event_op_t *e) { |
77 | + if (!e) return; |
78 | + |
79 | + g_free(e); |
80 | +} |
81 | + |
82 | +/** |
83 | + * execute a event-op on a event-base |
84 | + * |
85 | + * @see: chassis_event_add_local(), chassis_threaded_event_op() |
86 | + */ |
87 | +void chassis_event_op_apply(chassis_event_op_t *op, struct event_base *event_base) { |
88 | + switch (op->type) { |
89 | + case CHASSIS_EVENT_OP_ADD: |
90 | + event_base_set(event_base, op->ev); |
91 | + event_add(op->ev, NULL); |
92 | + break; |
93 | + case CHASSIS_EVENT_OP_UNSET: |
94 | + g_assert_not_reached(); |
95 | + break; |
96 | + } |
97 | +} |
98 | + |
99 | +/** |
100 | + * add a event asynchronously |
101 | + * |
102 | + * the event is added to the global event-queue and a fd-notification is sent allowing any |
103 | + * of the event-threads to handle it |
104 | + * |
105 | + * @see network_mysqld_con_handle() |
106 | + */ |
107 | +void chassis_event_add(chassis *chas, struct event *ev) { |
108 | + chassis_event_op_t *op = chassis_event_op_new(); |
109 | + |
110 | + op->type = CHASSIS_EVENT_OP_ADD; |
111 | + op->ev = ev; |
112 | + g_async_queue_push(chas->threads->event_queue, op); |
113 | + |
114 | + write(chas->threads->event_notify_fds[1], C(".")); /* ping the event handler */ |
115 | +} |
116 | + |
117 | +GPrivate *tls_event_base_key = NULL; |
118 | + |
119 | +/** |
120 | + * add a event to the current thread |
121 | + * |
122 | + * needs event-base stored in the thread local storage |
123 | + * |
124 | + * @see network_connection_pool_lua_add_connection() |
125 | + */ |
126 | +void chassis_event_add_local(chassis G_GNUC_UNUSED *chas, struct event *ev) { |
127 | + struct event_base *event_base = ev->ev_base; |
128 | + chassis_event_op_t *op; |
129 | + |
130 | + if (!event_base) event_base = g_private_get(tls_event_base_key); |
131 | + |
132 | + g_assert(event_base); /* the thread-local event-base has to be initialized */ |
133 | + |
134 | + op = chassis_event_op_new(); |
135 | + |
136 | + op->type = CHASSIS_EVENT_OP_ADD; |
137 | + op->ev = ev; |
138 | + |
139 | + chassis_event_op_apply(op, event_base); |
140 | + |
141 | + chassis_event_op_free(op); |
142 | +} |
143 | + |
144 | +/** |
145 | + * handled events sent through the global event-queue |
146 | + * |
147 | + * each event-thread has its own listener on the event-queue and |
148 | + * calls chassis_event_handle() with its own event-base |
149 | + * |
150 | + * @see chassis_event_add() |
151 | + */ |
152 | +void chassis_event_handle(int G_GNUC_UNUSED event_fd, short G_GNUC_UNUSED events, void *user_data) { |
153 | + chassis_event_thread_t *event_thread = user_data; |
154 | + struct event_base *event_base = event_thread->event_base; |
155 | + chassis *chas = event_thread->chas; |
156 | + chassis_event_op_t *op; |
157 | + char ping[1024]; |
158 | + |
159 | + /* flush the pipe */ |
160 | + while (read(event_thread->notify_fd, ping, sizeof(ping)) > 0); |
161 | + |
162 | + while ((op = g_async_queue_try_pop(chas->threads->event_queue))) { |
163 | + chassis_event_op_apply(op, event_base); |
164 | + |
165 | + chassis_event_op_free(op); |
166 | + } |
167 | +} |
168 | + |
169 | +chassis_event_thread_t *chassis_event_thread_new() { |
170 | + chassis_event_thread_t *event_thread; |
171 | + |
172 | + event_thread = g_new0(chassis_event_thread_t, 1); |
173 | + |
174 | + return event_thread; |
175 | +} |
176 | + |
177 | +void chassis_event_thread_free(chassis_event_thread_t *event_thread) { |
178 | + gboolean is_thread = (event_thread->thr != NULL); |
179 | + |
180 | + if (!event_thread) return; |
181 | + |
182 | + if (event_thread->thr) g_thread_join(event_thread->thr); |
183 | + |
184 | + if (event_thread->notify_fd != -1) { |
185 | + event_del(&(event_thread->notify_fd_event)); |
186 | + close(event_thread->notify_fd); |
187 | + } |
188 | + |
189 | + /* we don't want to free the global event-base */ |
190 | + if (is_thread && event_thread->event_base) event_base_free(event_thread->event_base); |
191 | + |
192 | + g_free(event_thread); |
193 | +} |
194 | + |
195 | +/** |
196 | + * set the event-based for the current event-thread |
197 | + * |
198 | + * @see chassis_event_add_local() |
199 | + */ |
200 | +void chassis_event_thread_set_event_base(chassis_event_thread_t G_GNUC_UNUSED *e, struct event_base *event_base) { |
201 | + tls_event_base_key = g_private_new(NULL); |
202 | + |
203 | + g_private_set(tls_event_base_key, event_base); |
204 | +} |
205 | + |
206 | +chassis_event_threads_t *chassis_event_threads_new() { |
207 | + chassis_event_threads_t *threads; |
208 | + |
209 | + threads = g_new0(chassis_event_threads_t, 1); |
210 | + |
211 | + /* create the ping-fds |
212 | + * |
213 | + * the event-thread write a byte to the ping-pipe to trigger a fd-event when |
214 | + * something is available in the event-async-queues |
215 | + */ |
216 | + if (0 != pipe(threads->event_notify_fds)) { |
217 | + g_error("%s: pipe() failed: %s (%d)", |
218 | + G_STRLOC, |
219 | + g_strerror(errno), |
220 | + errno); |
221 | + } |
222 | + |
223 | + threads->event_threads = g_ptr_array_new(); |
224 | + threads->event_queue = g_async_queue_new(); |
225 | + |
226 | + return threads; |
227 | +} |
228 | + |
229 | +void chassis_event_threads_free(chassis_event_threads_t *threads) { |
230 | + guint i; |
231 | + |
232 | + if (!threads) return; |
233 | + |
234 | + /* all threads are running, now wait until they are down again */ |
235 | + for (i = 0; i < threads->event_threads->len; i++) { |
236 | + chassis_event_thread_t *event_thread = threads->event_threads->pdata[i]; |
237 | + |
238 | + chassis_event_thread_free(event_thread); |
239 | + } |
240 | + |
241 | + g_ptr_array_free(threads->event_threads, TRUE); |
242 | + g_async_queue_unref(threads->event_queue); |
243 | + |
244 | + g_free(threads); |
245 | +} |
246 | + |
247 | +void chassis_event_threads_add(chassis_event_threads_t *threads, chassis_event_thread_t *thread) { |
248 | + g_ptr_array_add(threads->event_threads, thread); |
249 | +} |
250 | + |
251 | + |
252 | +/** |
253 | + * setup the notification-fd of a event-thread |
254 | + * |
255 | + * all event-threads listen on the same notification pipe |
256 | + * |
257 | + * @see chassis_event_handle() |
258 | + */ |
259 | +int chassis_event_threads_init_thread(chassis_event_threads_t *threads, chassis_event_thread_t *event_thread, chassis *chas) { |
260 | + event_thread->event_base = event_base_new(); |
261 | + event_thread->chas = chas; |
262 | + |
263 | + event_thread->notify_fd = dup(threads->event_notify_fds[0]); |
264 | + |
265 | + evutil_make_socket_nonblocking(event_thread->notify_fd); |
266 | + |
267 | + event_set(&(event_thread->notify_fd_event), event_thread->notify_fd, EV_READ | EV_PERSIST, chassis_event_handle, event_thread); |
268 | + event_base_set(event_thread->event_base, &(event_thread->notify_fd_event)); |
269 | + event_add(&(event_thread->notify_fd_event), NULL); |
270 | + |
271 | + return 0; |
272 | +} |
273 | + |
274 | +/** |
275 | + * event-handler thread |
276 | + * |
277 | + */ |
278 | +void *chassis_event_thread_loop(chassis_event_thread_t *event_thread) { |
279 | + chassis_event_thread_set_event_base(event_thread, event_thread->event_base); |
280 | + |
281 | + /** |
282 | + * check once a second if we shall shutdown the proxy |
283 | + */ |
284 | + while (!chassis_is_shutdown()) { |
285 | + struct timeval timeout; |
286 | + int r; |
287 | + |
288 | + timeout.tv_sec = 1; |
289 | + timeout.tv_usec = 0; |
290 | + |
291 | + g_assert(event_base_loopexit(event_thread->event_base, &timeout) == 0); |
292 | + |
293 | + r = event_base_dispatch(event_thread->event_base); |
294 | + |
295 | + if (r == -1) { |
296 | + if (errno == EINTR) continue; |
297 | + |
298 | + break; |
299 | + } |
300 | + } |
301 | + |
302 | + return NULL; |
303 | +} |
304 | + |
305 | +void chassis_event_threads_start(chassis_event_threads_t *threads) { |
306 | + guint i; |
307 | + |
308 | + for (i = 1; i < threads->event_threads->len; i++) { /* the 1st is the main-thread and already set up */ |
309 | + chassis_event_thread_t *event_thread = threads->event_threads->pdata[i]; |
310 | + GError *gerr = NULL; |
311 | + |
312 | + event_thread->thr = g_thread_create((GThreadFunc)chassis_event_thread_loop, event_thread, TRUE, &gerr); |
313 | + |
314 | + if (gerr) { |
315 | + g_error_free(gerr); |
316 | + gerr = NULL; |
317 | + } |
318 | + } |
319 | +} |
320 | + |
321 | + |
322 | |
323 | === added file 'src/chassis-event-thread.h' |
324 | --- src/chassis-event-thread.h 1970-01-01 00:00:00 +0000 |
325 | +++ src/chassis-event-thread.h 2009-05-25 08:57:34 +0000 |
326 | @@ -0,0 +1,81 @@ |
327 | +/* $%BEGINLICENSE%$ |
328 | + Copyright (C) 2007-2008 MySQL AB, 2008 Sun Microsystems, Inc |
329 | + |
330 | + This program is free software; you can redistribute it and/or modify |
331 | + it under the terms of the GNU General Public License as published by |
332 | + the Free Software Foundation; version 2 of the License. |
333 | + |
334 | + This program is distributed in the hope that it will be useful, |
335 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
336 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
337 | + GNU General Public License for more details. |
338 | + |
339 | + You should have received a copy of the GNU General Public License |
340 | + along with this program; if not, write to the Free Software |
341 | + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
342 | + |
343 | + $%ENDLICENSE%$ */ |
344 | + |
345 | + |
346 | +#ifndef _CHASSIS_EVENT_THREAD_H_ |
347 | +#define _CHASSIS_EVENT_THREAD_H_ |
348 | + |
349 | +#include <glib.h> /* GPtrArray */ |
350 | + |
351 | +#include "chassis-exports.h" |
352 | +#include "chassis-mainloop.h" |
353 | + |
354 | +/** |
355 | + * event operations |
356 | + * |
357 | + * event-ops are sent through the async-queues |
358 | + */ |
359 | + |
360 | +typedef struct { |
361 | + enum { |
362 | + CHASSIS_EVENT_OP_UNSET, |
363 | + CHASSIS_EVENT_OP_ADD |
364 | + } type; |
365 | + |
366 | + struct event *ev; |
367 | +} chassis_event_op_t; |
368 | + |
369 | +CHASSIS_API chassis_event_op_t *chassis_event_op_new(); |
370 | +CHASSIS_API void chassis_event_op_free(chassis_event_op_t *e); |
371 | +CHASSIS_API void chassis_event_add(chassis *chas, struct event *ev); |
372 | +CHASSIS_API void chassis_event_add_local(chassis *chas, struct event *ev); |
373 | + |
374 | +/** |
375 | + * a event-thread |
376 | + */ |
377 | +typedef struct { |
378 | + chassis *chas; |
379 | + |
380 | + int notify_fd; |
381 | + struct event notify_fd_event; |
382 | + |
383 | + GThread *thr; |
384 | + |
385 | + struct event_base *event_base; |
386 | +} chassis_event_thread_t; |
387 | + |
388 | +CHASSIS_API chassis_event_thread_t *chassis_event_thread_new(); |
389 | +CHASSIS_API void chassis_event_thread_free(chassis_event_thread_t *e); |
390 | +CHASSIS_API void chassis_event_handle(int event_fd, short events, void *user_data); |
391 | +CHASSIS_API void chassis_event_thread_set_event_base(chassis_event_thread_t *e, struct event_base *event_base); |
392 | +CHASSIS_API void *chassis_event_thread_loop(chassis_event_thread_t *); |
393 | + |
394 | +struct chassis_event_threads_t { |
395 | + GPtrArray *event_threads; |
396 | + |
397 | + GAsyncQueue *event_queue; |
398 | + int event_notify_fds[2]; |
399 | +}; |
400 | + |
401 | +CHASSIS_API chassis_event_threads_t *chassis_event_threads_new(); |
402 | +CHASSIS_API void chassis_event_threads_free(chassis_event_threads_t *threads); |
403 | +CHASSIS_API int chassis_event_threads_init_thread(chassis_event_threads_t *threads, chassis_event_thread_t *event_thread, chassis *chas); |
404 | +CHASSIS_API void chassis_event_threads_add(chassis_event_threads_t *threads, chassis_event_thread_t *thread); |
405 | +CHASSIS_API void chassis_event_threads_start(chassis_event_threads_t *threads); |
406 | + |
407 | +#endif |
408 | |
409 | === modified file 'src/chassis-mainloop.c' |
410 | --- src/chassis-mainloop.c 2009-02-23 23:13:09 +0000 |
411 | +++ src/chassis-mainloop.c 2009-05-25 08:57:34 +0000 |
412 | @@ -42,6 +42,7 @@ |
413 | #include <glib.h> |
414 | #include "chassis-plugin.h" |
415 | #include "chassis-mainloop.h" |
416 | +#include "chassis-event-thread.h" |
417 | #include "chassis-log.h" |
418 | #include "chassis-stats.h" |
419 | |
420 | @@ -68,6 +69,8 @@ |
421 | |
422 | chas->stats = chassis_stats_new(); |
423 | |
424 | + chas->threads = chassis_event_threads_new(); |
425 | + |
426 | return chas; |
427 | } |
428 | |
429 | @@ -120,6 +123,8 @@ |
430 | |
431 | if (chas->stats) chassis_stats_free(chas->stats); |
432 | |
433 | + if (chas->threads) chassis_event_threads_free(chas->threads); |
434 | + |
435 | g_free(chas); |
436 | } |
437 | |
438 | @@ -192,23 +197,12 @@ |
439 | g_log(G_LOG_DOMAIN, glib_log_level, "(libevent) %s", msg); |
440 | } |
441 | |
442 | -/** |
443 | - * init libevent |
444 | - * |
445 | - * kqueue has to be called after the fork() of daemonize |
446 | - * |
447 | - * @param m global context |
448 | - */ |
449 | -static void chassis_init_libevent(chassis *chas) { |
450 | - chas->event_base = event_init(); |
451 | - |
452 | - event_set_log_callback(event_log_use_glib); |
453 | -} |
454 | |
455 | int chassis_mainloop(void *_chas) { |
456 | chassis *chas = _chas; |
457 | guint i; |
458 | struct event ev_sigterm, ev_sigint, ev_sighup; |
459 | + chassis_event_thread_t *mainloop_thread; |
460 | |
461 | #ifdef _WIN32 |
462 | WORD wVersionRequested; |
463 | @@ -224,8 +218,19 @@ |
464 | return err; /* err is positive */ |
465 | } |
466 | #endif |
467 | - /* init the event-handlers */ |
468 | - chassis_init_libevent(chas); |
469 | + /* redirect logging from libevent to glib */ |
470 | + event_set_log_callback(event_log_use_glib); |
471 | + |
472 | + |
473 | + /* add a event-handler for the "main" events */ |
474 | + mainloop_thread = chassis_event_thread_new(); |
475 | + chassis_event_threads_init_thread(chas->threads, mainloop_thread, chas); |
476 | + chassis_event_threads_add(chas->threads, mainloop_thread); |
477 | + |
478 | + chas->event_base = mainloop_thread->event_base; /* all global events go to the 1st thread */ |
479 | + |
480 | + g_assert(chas->event_base); |
481 | + |
482 | |
483 | /* setup all plugins all plugins */ |
484 | for (i = 0; i < chas->modules->len; i++) { |
485 | @@ -293,28 +298,32 @@ |
486 | } |
487 | #endif |
488 | |
489 | + if (chas->event_thread_count < 1) chas->event_thread_count = 0; |
490 | + |
491 | + /* create the event-threads |
492 | + * |
493 | + * - dup the async-queue-ping-fds |
494 | + * - setup the events notification |
495 | + * */ |
496 | + for (i = 0; i < chas->event_thread_count; i++) { |
497 | + chassis_event_thread_t *event_thread; |
498 | + |
499 | + event_thread = chassis_event_thread_new(); |
500 | + chassis_event_threads_init_thread(chas->threads, event_thread, chas); |
501 | + chassis_event_threads_add(chas->threads, event_thread); |
502 | + } |
503 | + |
504 | + /* start the event threads */ |
505 | + if (chas->event_thread_count > 0) { |
506 | + chassis_event_threads_start(chas->threads); |
507 | + } |
508 | + |
509 | /** |
510 | - * check once a second if we shall shutdown the proxy |
511 | + * handle signals and all basic events into the main-thread |
512 | + * |
513 | + * block until we are asked to shutdown |
514 | */ |
515 | - while (!chassis_is_shutdown()) { |
516 | - struct timeval timeout; |
517 | - int r; |
518 | - |
519 | - timeout.tv_sec = 1; |
520 | - timeout.tv_usec = 0; |
521 | - |
522 | - g_assert(event_base_loopexit(chas->event_base, &timeout) == 0); |
523 | - |
524 | - r = event_base_dispatch(chas->event_base); |
525 | - |
526 | - if (r == -1) { |
527 | - if (errno == EINTR) continue; |
528 | - |
529 | - g_critical("%s: event_base_dispatch() failed: %s (%d)", |
530 | - G_STRLOC, g_strerror(errno), errno); |
531 | - break; |
532 | - } |
533 | - } |
534 | + chassis_event_thread_loop(mainloop_thread); |
535 | |
536 | signal_del(&ev_sigterm); |
537 | signal_del(&ev_sigint); |
538 | |
539 | === modified file 'src/chassis-mainloop.h' |
540 | --- src/chassis-mainloop.h 2009-02-23 23:13:09 +0000 |
541 | +++ src/chassis-mainloop.h 2009-05-25 08:57:34 +0000 |
542 | @@ -43,6 +43,7 @@ |
543 | |
544 | typedef struct chassis_private chassis_private; |
545 | typedef struct chassis chassis; |
546 | +typedef struct chassis_event_threads_t chassis_event_threads_t; |
547 | |
548 | struct chassis { |
549 | struct event_base *event_base; |
550 | @@ -59,6 +60,11 @@ |
551 | chassis_log *log; |
552 | |
553 | chassis_stats_t *stats; /**< the overall chassis stats, includes lua and glib allocation stats */ |
554 | + |
555 | + /* network-io threads */ |
556 | + gint event_thread_count; |
557 | + |
558 | + chassis_event_threads_t *threads; |
559 | }; |
560 | |
561 | CHASSIS_API chassis *chassis_init(void) G_GNUC_DEPRECATED; |
562 | |
563 | === modified file 'src/chassis.c' |
564 | --- src/chassis.c 2009-05-15 14:23:58 +0000 |
565 | +++ src/chassis.c 2009-05-25 08:57:34 +0000 |
566 | @@ -395,6 +395,7 @@ |
567 | guint invoke_dbg_on_crash = 0; |
568 | guint auto_restart = 0; |
569 | guint max_files_number = 8192; |
570 | + gint event_thread_count = 0; |
571 | #ifndef _WIN32 |
572 | struct rlimit max_files_rlimit; |
573 | #endif |
574 | @@ -431,6 +432,7 @@ |
575 | { "log-backtrace-on-crash", 0, 0, G_OPTION_ARG_NONE, NULL, "try to invoke debugger on crash", NULL }, |
576 | { "keepalive", 0, 0, G_OPTION_ARG_NONE, NULL, "try to restart the proxy if it crashed", NULL }, |
577 | { "max-open-files", 0, 0, G_OPTION_ARG_INT, NULL, "maximum number of open files (ulimit -n)", NULL}, |
578 | + { "event-threads", 0, 0, G_OPTION_ARG_INT, NULL, "number of event-handling threads", NULL}, |
579 | |
580 | { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } |
581 | }; |
582 | @@ -501,6 +503,7 @@ |
583 | main_entries[i++].arg_data = &(invoke_dbg_on_crash); |
584 | main_entries[i++].arg_data = &(auto_restart); |
585 | main_entries[i++].arg_data = &(max_files_number); |
586 | + main_entries[i++].arg_data = &(srv->event_thread_count); |
587 | |
588 | option_ctx = g_option_context_new("- MySQL App Shell"); |
589 | g_option_context_add_main_entries(option_ctx, base_main_entries, GETTEXT_PACKAGE); |
590 | @@ -888,6 +891,16 @@ |
591 | exit_code = EXIT_FAILURE; |
592 | goto exit_nicely; |
593 | } |
594 | + |
595 | + /* make sure that he max-thread-count isn't negative */ |
596 | + if (event_thread_count < 0) { |
597 | + g_critical("unknown option: %s", argv[1]); |
598 | + |
599 | + exit_code = EXIT_FAILURE; |
600 | + goto exit_nicely; |
601 | + } |
602 | + |
603 | + srv->event_thread_count = event_thread_count; |
604 | |
605 | #ifndef _WIN32 |
606 | signal(SIGPIPE, SIG_IGN); |
607 | @@ -988,7 +1001,6 @@ |
608 | } |
609 | } |
610 | #endif |
611 | - |
612 | if (chassis_mainloop(srv)) { |
613 | /* looks like we failed */ |
614 | |
615 | |
616 | === modified file 'src/network-conn-pool-lua.c' |
617 | --- src/network-conn-pool-lua.c 2009-02-24 00:20:29 +0000 |
618 | +++ src/network-conn-pool-lua.c 2009-05-25 08:57:34 +0000 |
619 | @@ -43,6 +43,7 @@ |
620 | |
621 | #include "network-mysqld.h" |
622 | #include "network-mysqld-packet.h" |
623 | +#include "chassis-event-thread.h" |
624 | #include "network-mysqld-lua.h" |
625 | |
626 | #include "network-conn-pool.h" |
627 | @@ -201,7 +202,6 @@ |
628 | * proxy from its backend |
629 | */ |
630 | int network_connection_pool_lua_add_connection(network_mysqld_con *con) { |
631 | - chassis *srv = con->srv; |
632 | network_connection_pool_entry *pool_entry = NULL; |
633 | network_mysqld_con_lua_t *st = con->plugin_con_state; |
634 | |
635 | @@ -215,8 +215,7 @@ |
636 | pool_entry = network_connection_pool_add(st->backend->pool, con->server); |
637 | |
638 | event_set(&(con->server->event), con->server->fd, EV_READ, network_mysqld_con_idle_handle, pool_entry); |
639 | - event_base_set(srv->event_base, &(con->server->event)); |
640 | - event_add(&(con->server->event), NULL); |
641 | + chassis_event_add_local(con->srv, &(con->server->event)); /* add a event, but stay in the same thread */ |
642 | |
643 | st->backend->connected_clients--; |
644 | st->backend = NULL; |
645 | |
646 | === modified file 'src/network-mysqld.c' |
647 | --- src/network-mysqld.c 2009-02-21 14:09:48 +0000 |
648 | +++ src/network-mysqld.c 2009-05-25 08:57:34 +0000 |
649 | @@ -179,6 +179,7 @@ |
650 | #include "network-mysqld-packet.h" |
651 | #include "network-conn-pool.h" |
652 | #include "chassis-mainloop.h" |
653 | +#include "chassis-event-thread.h" |
654 | #include "lua-scope.h" |
655 | #include "glib-ext.h" |
656 | |
657 | @@ -761,8 +762,7 @@ |
658 | |
659 | #define WAIT_FOR_EVENT(ev_struct, ev_type, timeout) \ |
660 | event_set(&(ev_struct->event), ev_struct->fd, ev_type, network_mysqld_con_handle, user_data); \ |
661 | - event_base_set(srv->event_base, &(ev_struct->event));\ |
662 | - event_add(&(ev_struct->event), timeout); |
663 | + chassis_event_add(srv, &(ev_struct->event)); |
664 | |
665 | /** |
666 | * loop on the same connection as long as we don't end up in a stable state |
667 | |
668 | === modified file 'tests/unit/Makefile.am' |
669 | --- tests/unit/Makefile.am 2009-04-02 22:10:21 +0000 |
670 | +++ tests/unit/Makefile.am 2009-05-25 08:57:34 +0000 |
671 | @@ -74,10 +74,11 @@ |
672 | check_chassis_path.c \ |
673 | $(top_srcdir)/src/chassis-log.c \ |
674 | $(top_srcdir)/src/chassis-mainloop.c \ |
675 | + $(top_srcdir)/src/chassis-event-thread.c \ |
676 | $(top_srcdir)/src/chassis-plugin.c \ |
677 | $(top_srcdir)/src/chassis-stats.c |
678 | check_chassis_path_CPPFLAGS = -I$(top_srcdir)/src $(GLIB_CFLAGS) $(MYSQL_CFLAGS) $(GMODULE_CFLAGS) |
679 | -check_chassis_path_LDADD = $(GLIB_LIBS) $(GMODULE_LIBS) $(EVENT_LIBS) |
680 | +check_chassis_path_LDADD = $(GLIB_LIBS) $(GMODULE_LIBS) $(EVENT_LIBS) $(GTHREAD_LIBS) |
681 | |
682 | t_network_backend_SOURCES = \ |
683 | t_network_backend.c \ |
684 | |
685 | === modified file 'tests/unit/check_chassis_path.c' |
686 | --- tests/unit/check_chassis_path.c 2009-02-23 23:13:09 +0000 |
687 | +++ tests/unit/check_chassis_path.c 2009-05-25 08:57:34 +0000 |
688 | @@ -95,6 +95,8 @@ |
689 | /*@}*/ |
690 | |
691 | int main(int argc, char **argv) { |
692 | + g_thread_init(NULL); |
693 | + |
694 | g_test_init(&argc, &argv, NULL); |
695 | g_test_bug_base("http://bugs.mysql.com/"); |
696 |
merge the initial threaded-io code into trunk for the 0.8 work