vincentchu-handlersocket 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/HandlerSocket-Plugin-for-MySQL/AUTHORS +22 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/COPYING +30 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/ChangeLog +12 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/Makefile.am +87 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/README +78 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/autogen.sh +117 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/Makefile.am +24 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp +88 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp +1041 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl +224 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest.cpp +1532 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest.pl +228 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_hs.sh +4 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_hs_more50.sh +4 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_md.sh +7 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_my.sh +3 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_my_more50.sh +3 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/configure.ac +144 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/about-handlersocket.en.txt +72 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/configuration-options.en.txt +99 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/installation.en.txt +92 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/perl-client.en.txt +135 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/protocol.en.txt +205 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/about-handlersocket.ja.txt +51 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/installation.ja.txt +88 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/perl-client.ja.txt +127 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/protocol.ja.txt +180 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/COPYRIGHT.txt +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/Makefile.am +10 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/Makefile.plain.template +31 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/database.cpp +1190 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/database.hpp +142 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/handlersocket.cpp +222 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/handlersocket.spec.template +29 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr.cpp +149 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr.hpp +58 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr_worker.cpp +951 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr_worker.hpp +35 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/mysql_incl.hpp +50 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/COPYRIGHT.txt +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/Makefile.am +12 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/Makefile.plain +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/allocator.hpp +64 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_addrinfo.hpp +49 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_file.hpp +64 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_ptrcontainer.hpp +67 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/config.cpp +67 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/config.hpp +32 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/escape.cpp +127 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/escape.hpp +66 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/fatal.cpp +36 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/fatal.hpp +22 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/hstcpcli.cpp +441 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/hstcpcli.hpp +62 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/libhsclient.spec.template +39 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/mutex.hpp +51 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/socket.cpp +186 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/socket.hpp +51 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_buffer.hpp +118 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_ref.hpp +63 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_util.cpp +182 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_util.hpp +53 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/thread.hpp +84 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/util.hpp +25 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/misc/microbench-hs.log +130 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/misc/microbench-my.log +125 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/COPYRIGHT.txt +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Changes +6 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/HandlerSocket.xs +632 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/MANIFEST +8 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Makefile.PL +18 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Makefile.PL.installed +20 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/README +30 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/lib/Net/HandlerSocket.pm +68 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm +362 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template +127 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/ppport.h +6375 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/t/Net-HandlerSocket.t +15 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/Makefile +79 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/binary_my.cnf +4 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/compat.sh +29 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/hstest.pm +66 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/Makefile +4 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/run.sh +27 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test01.expected +100 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test01.pl +38 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test02.expected +100 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test02.pl +49 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test03.expected +771 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test03.pl +61 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test04.expected +0 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test04.pl +63 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test05.expected +771 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test05.pl +59 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test06.expected +644 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test06.pl +90 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test07.expected +304 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test07.pl +98 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test08.expected +2 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test08.pl +48 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test09.expected +12 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test09.pl +67 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test10.expected +771 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test10.pl +93 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test11.expected +37 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test11.pl +112 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test12.expected +273 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test12.pl +134 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test13.expected +92 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test13.pl +92 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test14.expected +144 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test14.pl +80 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test15.expected +764 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test15.pl +114 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test16.expected +66 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test16.pl +88 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test17.expected +0 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test17.pl +125 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test18.expected +22 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test18.pl +63 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test19.expected +14894 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test19.pl +190 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test20.expected +2 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test20.pl +33 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test21.expected +11 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test21.pl +58 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test22.expected +9 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test22.pl +61 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test23.expected +101 -0
- data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test23.pl +53 -0
- data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/README +33 -0
- data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/extconf.rb +27 -0
- data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/handlersocket.cpp +437 -0
- data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/handlersocket.h +32 -0
- 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
|
+
|