diff --git a/core/Makefile b/core/Makefile index b559c86de..c6d7684eb 100644 --- a/core/Makefile +++ b/core/Makefile @@ -28,14 +28,15 @@ CFLAGS=-c -I/usr/include -I../include -I../inih -I/usr/include/mysql -Wall -g LDFLAGS=-rdynamic SRCS= atomic.c buffer.c spinlock.c gateway.c gateway_mysql_protocol.c gw_utils.c \ utils.c dcb.c load_utils.c session.c service.c server.c poll.c config.c \ - users.c hashtable.c dbusers.c + users.c hashtable.c dbusers.c thread.c HDRS= ../include/atomic.h ../include/buffer.h ../include/dcb.h \ ../include/gateway_mysql.h ../include/gw.h ../include/mysql_protocol.h \ ../include/session.h ../include/spinlock.h ../include/thread.h \ ../include/modules.h ../include/poll.h ../include/config.h ../include/users.h \ ../include/hashtable.h OBJ=$(SRCS:.c=.o) -LIBS=-L../inih/extra -linih -lssl -lstdc++ -L/packages/mariadb-5.5.25/libmysql -lmysqlclient -lz -lm -lcrypto +LIBS=-L../inih/extra -linih -lssl -lstdc++ -L/packages/mariadb-5.5.25/libmysql -lmysqlclient \ + -lz -lm -lcrypto gateway: $(OBJ) $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@ diff --git a/core/config.c b/core/config.c index 9450ed5b7..b3a65c014 100644 --- a/core/config.c +++ b/core/config.c @@ -36,11 +36,13 @@ #include #include - static int process_config_context(CONFIG_CONTEXT *); static void free_config_context(CONFIG_CONTEXT *); -static char *config_get_value(CONFIG_PARAMETER *, const char *); +static char *config_get_value(CONFIG_PARAMETER *, const char *); +static int handle_global_item(const char *, const char *); +static void global_defaults(); +static GATEWAY_CONF gateway; /** * Config item handler for the ini file reader @@ -58,6 +60,10 @@ CONFIG_CONTEXT *cntxt = (CONFIG_CONTEXT *)userdata; CONFIG_CONTEXT *ptr = cntxt; CONFIG_PARAMETER *param; + if (strcmp(section, "gateway") == 0) + { + return handle_global_item(name, value); + } /* * If we already have some parameters for the object * add the parameters to that object. If not create @@ -89,11 +95,13 @@ CONFIG_PARAMETER *param; * @param file The filename of the configuration file */ int -load_config(char *file) +config_load(char *file) { CONFIG_CONTEXT config; int rval; + global_defaults(); + config.object = ""; config.next = NULL; @@ -251,3 +259,40 @@ CONFIG_PARAMETER *p1, *p2; context = obj; } } + +/** + * Return the number of configured threads + * + * @return The number of threads configured in the config file + */ +int +config_threadcount() +{ + return gateway.n_threads; +} + +/** + * Configuration handler for items in the global [gateway] section + * + * @param name The item name + * @param value The item value + * @return 0 on error + */ +static int +handle_global_item(const char *name, const char *value) +{ + if (!strcmp(name, "threads") == 0) + gateway.n_threads = atoi(value); + else + return 0; + return 1; +} + +/** + * Set the defaults for the global configuration options + */ +static void +global_defaults() +{ + gateway.n_threads = 1; +} diff --git a/core/dcb.c b/core/dcb.c index 6bdbb2f4d..41ac8898a 100644 --- a/core/dcb.c +++ b/core/dcb.c @@ -111,9 +111,20 @@ dcb_free(DCB *dcb) /* First remove this DCB from the chain */ spinlock_acquire(dcbspin); if (allDCBs == dcb) + { + /* + * Deal with the special case of removign the DCB at the head of + * the chain. + */ allDCBs = dcb->next; + } else { + /* + * We find the DCB that pont to the one we are removing and then + * set the next pointer of that DCB to the next pointer of the + * DCB we are removing. + */ DCB *ptr = allDCBs; while (ptr && ptr->next != dcb) ptr = ptr->next; diff --git a/core/depend.mk b/core/depend.mk index 453d087d2..dfdd042e1 100644 --- a/core/depend.mk +++ b/core/depend.mk @@ -213,7 +213,7 @@ utils.o: utils.c ../include/gw.h /usr/include/stdio.h \ ../include/mysql_protocol.h ../include/dcb.h ../include/session.h \ ../include/mysql_protocol.h /usr/include/openssl/sha.h \ /usr/include/openssl/e_os2.h /usr/include/openssl/opensslconf.h \ - /usr/include/openssl/opensslconf-x86_64.h + /usr/include/openssl/opensslconf-x86_64.h ../include/poll.h dcb.o: dcb.c /usr/include/stdio.h /usr/include/features.h \ /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \ @@ -315,6 +315,28 @@ session.o: session.c /usr/include/stdio.h /usr/include/features.h \ /usr/include/bits/sched.h /usr/include/bits/setjmp.h ../include/dcb.h \ ../include/buffer.h ../include/server.h ../include/router.h \ ../include/atomic.h +service.o: service.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \ + /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/typesizes.h \ + /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ + /usr/include/stdlib.h /usr/include/bits/waitflags.h \ + /usr/include/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/bits/endian.h /usr/include/bits/byteswap.h \ + /usr/include/sys/types.h /usr/include/time.h /usr/include/sys/select.h \ + /usr/include/bits/select.h /usr/include/bits/sigset.h \ + /usr/include/bits/time.h /usr/include/sys/sysmacros.h \ + /usr/include/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/string.h /usr/include/xlocale.h ../include/session.h \ + ../include/service.h ../include/spinlock.h ../include/thread.h \ + /usr/include/pthread.h /usr/include/sched.h /usr/include/bits/sched.h \ + /usr/include/bits/setjmp.h ../include/dcb.h ../include/buffer.h \ + ../include/server.h ../include/router.h ../include/modules.h \ + ../include/users.h ../include/hashtable.h ../include/atomic.h \ + ../include/dbusers.h server.o: server.c /usr/include/stdio.h /usr/include/features.h \ /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \ @@ -429,3 +451,14 @@ dbusers.o: dbusers.c /usr/include/stdio.h /usr/include/features.h \ /usr/include/bits/setjmp.h ../include/buffer.h ../include/service.h \ ../include/server.h ../include/users.h ../include/hashtable.h \ ../include/atomic.h +thread.o: thread.c ../include/thread.h /usr/include/pthread.h \ + /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ + /usr/include/gnu/stubs-64.h /usr/include/endian.h \ + /usr/include/bits/endian.h /usr/include/bits/byteswap.h \ + /usr/include/sched.h /usr/include/bits/types.h \ + /usr/include/bits/typesizes.h \ + /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include/stddef.h \ + /usr/include/time.h /usr/include/bits/sched.h /usr/include/bits/time.h \ + /usr/include/xlocale.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/setjmp.h diff --git a/core/gateway.c b/core/gateway.c index 2bb97feff..bce09e4c9 100644 --- a/core/gateway.c +++ b/core/gateway.c @@ -204,7 +204,7 @@ char buf[1024], *home, *cnf_file = NULL; exit(1); } - if (!load_config(cnf_file)) + if (!config_load(cnf_file)) { fprintf(stderr, "Failed to load gateway configuration file %s\n", cnf_file); exit(1); @@ -246,8 +246,12 @@ char buf[1024], *home, *cnf_file = NULL; */ printf("Started %d services\n", serviceStartAll()); - while (1) - { - poll_waitevents(); - } + /* + * Start the polling threads, note this is one less than is configured as the + * main thread will also poll. + */ + for (n = 0; n < config_threadcount() - 1; n++) + thread_start(poll_waitevents); + poll_waitevents(); + } // End of main diff --git a/core/thread.c b/core/thread.c new file mode 100644 index 000000000..715d4792e --- /dev/null +++ b/core/thread.c @@ -0,0 +1,61 @@ +/* + * This file is distributed as part of the SkySQL Gateway. It is free + * software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, + * version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright SkySQL Ab 2013 + */ +#include +#include +/** + * @file thread.c - Implementation of thread related operations + * + * @verbatim + * Revision History + * + * Date Who Description + * 25/06/13 Mark Riddoch Initial implementation + * + * @endverbatim + */ + + +/** + * Start a polling thread + * + * @param entry The entry point to call + * @return The thread handle + */ +void * +thread_start(void (*entry)()) +{ +pthread_t thd; + + if (pthread_create(&thd, NULL, (void *(*)(void *))entry, NULL) != 0) + { + return NULL; + } + return (void *)thd; +} + +/** + * Wait for all running threads to complete. + * + */ +void +thread_wait(void *thd) +{ +void *rval; + + pthread_join((pthread_t)thd, &rval); +} diff --git a/core/utils.c b/core/utils.c index 4299f1921..8866ab04d 100644 --- a/core/utils.c +++ b/core/utils.c @@ -39,6 +39,7 @@ #include #include #include +#include // used in the hex2bin function #define char_val(X) (X >= '0' && X <= '9' ? X-'0' :\ diff --git a/gateway.cnf b/gateway.cnf index 7060cc73c..82c720257 100644 --- a/gateway.cnf +++ b/gateway.cnf @@ -1,6 +1,10 @@ # # Example gateway.cnf configuration file # +# +[gateway] +threads=1 + [Test Service] type=service router=readconnroute @@ -40,4 +44,4 @@ port=4442 type=listener service=Test Service protocol=MySQLClient -port=4407 +port=4006 diff --git a/include/config.h b/include/config.h index 1a6276dd6..3ef4bf785 100644 --- a/include/config.h +++ b/include/config.h @@ -38,6 +38,7 @@ typedef struct config_parameter { char *value; /**< The value of the parameter */ struct config_parameter *next; /**< Next pointer in the linked list */ } CONFIG_PARAMETER; + /** * The config context structure, used to build the configuration * data during the parse process @@ -49,5 +50,13 @@ typedef struct config_context { struct config_context *next; /**< Next pointer in the linked list */ } CONFIG_CONTEXT; -extern int load_config(char *); +/** + * The gateway global configuration data + */ +typedef struct { + int n_threads; /**< Number of polling threads */ +} GATEWAY_CONF; + +extern int config_load(char *); +extern int config_threadcount(); #endif diff --git a/include/thread.h b/include/thread.h index 0ba83ce9b..a9c28b518 100644 --- a/include/thread.h +++ b/include/thread.h @@ -22,4 +22,7 @@ #define THREAD pthread_t #define THREAD_SHELF pthread_self +extern void *thread_start(void (*entry)()); +extern void thread_wait(void *thd); + #endif