You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
5.5 KiB

Added "pool-of-threads" handling (with libevent) This is a backport of code from MySQL 6.0 with cleanups and extensions The following new options are supported configure options: --with-libevent ; Enable use of libevent, which is needed for pool of threads mysqld options: --thread-handling=pool-of-threads ; Use a pool of threads to handle queries --thread-pool-size=# ; Define how many threads should be created to handle all queries --extra-port=# ; Extra tcp port that uses the old one-thread-per-connection method --extra-max-connections=# ; Number of connections to accept to 'extra-port' --test-ignore-wrong-options ; Ignore setting an enum value to a wrong option (for mysql-test-run) BUILD/SETUP.sh: Added libevents (and thus pool-of-threads) to max builds CMakeLists.txt: Added libevent Makefile.am: Added libevents config/ac-macros/libevent.m4: Libevent code for configure config/ac-macros/libevent_configure.m4: Libevent code for configure configure.in: Added libevents dbug/dbug.c: Added _db_is_pushed(); Needed for pool-of-threads code extra/Makefile.am: Added libevents extra/libevent: Libevent initial code extra/libevent/CMakeLists.txt: Libevent initial code extra/libevent/Makefile.am: Libevent initial code extra/libevent/README: Libevent initial code extra/libevent/WIN32-Code: Libevent initial code extra/libevent/WIN32-Code/config.h: Libevent initial code extra/libevent/WIN32-Code/misc.c: Libevent initial code extra/libevent/WIN32-Code/misc.h: Libevent initial code extra/libevent/WIN32-Code/tree.h: Libevent initial code extra/libevent/WIN32-Code/win32.c: Libevent initial code extra/libevent/buffer.c: Libevent initial code extra/libevent/compat: Libevent initial code extra/libevent/compat/sys: Libevent initial code extra/libevent/compat/sys/_time.h: Libevent initial code extra/libevent/compat/sys/queue.h: Libevent initial code extra/libevent/compat/sys/tree.h: Libevent initial code extra/libevent/devpoll.c: Libevent initial code extra/libevent/epoll.c: Libevent initial code extra/libevent/epoll_sub.c: Libevent initial code extra/libevent/evbuffer.c: Libevent initial code extra/libevent/evdns.c: Libevent initial code extra/libevent/evdns.h: Libevent initial code extra/libevent/event-config.h: Libevent initial code extra/libevent/event-internal.h: Libevent initial code extra/libevent/event.c: Libevent initial code extra/libevent/event.h: Libevent initial code extra/libevent/event_tagging.c: Libevent initial code extra/libevent/evhttp.h: Libevent initial code extra/libevent/evport.c: Libevent initial code extra/libevent/evrpc-internal.h: Libevent initial code extra/libevent/evrpc.c: Libevent initial code extra/libevent/evrpc.h: Libevent initial code extra/libevent/evsignal.h: Libevent initial code extra/libevent/evutil.c: Libevent initial code extra/libevent/evutil.h: Libevent initial code extra/libevent/http-internal.h: Libevent initial code extra/libevent/http.c: Libevent initial code extra/libevent/kqueue.c: Libevent initial code extra/libevent/log.c: Libevent initial code extra/libevent/log.h: Libevent initial code extra/libevent/min_heap.h: Libevent initial code extra/libevent/poll.c: Libevent initial code extra/libevent/select.c: Libevent initial code extra/libevent/signal.c: Libevent initial code extra/libevent/strlcpy-internal.h: Libevent initial code extra/libevent/strlcpy.c: Libevent initial code include/config-win.h: Libevent support include/my_dbug.h: ADded _db_is_pushed include/mysql.h.pp: Update to handle new prototypes include/typelib.h: Split find_type_or_exit() into two functions include/violite.h: Added vio_is_pending() libmysqld/Makefile.am: Added libevent mysql-test/include/have_pool_of_threads.inc: Added test for pool-of-threads mysql-test/mysql-test-run.pl: Don't abort based on time and don't retry test cases when run under --gdb or --debug mysql-test/r/crash_commit_before.result: USE GLOBAL for debug variable mysql-test/r/have_pool_of_threads.require: Added test for pool-of-threads mysql-test/r/pool_of_threads.result: Added test for pool-of-threads mysql-test/r/subselect_debug.result: USE GLOBAL for debug variable mysql-test/t/crash_commit_before.test: USE GLOBAL for debug variable mysql-test/t/merge-big.test: USE GLOBAL for debug variable mysql-test/t/pool_of_threads-master.opt: Added test for pool-of-threads mysql-test/t/pool_of_threads.test: Added test for pool-of-threads mysys/typelib.c: Split find_type_or_exit() into find_type_with_warning() sql/Makefile.am: Added libevent sql/handler.cc: Indentation fix. Fixed memory loss bug Fixed crash on exit when handler plugin failed sql/mysql_priv.h: Added extra_max_connections and mysqld_extra_port Added extern functions from sql_connect.cc sql/mysqld.cc: Added support for new mysqld options Added code for 'extra-port' and 'extra-max-connections' Split some functions into smaller pieces to be able to reuse code Added code for test-ignore-wrong-options sql/scheduler.cc: Updated schduler code from MySQL 6.0 sql/scheduler.h: Updated schduler code from MySQL 6.0 sql/set_var.cc: Added support for changing "extra_max_connections" sql/sql_class.cc: Iniitalize thread schduler options in THD sql/sql_class.h: Added to extra_port and scheduler to 'THD' sql/sql_connect.cc: Use thd->schduler to check number of connections and terminate connection Made some local functions global (for scheduler.cc) vio/viosocket.c: Added 'vio_pending', needed for scheduler..c
17 years ago
  1. /*
  2. * Copyright (c) 2007 Niels Provos <provos@citi.umich.edu>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. The name of the author may not be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #ifdef HAVE_CONFIG_H
  28. #include "config.h"
  29. #endif
  30. #ifdef WIN32
  31. #define WIN32_LEAN_AND_MEAN
  32. #include <windows.h>
  33. #undef WIN32_LEAN_AND_MEAN
  34. #include <winsock2.h>
  35. #include "misc.h"
  36. #endif
  37. #include <sys/types.h>
  38. #ifdef HAVE_SYS_SOCKET_H
  39. #include <sys/socket.h>
  40. #endif
  41. #ifdef HAVE_UNISTD_H
  42. #include <unistd.h>
  43. #endif
  44. #ifdef HAVE_FCNTL_H
  45. #include <fcntl.h>
  46. #endif
  47. #ifdef HAVE_STDLIB_H
  48. #include <stdlib.h>
  49. #endif
  50. #include <errno.h>
  51. #include "evutil.h"
  52. #include "log.h"
  53. int
  54. evutil_socketpair(int family, int type, int protocol, int fd[2])
  55. {
  56. #ifndef WIN32
  57. return socketpair(family, type, protocol, fd);
  58. #else
  59. /* This code is originally from Tor. Used with permission. */
  60. /* This socketpair does not work when localhost is down. So
  61. * it's really not the same thing at all. But it's close enough
  62. * for now, and really, when localhost is down sometimes, we
  63. * have other problems too.
  64. */
  65. int listener = -1;
  66. int connector = -1;
  67. int acceptor = -1;
  68. struct sockaddr_in listen_addr;
  69. struct sockaddr_in connect_addr;
  70. int size;
  71. int saved_errno = -1;
  72. if (protocol
  73. #ifdef AF_UNIX
  74. || family != AF_UNIX
  75. #endif
  76. ) {
  77. EVUTIL_SET_SOCKET_ERROR(WSAEAFNOSUPPORT);
  78. return -1;
  79. }
  80. if (!fd) {
  81. EVUTIL_SET_SOCKET_ERROR(WSAEINVAL);
  82. return -1;
  83. }
  84. listener = (int)socket(AF_INET, type, 0);
  85. if (listener < 0)
  86. return -1;
  87. memset(&listen_addr, 0, sizeof(listen_addr));
  88. listen_addr.sin_family = AF_INET;
  89. listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  90. listen_addr.sin_port = 0; /* kernel chooses port. */
  91. if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
  92. == -1)
  93. goto tidy_up_and_fail;
  94. if (listen(listener, 1) == -1)
  95. goto tidy_up_and_fail;
  96. connector = (int)socket(AF_INET, type, 0);
  97. if (connector < 0)
  98. goto tidy_up_and_fail;
  99. /* We want to find out the port number to connect to. */
  100. size = sizeof(connect_addr);
  101. if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
  102. goto tidy_up_and_fail;
  103. if (size != sizeof (connect_addr))
  104. goto abort_tidy_up_and_fail;
  105. if (connect(connector, (struct sockaddr *) &connect_addr,
  106. sizeof(connect_addr)) == -1)
  107. goto tidy_up_and_fail;
  108. size = sizeof(listen_addr);
  109. acceptor = (int)accept(listener, (struct sockaddr *) &listen_addr, &size);
  110. if (acceptor < 0)
  111. goto tidy_up_and_fail;
  112. if (size != sizeof(listen_addr))
  113. goto abort_tidy_up_and_fail;
  114. EVUTIL_CLOSESOCKET(listener);
  115. /* Now check we are talking to ourself by matching port and host on the
  116. two sockets. */
  117. if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
  118. goto tidy_up_and_fail;
  119. if (size != sizeof (connect_addr)
  120. || listen_addr.sin_family != connect_addr.sin_family
  121. || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
  122. || listen_addr.sin_port != connect_addr.sin_port)
  123. goto abort_tidy_up_and_fail;
  124. fd[0] = connector;
  125. fd[1] = acceptor;
  126. return 0;
  127. abort_tidy_up_and_fail:
  128. saved_errno = WSAECONNABORTED;
  129. tidy_up_and_fail:
  130. if (saved_errno < 0)
  131. saved_errno = WSAGetLastError();
  132. if (listener != -1)
  133. EVUTIL_CLOSESOCKET(listener);
  134. if (connector != -1)
  135. EVUTIL_CLOSESOCKET(connector);
  136. if (acceptor != -1)
  137. EVUTIL_CLOSESOCKET(acceptor);
  138. EVUTIL_SET_SOCKET_ERROR(saved_errno);
  139. return -1;
  140. #endif
  141. }
  142. int
  143. evutil_make_socket_nonblocking(int fd)
  144. {
  145. #ifdef WIN32
  146. {
  147. unsigned long nonblocking = 1;
  148. ioctlsocket(fd, FIONBIO, (unsigned long*) &nonblocking);
  149. }
  150. #else
  151. if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
  152. event_warn("fcntl(O_NONBLOCK)");
  153. return -1;
  154. }
  155. #endif
  156. return 0;
  157. }
  158. ev_int64_t
  159. evutil_strtoll(const char *s, char **endptr, int base)
  160. {
  161. #ifdef HAVE_STRTOLL
  162. return (ev_int64_t)strtoll(s, endptr, base);
  163. #elif SIZEOF_LONG == 8
  164. return (ev_int64_t)strtol(s, endptr, base);
  165. #elif defined(WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
  166. /* XXXX on old versions of MS APIs, we only support base
  167. * 10. */
  168. ev_int64_t r;
  169. if (base != 10)
  170. return 0;
  171. r = (ev_int64_t) _atoi64(s);
  172. while (isspace(*s))
  173. ++s;
  174. while (isdigit(*s))
  175. ++s;
  176. if (endptr)
  177. *endptr = (char*) s;
  178. return r;
  179. #elif defined(WIN32)
  180. return (ev_int64_t) _strtoi64(s, endptr, base);
  181. #else
  182. #error "I don't know how to parse 64-bit integers."
  183. #endif
  184. }