nutcracker 0.2.4.12 → 0.3.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Rakefile +1 -1
- data/ext/nutcracker/ChangeLog +10 -0
- data/ext/nutcracker/Makefile.am +2 -0
- data/ext/nutcracker/Makefile.in +101 -14
- data/ext/nutcracker/README.md +18 -1
- data/ext/nutcracker/config.h.in +18 -0
- data/ext/nutcracker/configure +196 -25
- data/ext/nutcracker/configure.ac +64 -6
- data/ext/nutcracker/extconf.rb +1 -1
- data/ext/nutcracker/man/nutcracker.8 +76 -0
- data/ext/nutcracker/notes/debug.txt +116 -16
- data/ext/nutcracker/notes/kqueue.pdf +0 -0
- data/ext/nutcracker/notes/recommendation.md +20 -0
- data/ext/nutcracker/notes/redis.md +2 -2
- data/ext/nutcracker/scripts/nutcracker.spec +1 -1
- data/ext/nutcracker/scripts/redis-check.sh +3 -1
- data/ext/nutcracker/src/Makefile.am +15 -6
- data/ext/nutcracker/src/Makefile.in +39 -36
- data/ext/nutcracker/src/event/Makefile.am +16 -0
- data/ext/nutcracker/src/event/Makefile.in +492 -0
- data/ext/nutcracker/src/event/nc_epoll.c +344 -0
- data/ext/nutcracker/src/event/nc_event.h +88 -0
- data/ext/nutcracker/src/event/nc_evport.c +420 -0
- data/ext/nutcracker/src/event/nc_kqueue.c +412 -0
- data/ext/nutcracker/src/hashkit/nc_crc32.c +19 -1
- data/ext/nutcracker/src/hashkit/nc_hashkit.h +3 -1
- data/ext/nutcracker/src/hashkit/nc_md5.c +257 -315
- data/ext/nutcracker/src/nc.c +12 -1
- data/ext/nutcracker/src/nc_connection.c +18 -1
- data/ext/nutcracker/src/nc_connection.h +1 -0
- data/ext/nutcracker/src/nc_core.c +22 -30
- data/ext/nutcracker/src/nc_core.h +22 -7
- data/ext/nutcracker/src/nc_proxy.c +8 -9
- data/ext/nutcracker/src/nc_queue.h +2 -0
- data/ext/nutcracker/src/nc_request.c +3 -4
- data/ext/nutcracker/src/nc_response.c +25 -8
- data/ext/nutcracker/src/nc_server.c +8 -6
- data/ext/nutcracker/src/nc_stats.c +46 -43
- data/ext/nutcracker/src/nc_stats.h +37 -30
- data/ext/nutcracker/src/nc_util.c +6 -1
- data/ext/nutcracker/src/proto/nc_redis.c +19 -5
- data/lib/nutcracker/version.rb +1 -1
- data/lib/nutcracker.rb +1 -1
- metadata +10 -4
- data/ext/nutcracker/src/nc_event.c +0 -214
- data/ext/nutcracker/src/nc_event.h +0 -39
@@ -18,36 +18,35 @@
|
|
18
18
|
#ifndef _NC_STATS_H_
|
19
19
|
#define _NC_STATS_H_
|
20
20
|
|
21
|
-
#include <sys/epoll.h>
|
22
|
-
|
23
21
|
#include <nc_core.h>
|
24
22
|
|
25
|
-
#define STATS_POOL_CODEC(ACTION)
|
26
|
-
/* client behavior */
|
27
|
-
ACTION( client_eof, STATS_COUNTER, "# eof on client connections")
|
28
|
-
ACTION( client_err, STATS_COUNTER, "# errors on client connections")
|
29
|
-
ACTION( client_connections, STATS_GAUGE, "# active client connections")
|
30
|
-
/* pool behavior */
|
31
|
-
ACTION( server_ejects, STATS_COUNTER, "# times backend server was ejected")
|
32
|
-
/* forwarder behavior */
|
33
|
-
ACTION( forward_error, STATS_COUNTER, "# times we encountered a forwarding error")
|
34
|
-
ACTION( fragments, STATS_COUNTER, "# fragments created from a multi-vector request")
|
35
|
-
|
36
|
-
#define STATS_SERVER_CODEC(ACTION)
|
37
|
-
/* server behavior */
|
38
|
-
ACTION( server_eof, STATS_COUNTER, "# eof on server connections")
|
39
|
-
ACTION( server_err, STATS_COUNTER, "# errors on server connections")
|
40
|
-
ACTION( server_timedout, STATS_COUNTER, "# timeouts on server connections")
|
41
|
-
ACTION( server_connections, STATS_GAUGE, "# active server connections")
|
42
|
-
|
43
|
-
|
44
|
-
ACTION(
|
45
|
-
ACTION(
|
46
|
-
ACTION(
|
47
|
-
ACTION(
|
48
|
-
ACTION(
|
49
|
-
ACTION(
|
50
|
-
ACTION(
|
23
|
+
#define STATS_POOL_CODEC(ACTION) \
|
24
|
+
/* client behavior */ \
|
25
|
+
ACTION( client_eof, STATS_COUNTER, "# eof on client connections") \
|
26
|
+
ACTION( client_err, STATS_COUNTER, "# errors on client connections") \
|
27
|
+
ACTION( client_connections, STATS_GAUGE, "# active client connections") \
|
28
|
+
/* pool behavior */ \
|
29
|
+
ACTION( server_ejects, STATS_COUNTER, "# times backend server was ejected") \
|
30
|
+
/* forwarder behavior */ \
|
31
|
+
ACTION( forward_error, STATS_COUNTER, "# times we encountered a forwarding error") \
|
32
|
+
ACTION( fragments, STATS_COUNTER, "# fragments created from a multi-vector request") \
|
33
|
+
|
34
|
+
#define STATS_SERVER_CODEC(ACTION) \
|
35
|
+
/* server behavior */ \
|
36
|
+
ACTION( server_eof, STATS_COUNTER, "# eof on server connections") \
|
37
|
+
ACTION( server_err, STATS_COUNTER, "# errors on server connections") \
|
38
|
+
ACTION( server_timedout, STATS_COUNTER, "# timeouts on server connections") \
|
39
|
+
ACTION( server_connections, STATS_GAUGE, "# active server connections") \
|
40
|
+
ACTION( server_ejected_at, STATS_TIMESTAMP, "timestamp when server was ejected in usec since epoch") \
|
41
|
+
/* data behavior */ \
|
42
|
+
ACTION( requests, STATS_COUNTER, "# requests") \
|
43
|
+
ACTION( request_bytes, STATS_COUNTER, "total request bytes") \
|
44
|
+
ACTION( responses, STATS_COUNTER, "# respones") \
|
45
|
+
ACTION( response_bytes, STATS_COUNTER, "total response bytes") \
|
46
|
+
ACTION( in_queue, STATS_GAUGE, "# requests in incoming queue") \
|
47
|
+
ACTION( in_queue_bytes, STATS_GAUGE, "current request bytes in incoming queue") \
|
48
|
+
ACTION( out_queue, STATS_GAUGE, "# requests in outgoing queue") \
|
49
|
+
ACTION( out_queue_bytes, STATS_GAUGE, "current request bytes in outgoing queue") \
|
51
50
|
|
52
51
|
#define STATS_ADDR "0.0.0.0"
|
53
52
|
#define STATS_PORT 22222
|
@@ -101,8 +100,6 @@ struct stats {
|
|
101
100
|
|
102
101
|
pthread_t tid; /* stats aggregator thread */
|
103
102
|
int sd; /* stats descriptor */
|
104
|
-
int ep; /* epoll device */
|
105
|
-
struct epoll_event event; /* epoll event */
|
106
103
|
|
107
104
|
struct string service_str; /* service string */
|
108
105
|
struct string service; /* service */
|
@@ -149,6 +146,10 @@ typedef enum stats_server_field {
|
|
149
146
|
_stats_pool_decr_by(_ctx, _pool, STATS_POOL_##_name, _val); \
|
150
147
|
} while (0)
|
151
148
|
|
149
|
+
#define stats_pool_set_ts(_ctx, _pool, _name, _val) do { \
|
150
|
+
_stats_pool_set_ts(_ctx, _pool, STATS_POOL_##_name, _val); \
|
151
|
+
} while (0)
|
152
|
+
|
152
153
|
#define stats_server_incr(_ctx, _server, _name) do { \
|
153
154
|
_stats_server_incr(_ctx, _server, STATS_SERVER_##_name); \
|
154
155
|
} while (0)
|
@@ -165,6 +166,10 @@ typedef enum stats_server_field {
|
|
165
166
|
_stats_server_decr_by(_ctx, _server, STATS_SERVER_##_name, _val); \
|
166
167
|
} while (0)
|
167
168
|
|
169
|
+
#define stats_server_set_ts(_ctx, _server, _name, _val) do { \
|
170
|
+
_stats_server_set_ts(_ctx, _server, STATS_SERVER_##_name, _val); \
|
171
|
+
} while (0)
|
172
|
+
|
168
173
|
#else
|
169
174
|
|
170
175
|
#define stats_pool_incr(_ctx, _pool, _name)
|
@@ -193,11 +198,13 @@ void _stats_pool_incr(struct context *ctx, struct server_pool *pool, stats_pool_
|
|
193
198
|
void _stats_pool_decr(struct context *ctx, struct server_pool *pool, stats_pool_field_t fidx);
|
194
199
|
void _stats_pool_incr_by(struct context *ctx, struct server_pool *pool, stats_pool_field_t fidx, int64_t val);
|
195
200
|
void _stats_pool_decr_by(struct context *ctx, struct server_pool *pool, stats_pool_field_t fidx, int64_t val);
|
201
|
+
void _stats_pool_set_ts(struct context *ctx, struct server_pool *pool, stats_pool_field_t fidx, int64_t val);
|
196
202
|
|
197
203
|
void _stats_server_incr(struct context *ctx, struct server *server, stats_server_field_t fidx);
|
198
204
|
void _stats_server_decr(struct context *ctx, struct server *server, stats_server_field_t fidx);
|
199
205
|
void _stats_server_incr_by(struct context *ctx, struct server *server, stats_server_field_t fidx, int64_t val);
|
200
206
|
void _stats_server_decr_by(struct context *ctx, struct server *server, stats_server_field_t fidx, int64_t val);
|
207
|
+
void _stats_server_set_ts(struct context *ctx, struct server *server, stats_server_field_t fidx, int64_t val);
|
201
208
|
|
202
209
|
struct stats *stats_create(uint16_t stats_port, char *stats_ip, int stats_interval, char *source, struct array *server_pool);
|
203
210
|
void stats_destroy(struct stats *stats);
|
@@ -22,7 +22,6 @@
|
|
22
22
|
#include <unistd.h>
|
23
23
|
#include <fcntl.h>
|
24
24
|
#include <netdb.h>
|
25
|
-
#include <execinfo.h>
|
26
25
|
|
27
26
|
#include <sys/time.h>
|
28
27
|
#include <sys/types.h>
|
@@ -34,6 +33,10 @@
|
|
34
33
|
|
35
34
|
#include <nc_core.h>
|
36
35
|
|
36
|
+
#ifdef NC_HAVE_BACKTRACE
|
37
|
+
# include <execinfo.h>
|
38
|
+
#endif
|
39
|
+
|
37
40
|
int
|
38
41
|
nc_set_blocking(int sd)
|
39
42
|
{
|
@@ -275,6 +278,7 @@ _nc_free(void *ptr, const char *name, int line)
|
|
275
278
|
void
|
276
279
|
nc_stacktrace(int skip_count)
|
277
280
|
{
|
281
|
+
#ifdef NC_HAVE_BACKTRACE
|
278
282
|
void *stack[64];
|
279
283
|
char **symbols;
|
280
284
|
int size, i, j;
|
@@ -292,6 +296,7 @@ nc_stacktrace(int skip_count)
|
|
292
296
|
}
|
293
297
|
|
294
298
|
free(symbols);
|
299
|
+
#endif
|
295
300
|
}
|
296
301
|
|
297
302
|
void
|
@@ -53,7 +53,6 @@ redis_arg0(struct msg *r)
|
|
53
53
|
case MSG_REQ_REDIS_SCARD:
|
54
54
|
case MSG_REQ_REDIS_SMEMBERS:
|
55
55
|
case MSG_REQ_REDIS_SPOP:
|
56
|
-
case MSG_REQ_REDIS_SRANDMEMBER:
|
57
56
|
|
58
57
|
case MSG_REQ_REDIS_ZCARD:
|
59
58
|
return true;
|
@@ -84,7 +83,6 @@ redis_arg1(struct msg *r)
|
|
84
83
|
case MSG_REQ_REDIS_GETSET:
|
85
84
|
case MSG_REQ_REDIS_INCRBY:
|
86
85
|
case MSG_REQ_REDIS_INCRBYFLOAT:
|
87
|
-
case MSG_REQ_REDIS_SET:
|
88
86
|
case MSG_REQ_REDIS_SETNX:
|
89
87
|
|
90
88
|
case MSG_REQ_REDIS_HEXISTS:
|
@@ -178,6 +176,7 @@ redis_argn(struct msg *r)
|
|
178
176
|
switch (r->type) {
|
179
177
|
case MSG_REQ_REDIS_BITCOUNT:
|
180
178
|
|
179
|
+
case MSG_REQ_REDIS_SET:
|
181
180
|
case MSG_REQ_REDIS_HDEL:
|
182
181
|
case MSG_REQ_REDIS_HMGET:
|
183
182
|
case MSG_REQ_REDIS_HMSET:
|
@@ -193,6 +192,7 @@ redis_argn(struct msg *r)
|
|
193
192
|
case MSG_REQ_REDIS_SREM:
|
194
193
|
case MSG_REQ_REDIS_SUNION:
|
195
194
|
case MSG_REQ_REDIS_SUNIONSTORE:
|
195
|
+
case MSG_REQ_REDIS_SRANDMEMBER:
|
196
196
|
|
197
197
|
case MSG_REQ_REDIS_ZADD:
|
198
198
|
case MSG_REQ_REDIS_ZINTERSTORE:
|
@@ -1538,6 +1538,7 @@ redis_parse_rsp(struct msg *r)
|
|
1538
1538
|
struct mbuf *b;
|
1539
1539
|
uint8_t *p, *m;
|
1540
1540
|
uint8_t ch;
|
1541
|
+
|
1541
1542
|
enum {
|
1542
1543
|
SW_START,
|
1543
1544
|
SW_STATUS,
|
@@ -1675,6 +1676,7 @@ redis_parse_rsp(struct msg *r)
|
|
1675
1676
|
r->token = p;
|
1676
1677
|
r->rlen = 0;
|
1677
1678
|
} else if (ch == '-') {
|
1679
|
+
/* handles null bulk reply = '$-1' */
|
1678
1680
|
state = SW_RUNTO_CRLF;
|
1679
1681
|
} else if (isdigit(ch)) {
|
1680
1682
|
r->rlen = r->rlen * 10 + (uint32_t)(ch - '0');
|
@@ -1742,12 +1744,15 @@ redis_parse_rsp(struct msg *r)
|
|
1742
1744
|
/* rsp_start <- p */
|
1743
1745
|
r->narg_start = p;
|
1744
1746
|
r->rnarg = 0;
|
1747
|
+
} else if (ch == '-') {
|
1748
|
+
state = SW_RUNTO_CRLF;
|
1745
1749
|
} else if (isdigit(ch)) {
|
1746
1750
|
r->rnarg = r->rnarg * 10 + (uint32_t)(ch - '0');
|
1747
1751
|
} else if (ch == CR) {
|
1748
1752
|
if ((p - r->token) <= 1) {
|
1749
1753
|
goto error;
|
1750
1754
|
}
|
1755
|
+
|
1751
1756
|
r->narg = r->rnarg;
|
1752
1757
|
r->narg_end = p;
|
1753
1758
|
r->token = NULL;
|
@@ -1776,7 +1781,16 @@ redis_parse_rsp(struct msg *r)
|
|
1776
1781
|
|
1777
1782
|
case SW_MULTIBULK_ARGN_LEN:
|
1778
1783
|
if (r->token == NULL) {
|
1779
|
-
|
1784
|
+
/*
|
1785
|
+
* From: http://redis.io/topics/protocol, a multi bulk reply
|
1786
|
+
* is used to return an array of other replies. Every element
|
1787
|
+
* of a multi bulk reply can be of any kind, including a
|
1788
|
+
* nested multi bulk reply.
|
1789
|
+
*
|
1790
|
+
* Here, we only handle a multi bulk reply element that
|
1791
|
+
* are either integer reply or bulk reply.
|
1792
|
+
*/
|
1793
|
+
if (ch != '$' && ch != ':') {
|
1780
1794
|
goto error;
|
1781
1795
|
}
|
1782
1796
|
r->token = p;
|
@@ -1790,8 +1804,8 @@ redis_parse_rsp(struct msg *r)
|
|
1790
1804
|
goto error;
|
1791
1805
|
}
|
1792
1806
|
|
1793
|
-
if (r->rlen == 1 && (p - r->token) == 3) {
|
1794
|
-
/* handles not-found reply = '$-1'*/
|
1807
|
+
if ((r->rlen == 1 && (p - r->token) == 3) || *r->token == ':') {
|
1808
|
+
/* handles not-found reply = '$-1' or integer reply = ':<num>' */
|
1795
1809
|
r->rlen = 0;
|
1796
1810
|
state = SW_MULTIBULK_ARGN_LF;
|
1797
1811
|
} else {
|
data/lib/nutcracker/version.rb
CHANGED
data/lib/nutcracker.rb
CHANGED
@@ -50,7 +50,7 @@ module Nutcracker
|
|
50
50
|
@pid = ::Process.spawn Nutcracker.executable, *command
|
51
51
|
Process.detach(@pid)
|
52
52
|
sleep 2
|
53
|
-
|
53
|
+
raise "Nutcracker failed to start" unless running?
|
54
54
|
Kernel.at_exit { kill if running? }
|
55
55
|
self
|
56
56
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nutcracker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eran Barak Levi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -136,8 +136,10 @@ files:
|
|
136
136
|
- ext/nutcracker/m4/lt~obsolete.m4
|
137
137
|
- ext/nutcracker/Makefile.am
|
138
138
|
- ext/nutcracker/Makefile.in
|
139
|
+
- ext/nutcracker/man/nutcracker.8
|
139
140
|
- ext/nutcracker/notes/c-styleguide.txt
|
140
141
|
- ext/nutcracker/notes/debug.txt
|
142
|
+
- ext/nutcracker/notes/kqueue.pdf
|
141
143
|
- ext/nutcracker/notes/memcache.txt
|
142
144
|
- ext/nutcracker/notes/recommendation.md
|
143
145
|
- ext/nutcracker/notes/redis.md
|
@@ -152,6 +154,12 @@ files:
|
|
152
154
|
- ext/nutcracker/scripts/populate_memcached.sh
|
153
155
|
- ext/nutcracker/scripts/redis-check.py
|
154
156
|
- ext/nutcracker/scripts/redis-check.sh
|
157
|
+
- ext/nutcracker/src/event/Makefile.am
|
158
|
+
- ext/nutcracker/src/event/Makefile.in
|
159
|
+
- ext/nutcracker/src/event/nc_epoll.c
|
160
|
+
- ext/nutcracker/src/event/nc_event.h
|
161
|
+
- ext/nutcracker/src/event/nc_evport.c
|
162
|
+
- ext/nutcracker/src/event/nc_kqueue.c
|
155
163
|
- ext/nutcracker/src/hashkit/Makefile.am
|
156
164
|
- ext/nutcracker/src/hashkit/Makefile.in
|
157
165
|
- ext/nutcracker/src/hashkit/nc_crc16.c
|
@@ -179,8 +187,6 @@ files:
|
|
179
187
|
- ext/nutcracker/src/nc_connection.h
|
180
188
|
- ext/nutcracker/src/nc_core.c
|
181
189
|
- ext/nutcracker/src/nc_core.h
|
182
|
-
- ext/nutcracker/src/nc_event.c
|
183
|
-
- ext/nutcracker/src/nc_event.h
|
184
190
|
- ext/nutcracker/src/nc_log.c
|
185
191
|
- ext/nutcracker/src/nc_log.h
|
186
192
|
- ext/nutcracker/src/nc_mbuf.c
|
@@ -1,214 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* twemproxy - A fast and lightweight proxy for memcached protocol.
|
3
|
-
* Copyright (C) 2011 Twitter, Inc.
|
4
|
-
*
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
* you may not use this file except in compliance with the License.
|
7
|
-
* You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
*
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
* See the License for the specific language governing permissions and
|
15
|
-
* limitations under the License.
|
16
|
-
*/
|
17
|
-
|
18
|
-
#include <unistd.h>
|
19
|
-
#include <sys/epoll.h>
|
20
|
-
|
21
|
-
#include <nc_core.h>
|
22
|
-
#include <nc_event.h>
|
23
|
-
|
24
|
-
int
|
25
|
-
event_init(struct context *ctx, int size)
|
26
|
-
{
|
27
|
-
int status, ep;
|
28
|
-
struct epoll_event *event;
|
29
|
-
|
30
|
-
ASSERT(ctx->ep < 0);
|
31
|
-
ASSERT(ctx->nevent != 0);
|
32
|
-
ASSERT(ctx->event == NULL);
|
33
|
-
|
34
|
-
ep = epoll_create(size);
|
35
|
-
if (ep < 0) {
|
36
|
-
log_error("epoll create of size %d failed: %s", size, strerror(errno));
|
37
|
-
return -1;
|
38
|
-
}
|
39
|
-
|
40
|
-
event = nc_calloc(ctx->nevent, sizeof(*ctx->event));
|
41
|
-
if (event == NULL) {
|
42
|
-
status = close(ep);
|
43
|
-
if (status < 0) {
|
44
|
-
log_error("close e %d failed, ignored: %s", ep, strerror(errno));
|
45
|
-
}
|
46
|
-
return -1;
|
47
|
-
}
|
48
|
-
|
49
|
-
ctx->ep = ep;
|
50
|
-
ctx->event = event;
|
51
|
-
|
52
|
-
log_debug(LOG_INFO, "e %d with nevent %d timeout %d", ctx->ep,
|
53
|
-
ctx->nevent, ctx->timeout);
|
54
|
-
|
55
|
-
return 0;
|
56
|
-
}
|
57
|
-
|
58
|
-
void
|
59
|
-
event_deinit(struct context *ctx)
|
60
|
-
{
|
61
|
-
int status;
|
62
|
-
|
63
|
-
ASSERT(ctx->ep >= 0);
|
64
|
-
|
65
|
-
nc_free(ctx->event);
|
66
|
-
|
67
|
-
status = close(ctx->ep);
|
68
|
-
if (status < 0) {
|
69
|
-
log_error("close e %d failed, ignored: %s", ctx->ep, strerror(errno));
|
70
|
-
}
|
71
|
-
ctx->ep = -1;
|
72
|
-
}
|
73
|
-
|
74
|
-
int
|
75
|
-
event_add_out(int ep, struct conn *c)
|
76
|
-
{
|
77
|
-
int status;
|
78
|
-
struct epoll_event event;
|
79
|
-
|
80
|
-
ASSERT(ep > 0);
|
81
|
-
ASSERT(c != NULL);
|
82
|
-
ASSERT(c->sd > 0);
|
83
|
-
ASSERT(c->recv_active);
|
84
|
-
|
85
|
-
if (c->send_active) {
|
86
|
-
return 0;
|
87
|
-
}
|
88
|
-
|
89
|
-
event.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
|
90
|
-
event.data.ptr = c;
|
91
|
-
|
92
|
-
status = epoll_ctl(ep, EPOLL_CTL_MOD, c->sd, &event);
|
93
|
-
if (status < 0) {
|
94
|
-
log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
|
95
|
-
strerror(errno));
|
96
|
-
} else {
|
97
|
-
c->send_active = 1;
|
98
|
-
}
|
99
|
-
|
100
|
-
return status;
|
101
|
-
}
|
102
|
-
|
103
|
-
int
|
104
|
-
event_del_out(int ep, struct conn *c)
|
105
|
-
{
|
106
|
-
int status;
|
107
|
-
struct epoll_event event;
|
108
|
-
|
109
|
-
ASSERT(ep > 0);
|
110
|
-
ASSERT(c != NULL);
|
111
|
-
ASSERT(c->sd > 0);
|
112
|
-
ASSERT(c->recv_active);
|
113
|
-
|
114
|
-
if (!c->send_active) {
|
115
|
-
return 0;
|
116
|
-
}
|
117
|
-
|
118
|
-
event.events = (uint32_t)(EPOLLIN | EPOLLET);
|
119
|
-
event.data.ptr = c;
|
120
|
-
|
121
|
-
status = epoll_ctl(ep, EPOLL_CTL_MOD, c->sd, &event);
|
122
|
-
if (status < 0) {
|
123
|
-
log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
|
124
|
-
strerror(errno));
|
125
|
-
} else {
|
126
|
-
c->send_active = 0;
|
127
|
-
}
|
128
|
-
|
129
|
-
return status;
|
130
|
-
}
|
131
|
-
|
132
|
-
int
|
133
|
-
event_add_conn(int ep, struct conn *c)
|
134
|
-
{
|
135
|
-
int status;
|
136
|
-
struct epoll_event event;
|
137
|
-
|
138
|
-
ASSERT(ep > 0);
|
139
|
-
ASSERT(c != NULL);
|
140
|
-
ASSERT(c->sd > 0);
|
141
|
-
|
142
|
-
event.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
|
143
|
-
event.data.ptr = c;
|
144
|
-
|
145
|
-
status = epoll_ctl(ep, EPOLL_CTL_ADD, c->sd, &event);
|
146
|
-
if (status < 0) {
|
147
|
-
log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
|
148
|
-
strerror(errno));
|
149
|
-
} else {
|
150
|
-
c->send_active = 1;
|
151
|
-
c->recv_active = 1;
|
152
|
-
}
|
153
|
-
|
154
|
-
return status;
|
155
|
-
}
|
156
|
-
|
157
|
-
int
|
158
|
-
event_del_conn(int ep, struct conn *c)
|
159
|
-
{
|
160
|
-
int status;
|
161
|
-
|
162
|
-
ASSERT(ep > 0);
|
163
|
-
ASSERT(c != NULL);
|
164
|
-
ASSERT(c->sd > 0);
|
165
|
-
|
166
|
-
status = epoll_ctl(ep, EPOLL_CTL_DEL, c->sd, NULL);
|
167
|
-
if (status < 0) {
|
168
|
-
log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
|
169
|
-
strerror(errno));
|
170
|
-
} else {
|
171
|
-
c->recv_active = 0;
|
172
|
-
c->send_active = 0;
|
173
|
-
}
|
174
|
-
|
175
|
-
return status;
|
176
|
-
}
|
177
|
-
|
178
|
-
int
|
179
|
-
event_wait(int ep, struct epoll_event *event, int nevent, int timeout)
|
180
|
-
{
|
181
|
-
int nsd;
|
182
|
-
|
183
|
-
ASSERT(ep > 0);
|
184
|
-
ASSERT(event != NULL);
|
185
|
-
ASSERT(nevent > 0);
|
186
|
-
|
187
|
-
for (;;) {
|
188
|
-
nsd = epoll_wait(ep, event, nevent, timeout);
|
189
|
-
if (nsd > 0) {
|
190
|
-
return nsd;
|
191
|
-
}
|
192
|
-
|
193
|
-
if (nsd == 0) {
|
194
|
-
if (timeout == -1) {
|
195
|
-
log_error("epoll wait on e %d with %d events and %d timeout "
|
196
|
-
"returned no events", ep, nevent, timeout);
|
197
|
-
return -1;
|
198
|
-
}
|
199
|
-
|
200
|
-
return 0;
|
201
|
-
}
|
202
|
-
|
203
|
-
if (errno == EINTR) {
|
204
|
-
continue;
|
205
|
-
}
|
206
|
-
|
207
|
-
log_error("epoll wait on e %d with %d events failed: %s", ep, nevent,
|
208
|
-
strerror(errno));
|
209
|
-
|
210
|
-
return -1;
|
211
|
-
}
|
212
|
-
|
213
|
-
NOT_REACHED();
|
214
|
-
}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* twemproxy - A fast and lightweight proxy for memcached protocol.
|
3
|
-
* Copyright (C) 2011 Twitter, Inc.
|
4
|
-
*
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
* you may not use this file except in compliance with the License.
|
7
|
-
* You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
*
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
* See the License for the specific language governing permissions and
|
15
|
-
* limitations under the License.
|
16
|
-
*/
|
17
|
-
|
18
|
-
#ifndef _NC_EVENT_H_
|
19
|
-
#define _NC_EVENT_H_
|
20
|
-
|
21
|
-
#include <nc_core.h>
|
22
|
-
|
23
|
-
/*
|
24
|
-
* A hint to the kernel that is used to size the event backing store
|
25
|
-
* of a given epoll instance
|
26
|
-
*/
|
27
|
-
#define EVENT_SIZE_HINT 1024
|
28
|
-
|
29
|
-
int event_init(struct context *ctx, int size);
|
30
|
-
void event_deinit(struct context *ctx);
|
31
|
-
|
32
|
-
int event_add_out(int ep, struct conn *c);
|
33
|
-
int event_del_out(int ep, struct conn *c);
|
34
|
-
int event_add_conn(int ep, struct conn *c);
|
35
|
-
int event_del_conn(int ep, struct conn *c);
|
36
|
-
|
37
|
-
int event_wait(int ep, struct epoll_event *event, int nevent, int timeout);
|
38
|
-
|
39
|
-
#endif
|