vincentchu-handlersocket 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. data/ext/HandlerSocket-Plugin-for-MySQL/AUTHORS +22 -0
  2. data/ext/HandlerSocket-Plugin-for-MySQL/COPYING +30 -0
  3. data/ext/HandlerSocket-Plugin-for-MySQL/ChangeLog +12 -0
  4. data/ext/HandlerSocket-Plugin-for-MySQL/Makefile.am +87 -0
  5. data/ext/HandlerSocket-Plugin-for-MySQL/README +78 -0
  6. data/ext/HandlerSocket-Plugin-for-MySQL/autogen.sh +117 -0
  7. data/ext/HandlerSocket-Plugin-for-MySQL/client/Makefile.am +24 -0
  8. data/ext/HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp +88 -0
  9. data/ext/HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp +1041 -0
  10. data/ext/HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl +224 -0
  11. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest.cpp +1532 -0
  12. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest.pl +228 -0
  13. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_hs.sh +4 -0
  14. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_hs_more50.sh +4 -0
  15. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_md.sh +7 -0
  16. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_my.sh +3 -0
  17. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_my_more50.sh +3 -0
  18. data/ext/HandlerSocket-Plugin-for-MySQL/configure.ac +144 -0
  19. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/about-handlersocket.en.txt +72 -0
  20. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/configuration-options.en.txt +99 -0
  21. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/installation.en.txt +92 -0
  22. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/perl-client.en.txt +135 -0
  23. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/protocol.en.txt +205 -0
  24. data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/about-handlersocket.ja.txt +51 -0
  25. data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/installation.ja.txt +88 -0
  26. data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/perl-client.ja.txt +127 -0
  27. data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/protocol.ja.txt +180 -0
  28. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/COPYRIGHT.txt +27 -0
  29. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/Makefile.am +10 -0
  30. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/Makefile.plain.template +31 -0
  31. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/database.cpp +1190 -0
  32. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/database.hpp +142 -0
  33. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/handlersocket.cpp +222 -0
  34. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/handlersocket.spec.template +29 -0
  35. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr.cpp +149 -0
  36. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr.hpp +58 -0
  37. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr_worker.cpp +951 -0
  38. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr_worker.hpp +35 -0
  39. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/mysql_incl.hpp +50 -0
  40. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/COPYRIGHT.txt +27 -0
  41. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/Makefile.am +12 -0
  42. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/Makefile.plain +27 -0
  43. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/allocator.hpp +64 -0
  44. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_addrinfo.hpp +49 -0
  45. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_file.hpp +64 -0
  46. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_ptrcontainer.hpp +67 -0
  47. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/config.cpp +67 -0
  48. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/config.hpp +32 -0
  49. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/escape.cpp +127 -0
  50. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/escape.hpp +66 -0
  51. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/fatal.cpp +36 -0
  52. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/fatal.hpp +22 -0
  53. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/hstcpcli.cpp +441 -0
  54. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/hstcpcli.hpp +62 -0
  55. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/libhsclient.spec.template +39 -0
  56. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/mutex.hpp +51 -0
  57. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/socket.cpp +186 -0
  58. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/socket.hpp +51 -0
  59. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_buffer.hpp +118 -0
  60. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_ref.hpp +63 -0
  61. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_util.cpp +182 -0
  62. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_util.hpp +53 -0
  63. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/thread.hpp +84 -0
  64. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/util.hpp +25 -0
  65. data/ext/HandlerSocket-Plugin-for-MySQL/misc/microbench-hs.log +130 -0
  66. data/ext/HandlerSocket-Plugin-for-MySQL/misc/microbench-my.log +125 -0
  67. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/COPYRIGHT.txt +27 -0
  68. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Changes +6 -0
  69. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/HandlerSocket.xs +632 -0
  70. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/MANIFEST +8 -0
  71. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Makefile.PL +18 -0
  72. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Makefile.PL.installed +20 -0
  73. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/README +30 -0
  74. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/lib/Net/HandlerSocket.pm +68 -0
  75. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm +362 -0
  76. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template +127 -0
  77. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/ppport.h +6375 -0
  78. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/t/Net-HandlerSocket.t +15 -0
  79. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/Makefile +79 -0
  80. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/binary_my.cnf +4 -0
  81. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/compat.sh +29 -0
  82. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/hstest.pm +66 -0
  83. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/Makefile +4 -0
  84. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/run.sh +27 -0
  85. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test01.expected +100 -0
  86. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test01.pl +38 -0
  87. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test02.expected +100 -0
  88. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test02.pl +49 -0
  89. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test03.expected +771 -0
  90. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test03.pl +61 -0
  91. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test04.expected +0 -0
  92. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test04.pl +63 -0
  93. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test05.expected +771 -0
  94. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test05.pl +59 -0
  95. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test06.expected +644 -0
  96. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test06.pl +90 -0
  97. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test07.expected +304 -0
  98. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test07.pl +98 -0
  99. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test08.expected +2 -0
  100. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test08.pl +48 -0
  101. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test09.expected +12 -0
  102. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test09.pl +67 -0
  103. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test10.expected +771 -0
  104. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test10.pl +93 -0
  105. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test11.expected +37 -0
  106. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test11.pl +112 -0
  107. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test12.expected +273 -0
  108. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test12.pl +134 -0
  109. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test13.expected +92 -0
  110. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test13.pl +92 -0
  111. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test14.expected +144 -0
  112. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test14.pl +80 -0
  113. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test15.expected +764 -0
  114. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test15.pl +114 -0
  115. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test16.expected +66 -0
  116. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test16.pl +88 -0
  117. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test17.expected +0 -0
  118. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test17.pl +125 -0
  119. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test18.expected +22 -0
  120. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test18.pl +63 -0
  121. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test19.expected +14894 -0
  122. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test19.pl +190 -0
  123. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test20.expected +2 -0
  124. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test20.pl +33 -0
  125. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test21.expected +11 -0
  126. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test21.pl +58 -0
  127. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test22.expected +9 -0
  128. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test22.pl +61 -0
  129. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test23.expected +101 -0
  130. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test23.pl +53 -0
  131. data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/README +33 -0
  132. data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/extconf.rb +27 -0
  133. data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/handlersocket.cpp +437 -0
  134. data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/handlersocket.h +32 -0
  135. metadata +200 -0
