nutcracker 0.2.4.12 → 0.3.0.12
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.
- 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
|