@@ -0,0 +1,142 @@
1
+
2
+ // vim:sw=2:ai
3
+
4
+ /*
5
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
+ * See COPYRIGHT.txt for details.
7
+ */
8
+
9
+ #ifndef DENA_DATABASE_HPP
10
+ #define DENA_DATABASE_HPP
11
+
12
+ #include <string>
13
+ #include <memory>
14
+ #include <vector>
15
+ #include <stdint.h>
16
+
17
+ #include "string_buffer.hpp"
18
+ #include "string_ref.hpp"
19
+ #include "config.hpp"
20
+
21
+ namespace dena {
22
+
23
+ struct database_i;
24
+ typedef std::auto_ptr<volatile database_i> database_ptr;
25
+
26
+ struct dbcontext_i;
27
+ typedef std::auto_ptr<dbcontext_i> dbcontext_ptr;
28
+
29
+ struct database_i {
30
+ virtual ~database_i() { }
31
+ virtual dbcontext_ptr create_context(bool for_write) volatile = 0;
32
+ virtual void stop() volatile = 0;
33
+ virtual const config& get_conf() const volatile = 0;
34
+ static database_ptr create(const config& conf);
35
+ };
36
+
37
+ struct prep_stmt {
38
+ typedef std::vector<uint32_t> fields_type;
39
+ private:
40
+ dbcontext_i *dbctx; /* must be valid while *this is alive */
41
+ size_t table_id; /* a prep_stmt object holds a refcount of the table */
42
+ size_t idxnum;
43
+ fields_type ret_fields;
44
+ fields_type filter_fields;
45
+ public:
46
+ prep_stmt();
47
+ prep_stmt(dbcontext_i *c, size_t tbl, size_t idx, const fields_type& rf,
48
+ const fields_type& ff);
49
+ ~prep_stmt();
50
+ prep_stmt(const prep_stmt& x);
51
+ prep_stmt& operator =(const prep_stmt& x);
52
+ public:
53
+ size_t get_table_id() const { return table_id; }
54
+ size_t get_idxnum() const { return idxnum; }
55
+ const fields_type& get_ret_fields() const { return ret_fields; }
56
+ const fields_type& get_filter_fields() const { return filter_fields; }
57
+ };
58
+
59
+ struct dbcallback_i {
60
+ virtual ~dbcallback_i () { }
61
+ virtual void dbcb_set_prep_stmt(size_t pst_id, const prep_stmt& v) = 0;
62
+ virtual const prep_stmt *dbcb_get_prep_stmt(size_t pst_id) const = 0;
63
+ virtual void dbcb_resp_short(uint32_t code, const char *msg) = 0;
64
+ virtual void dbcb_resp_short_num(uint32_t code, uint32_t value) = 0;
65
+ virtual void dbcb_resp_short_num64(uint32_t code, uint64_t value) = 0;
66
+ virtual void dbcb_resp_begin(size_t num_flds) = 0;
67
+ virtual void dbcb_resp_entry(const char *fld, size_t fldlen) = 0;
68
+ virtual void dbcb_resp_end() = 0;
69
+ virtual void dbcb_resp_cancel() = 0;
70
+ };
71
+
72
+ enum record_filter_type {
73
+ record_filter_type_skip = 0,
74
+ record_filter_type_break = 1,
75
+ };
76
+
77
+ struct record_filter {
78
+ record_filter_type filter_type;
79
+ string_ref op;
80
+ uint32_t ff_offset; /* offset in filter_fields */
81
+ string_ref val;
82
+ record_filter() : filter_type(record_filter_type_skip), ff_offset(0) { }
83
+ };
84
+
85
+ struct cmd_open_args {
86
+ size_t pst_id;
87
+ const char *dbn;
88
+ const char *tbl;
89
+ const char *idx;
90
+ const char *retflds;
91
+ const char *filflds;
92
+ cmd_open_args() : pst_id(0), dbn(0), tbl(0), idx(0), retflds(0),
93
+ filflds(0) { }
94
+ };
95
+
96
+ struct cmd_exec_args {
97
+ const prep_stmt *pst;
98
+ string_ref op;
99
+ const string_ref *kvals;
100
+ size_t kvalslen;
101
+ uint32_t limit;
102
+ uint32_t skip;
103
+ string_ref mod_op;
104
+ const string_ref *uvals; /* size must be pst->retfieelds.size() */
105
+ const record_filter *filters;
106
+ int invalues_keypart;
107
+ const string_ref *invalues;
108
+ size_t invalueslen;
109
+ cmd_exec_args() : pst(0), kvals(0), kvalslen(0), limit(0), skip(0),
110
+ uvals(0), filters(0), invalues_keypart(-1), invalues(0), invalueslen(0) { }
111
+ };
112
+
113
+ struct dbcontext_i {
114
+ virtual ~dbcontext_i() { }
115
+ virtual void init_thread(const void *stack_bottom,
116
+ volatile int& shutdown_flag) = 0;
117
+ virtual void term_thread() = 0;
118
+ virtual bool check_alive() = 0;
119
+ virtual void lock_tables_if() = 0;
120
+ virtual void unlock_tables_if() = 0;
121
+ virtual bool get_commit_error() = 0;
122
+ virtual void clear_error() = 0;
123
+ virtual void close_tables_if() = 0;
124
+ virtual void table_addref(size_t tbl_id) = 0; /* TODO: hide */
125
+ virtual void table_release(size_t tbl_id) = 0; /* TODO: hide */
126
+ virtual void cmd_open(dbcallback_i& cb, const cmd_open_args& args) = 0;
127
+ virtual void cmd_exec(dbcallback_i& cb, const cmd_exec_args& args) = 0;
128
+ virtual void set_statistics(size_t num_conns, size_t num_active) = 0;
129
+ };
130
+
131
+ };
132
+
133
+ extern unsigned long long int open_tables_count;
134
+ extern unsigned long long int close_tables_count;
135
+ extern unsigned long long int lock_tables_count;
136
+ extern unsigned long long int unlock_tables_count;
137
+ #if 0
138
+ extern unsigned long long int index_exec_count;
139
+ #endif
140
+
141
+ #endif
142
+
@@ -0,0 +1,222 @@
1
+
2
+ // vim:sw=2:ai
3
+
4
+ /*
5
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
+ * See COPYRIGHT.txt for details.
7
+ */
8
+
9
+ #include <memory>
10
+ #include <string>
11
+ #include <stdio.h>
12
+
13
+ #include "config.hpp"
14
+ #include "hstcpsvr.hpp"
15
+ #include "string_util.hpp"
16
+ #include "mysql_incl.hpp"
17
+
18
+ #define DBG_LOG \
19
+ if (dena::verbose_level >= 100) { \
20
+ fprintf(stderr, "%s %p\n", __PRETTY_FUNCTION__, this); \
21
+ }
22
+ #define DBG_DO(x) if (dena::verbose_level >= 100) { x; }
23
+
24
+ #define DBG_DIR(x)
25
+
26
+ using namespace dena;
27
+
28
+ static char *handlersocket_address = 0;
29
+ static char *handlersocket_port = 0;
30
+ static char *handlersocket_port_wr = 0;
31
+ static unsigned int handlersocket_epoll = 1;
32
+ static unsigned int handlersocket_threads = 32;
33
+ static unsigned int handlersocket_threads_wr = 1;
34
+ static unsigned int handlersocket_timeout = 30;
35
+ static unsigned int handlersocket_backlog = 32768;
36
+ static unsigned int handlersocket_sndbuf = 0;
37
+ static unsigned int handlersocket_rcvbuf = 0;
38
+ static unsigned int handlersocket_readsize = 0;
39
+ static unsigned int handlersocket_accept_balance = 0;
40
+ static unsigned int handlersocket_wrlock_timeout = 0;
41
+ static char *handlersocket_plain_secret = 0;
42
+ static char *handlersocket_plain_secret_wr = 0;
43
+
44
+ struct daemon_handlersocket_data {
45
+ hstcpsvr_ptr hssvr_rd;
46
+ hstcpsvr_ptr hssvr_wr;
47
+ };
48
+
49
+ static int
50
+ daemon_handlersocket_init(void *p)
51
+ {
52
+ config conf;
53
+ conf["use_epoll"] = handlersocket_epoll ? "1" : "0";
54
+ if (handlersocket_address) {
55
+ conf["host"] = handlersocket_address;
56
+ }
57
+ if (handlersocket_port) {
58
+ conf["port"] = handlersocket_port;
59
+ }
60
+ /*
61
+ * unix domain socket
62
+ * conf["host"] = "/";
63
+ * conf["port"] = "/tmp/handlersocket";
64
+ */
65
+ if (handlersocket_threads > 0) {
66
+ conf["num_threads"] = to_stdstring(handlersocket_threads);
67
+ } else {
68
+ conf["num_threads"] = "1";
69
+ }
70
+ conf["timeout"] = to_stdstring(handlersocket_timeout);
71
+ conf["listen_backlog"] = to_stdstring(handlersocket_backlog);
72
+ conf["sndbuf"] = to_stdstring(handlersocket_sndbuf);
73
+ conf["rcvbuf"] = to_stdstring(handlersocket_rcvbuf);
74
+ conf["readsize"] = to_stdstring(handlersocket_readsize);
75
+ conf["accept_balance"] = to_stdstring(handlersocket_accept_balance);
76
+ conf["wrlock_timeout"] = to_stdstring(handlersocket_wrlock_timeout);
77
+ std::auto_ptr<daemon_handlersocket_data> ap(new daemon_handlersocket_data);
78
+ if (handlersocket_port != 0 && handlersocket_port_wr != handlersocket_port) {
79
+ conf["port"] = handlersocket_port;
80
+ if (handlersocket_plain_secret) {
81
+ conf["plain_secret"] = handlersocket_plain_secret;
82
+ }
83
+ ap->hssvr_rd = hstcpsvr_i::create(conf);
84
+ ap->hssvr_rd->start_listen();
85
+ } else {
86
+ DENA_VERBOSE(10, fprintf(stderr, "handlersocket: not listening "
87
+ "for reads\n"));
88
+ }
89
+ if (handlersocket_port_wr != 0) {
90
+ if (handlersocket_threads_wr > 0) {
91
+ conf["num_threads"] = to_stdstring(handlersocket_threads_wr);
92
+ }
93
+ conf["port"] = handlersocket_port_wr;
94
+ conf["for_write"] = "1";
95
+ conf["plain_secret"] = "";
96
+ if (handlersocket_plain_secret_wr) {
97
+ conf["plain_secret"] = handlersocket_plain_secret_wr;
98
+ }
99
+ ap->hssvr_wr = hstcpsvr_i::create(conf);
100
+ ap->hssvr_wr->start_listen();
101
+ } else {
102
+ DENA_VERBOSE(10, fprintf(stderr, "handlersocket: not listening "
103
+ "for writes\n"));
104
+ }
105
+ st_plugin_int *const plugin = static_cast<st_plugin_int *>(p);
106
+ plugin->data = ap.release();
107
+ DENA_VERBOSE(10, fprintf(stderr, "handlersocket: initialized\n"));
108
+ return 0;
109
+ }
110
+
111
+ static int
112
+ daemon_handlersocket_deinit(void *p)
113
+ {
114
+ DENA_VERBOSE(10, fprintf(stderr, "handlersocket: terminated\n"));
115
+ st_plugin_int *const plugin = static_cast<st_plugin_int *>(p);
116
+ daemon_handlersocket_data *ptr =
117
+ static_cast<daemon_handlersocket_data *>(plugin->data);
118
+ delete ptr;
119
+ return 0;
120
+ }
121
+
122
+ static struct st_mysql_daemon daemon_handlersocket_plugin = {
123
+ MYSQL_DAEMON_INTERFACE_VERSION
124
+ };
125
+
126
+ static MYSQL_SYSVAR_UINT(verbose, dena::verbose_level, 0,
127
+ "0..10000", 0, 0, 10 /* default */, 0, 10000, 0);
128
+ static MYSQL_SYSVAR_UINT(epoll, handlersocket_epoll, PLUGIN_VAR_READONLY,
129
+ "0..1", 0, 0, 1 /* default */, 0, 1, 0);
130
+ static MYSQL_SYSVAR_STR(address, handlersocket_address,
131
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
132
+ static MYSQL_SYSVAR_STR(port, handlersocket_port,
133
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
134
+ static MYSQL_SYSVAR_STR(port_wr, handlersocket_port_wr,
135
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
136
+ static MYSQL_SYSVAR_UINT(threads, handlersocket_threads, PLUGIN_VAR_READONLY,
137
+ "1..3000", 0, 0, 16 /* default */, 1, 3000, 0);
138
+ static MYSQL_SYSVAR_UINT(threads_wr, handlersocket_threads_wr,
139
+ PLUGIN_VAR_READONLY, "1..3000", 0, 0, 1 /* default */, 1, 3000, 0);
140
+ static MYSQL_SYSVAR_UINT(timeout, handlersocket_timeout, PLUGIN_VAR_READONLY,
141
+ "30..3600", 0, 0, 300 /* default */, 30, 3600, 0);
142
+ static MYSQL_SYSVAR_UINT(backlog, handlersocket_backlog, PLUGIN_VAR_READONLY,
143
+ "5..1000000", 0, 0, 32768 /* default */, 5, 1000000, 0);
144
+ static MYSQL_SYSVAR_UINT(sndbuf, handlersocket_sndbuf, PLUGIN_VAR_READONLY,
145
+ "0..16777216", 0, 0, 0 /* default */, 0, 16777216, 0);
146
+ static MYSQL_SYSVAR_UINT(rcvbuf, handlersocket_rcvbuf, PLUGIN_VAR_READONLY,
147
+ "0..16777216", 0, 0, 0 /* default */, 0, 16777216, 0);
148
+ static MYSQL_SYSVAR_UINT(readsize, handlersocket_readsize, PLUGIN_VAR_READONLY,
149
+ "0..16777216", 0, 0, 0 /* default */, 0, 16777216, 0);
150
+ static MYSQL_SYSVAR_UINT(accept_balance, handlersocket_accept_balance,
151
+ PLUGIN_VAR_READONLY, "0..10000", 0, 0, 0 /* default */, 0, 10000, 0);
152
+ static MYSQL_SYSVAR_UINT(wrlock_timeout, handlersocket_wrlock_timeout,
153
+ PLUGIN_VAR_READONLY, "0..3600", 0, 0, 12 /* default */, 0, 3600, 0);
154
+ static MYSQL_SYSVAR_STR(plain_secret, handlersocket_plain_secret,
155
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
156
+ static MYSQL_SYSVAR_STR(plain_secret_wr, handlersocket_plain_secret_wr,
157
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
158
+
159
+
160
+ /* warning: type-punning to incomplete type might break strict-aliasing
161
+ * rules */
162
+ static struct st_mysql_sys_var *daemon_handlersocket_system_variables[] = {
163
+ MYSQL_SYSVAR(verbose),
164
+ MYSQL_SYSVAR(address),
165
+ MYSQL_SYSVAR(port),
166
+ MYSQL_SYSVAR(port_wr),
167
+ MYSQL_SYSVAR(epoll),
168
+ MYSQL_SYSVAR(threads),
169
+ MYSQL_SYSVAR(threads_wr),
170
+ MYSQL_SYSVAR(timeout),
171
+ MYSQL_SYSVAR(backlog),
172
+ MYSQL_SYSVAR(sndbuf),
173
+ MYSQL_SYSVAR(rcvbuf),
174
+ MYSQL_SYSVAR(readsize),
175
+ MYSQL_SYSVAR(accept_balance),
176
+ MYSQL_SYSVAR(wrlock_timeout),
177
+ MYSQL_SYSVAR(plain_secret),
178
+ MYSQL_SYSVAR(plain_secret_wr),
179
+ 0
180
+ };
181
+
182
+ static SHOW_VAR hs_status_variables[] = {
183
+ {"table_open", (char*) &open_tables_count, SHOW_LONGLONG},
184
+ {"table_close", (char*) &close_tables_count, SHOW_LONGLONG},
185
+ {"table_lock", (char*) &lock_tables_count, SHOW_LONGLONG},
186
+ {"table_unlock", (char*) &unlock_tables_count, SHOW_LONGLONG},
187
+ #if 0
188
+ {"index_exec", (char*) &index_exec_count, SHOW_LONGLONG},
189
+ #endif
190
+ {NullS, NullS, SHOW_LONG}
191
+ };
192
+
193
+ static int show_hs_vars(THD *thd, SHOW_VAR *var, char *buff)
194
+ {
195
+ var->type= SHOW_ARRAY;
196
+ var->value= (char *) &hs_status_variables;
197
+ return 0;
198
+ }
199
+
200
+ static SHOW_VAR daemon_handlersocket_status_variables[] = {
201
+ {"Hs", (char*) show_hs_vars, SHOW_FUNC},
202
+ {NullS, NullS, SHOW_LONG}
203
+ };
204
+
205
+
206
+ mysql_declare_plugin(handlersocket)
207
+ {
208
+ MYSQL_DAEMON_PLUGIN,
209
+ &daemon_handlersocket_plugin,
210
+ "handlersocket",
211
+ "higuchi dot akira at dena dot jp",
212
+ "",
213
+ PLUGIN_LICENSE_BSD,
214
+ daemon_handlersocket_init,
215
+ daemon_handlersocket_deinit,
216
+ 0x0100 /* 1.0 */,
217
+ daemon_handlersocket_status_variables,
218
+ daemon_handlersocket_system_variables,
219
+ 0
220
+ }
221
+ mysql_declare_plugin_end;
222
+
@@ -0,0 +1,29 @@
1
+ Summary: handlersocket plugin for mysql
2
+ Name: handlersocket
3
+ Version: HANDLERSOCKET_VERSION
4
+ Release: 1%{?dist}
5
+ Group: System Environment/Libraries
6
+ License: BSD
7
+ Source: handlersocket.tar.gz
8
+ Packager: Akira Higuchi <higuchi dot akira at dena dot jp>
9
+ BuildRoot: /var/tmp/%{name}-%{version}-root
10
+
11
+ %description
12
+
13
+ %prep
14
+ %setup -n %{name}
15
+
16
+ %define _use_internal_dependency_generator 0
17
+
18
+ %build
19
+ make -f Makefile.plain
20
+
21
+ %install
22
+ rm -rf $RPM_BUILD_ROOT
23
+ mkdir -p $RPM_BUILD_ROOT/%{_libdir}/mysql/plugin
24
+ install -m 755 handlersocket.so $RPM_BUILD_ROOT/%{_libdir}/mysql/plugin/
25
+
26
+ %files
27
+ %defattr(-, root, root)
28
+ %{_libdir}/mysql/plugin/*.so
29
+
@@ -0,0 +1,149 @@
1
+
2
+ // vim:sw=2:ai
3
+
4
+ /*
5
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
+ * See COPYRIGHT.txt for details.
7
+ */
8
+
9
+ #include <stdlib.h>
10
+ #include <vector>
11
+ #include <sys/types.h>
12
+ #include <sys/socket.h>
13
+ #include <netinet/in.h>
14
+ #include <unistd.h>
15
+ #include <fcntl.h>
16
+ #include <sys/resource.h>
17
+
18
+ #include "hstcpsvr.hpp"
19
+ #include "hstcpsvr_worker.hpp"
20
+ #include "thread.hpp"
21
+ #include "fatal.hpp"
22
+ #include "auto_ptrcontainer.hpp"
23
+
24
+ #define DBG(x)
25
+
26
+ namespace dena {
27
+
28
+ struct worker_throbj {
29
+ worker_throbj(const hstcpsvr_worker_arg& arg)
30
+ : worker(hstcpsvr_worker_i::create(arg)) { }
31
+ void operator ()() {
32
+ worker->run();
33
+ }
34
+ hstcpsvr_worker_ptr worker;
35
+ };
36
+
37
+ struct hstcpsvr : public hstcpsvr_i, private noncopyable {
38
+ hstcpsvr(const config& c);
39
+ ~hstcpsvr();
40
+ virtual std::string start_listen();
41
+ private:
42
+ hstcpsvr_shared_c cshared;
43
+ volatile hstcpsvr_shared_v vshared;
44
+ typedef thread<worker_throbj> worker_thread_type;
45
+ typedef auto_ptrcontainer< std::vector<worker_thread_type *> > threads_type;
46
+ threads_type threads;
47
+ std::vector<unsigned int> thread_num_conns_vec;
48
+ private:
49
+ void stop_workers();
50
+ };
51
+
52
+ namespace {
53
+
54
+ void
55
+ check_nfile(size_t nfile)
56
+ {
57
+ struct rlimit rl = { };
58
+ const int r = getrlimit(RLIMIT_NOFILE, &rl);
59
+ if (r != 0) {
60
+ fatal_abort("check_nfile: getrlimit failed");
61
+ }
62
+ if (rl.rlim_cur < static_cast<rlim_t>(nfile + 1000)) {
63
+ fprintf(stderr,
64
+ "[Warning] handlersocket: open_files_limit is too small.\n");
65
+ }
66
+ }
67
+
68
+ };
69
+
70
+ hstcpsvr::hstcpsvr(const config& c)
71
+ : cshared(), vshared()
72
+ {
73
+ vshared.shutdown = 0;
74
+ cshared.conf = c; /* copy */
75
+ if (cshared.conf["port"] == "") {
76
+ cshared.conf["port"] = "9999";
77
+ }
78
+ cshared.num_threads = cshared.conf.get_int("num_threads", 32);
79
+ cshared.sockargs.nonblocking = cshared.conf.get_int("nonblocking", 1);
80
+ cshared.sockargs.use_epoll = cshared.conf.get_int("use_epoll", 1);
81
+ if (cshared.sockargs.use_epoll) {
82
+ cshared.sockargs.nonblocking = 1;
83
+ }
84
+ cshared.readsize = cshared.conf.get_int("readsize", 1);
85
+ cshared.nb_conn_per_thread = cshared.conf.get_int("conn_per_thread", 1024);
86
+ cshared.for_write_flag = cshared.conf.get_int("for_write", 0);
87
+ cshared.plain_secret = cshared.conf.get_str("plain_secret", "");
88
+ cshared.require_auth = !cshared.plain_secret.empty();
89
+ cshared.sockargs.set(cshared.conf);
90
+ cshared.dbptr = database_i::create(c);
91
+ check_nfile(cshared.num_threads * cshared.nb_conn_per_thread);
92
+ thread_num_conns_vec.resize(cshared.num_threads);
93
+ cshared.thread_num_conns = thread_num_conns_vec.empty()
94
+ ? 0 : &thread_num_conns_vec[0];
95
+ }
96
+
97
+ hstcpsvr::~hstcpsvr()
98
+ {
99
+ stop_workers();
100
+ }
101
+
102
+ std::string
103
+ hstcpsvr::start_listen()
104
+ {
105
+ std::string err;
106
+ if (threads.size() != 0) {
107
+ return "start_listen: already running";
108
+ }
109
+ if (socket_bind(cshared.listen_fd, cshared.sockargs, err) != 0) {
110
+ return "bind: " + err;
111
+ }
112
+ DENA_VERBOSE(20, fprintf(stderr, "bind done\n"));
113
+ const size_t stack_size = std::max(
114
+ cshared.conf.get_int("stack_size", 1 * 1024LL * 1024), 8 * 1024LL * 1024);
115
+ for (long i = 0; i < cshared.num_threads; ++i) {
116
+ hstcpsvr_worker_arg arg;
117
+ arg.cshared = &cshared;
118
+ arg.vshared = &vshared;
119
+ arg.worker_id = i;
120
+ std::auto_ptr< thread<worker_throbj> > thr(
121
+ new thread<worker_throbj>(arg, stack_size));
122
+ threads.push_back_ptr(thr);
123
+ }
124
+ DENA_VERBOSE(20, fprintf(stderr, "threads created\n"));
125
+ for (size_t i = 0; i < threads.size(); ++i) {
126
+ threads[i]->start();
127
+ }
128
+ DENA_VERBOSE(20, fprintf(stderr, "threads started\n"));
129
+ return std::string();
130
+ }
131
+
132
+ void
133
+ hstcpsvr::stop_workers()
134
+ {
135
+ vshared.shutdown = 1;
136
+ for (size_t i = 0; i < threads.size(); ++i) {
137
+ threads[i]->join();
138
+ }
139
+ threads.clear();
140
+ }
141
+
142
+ hstcpsvr_ptr
143
+ hstcpsvr_i::create(const config& conf)
144
+ {
145
+ return hstcpsvr_ptr(new hstcpsvr(conf));
146
+ }
147
+
148
+ };
149
+