nutcracker 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/README.md +22 -0
  2. data/Rakefile +55 -0
  3. data/bin/nutcracker +2 -0
  4. data/ext/nutcracker/ChangeLog +66 -0
  5. data/ext/nutcracker/LICENSE +177 -0
  6. data/ext/nutcracker/Makefile.am +7 -0
  7. data/ext/nutcracker/Makefile.in +726 -0
  8. data/ext/nutcracker/NOTICE +124 -0
  9. data/ext/nutcracker/README.md +240 -0
  10. data/ext/nutcracker/aclocal.m4 +956 -0
  11. data/ext/nutcracker/conf/nutcracker.leaf.yml +10 -0
  12. data/ext/nutcracker/conf/nutcracker.root.yml +8 -0
  13. data/ext/nutcracker/conf/nutcracker.yml +67 -0
  14. data/ext/nutcracker/config.h.in +316 -0
  15. data/ext/nutcracker/config/config.guess +1561 -0
  16. data/ext/nutcracker/config/config.sub +1686 -0
  17. data/ext/nutcracker/config/depcomp +630 -0
  18. data/ext/nutcracker/config/install-sh +520 -0
  19. data/ext/nutcracker/config/ltmain.sh +8413 -0
  20. data/ext/nutcracker/config/missing +376 -0
  21. data/ext/nutcracker/configure +18862 -0
  22. data/ext/nutcracker/configure.ac +155 -0
  23. data/ext/nutcracker/contrib/Makefile.am +3 -0
  24. data/ext/nutcracker/contrib/Makefile.in +560 -0
  25. data/ext/nutcracker/contrib/yaml-0.1.4.tar.gz +0 -0
  26. data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
  27. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
  28. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +736 -0
  29. data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
  30. data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +956 -0
  31. data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +80 -0
  32. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1561 -0
  33. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1686 -0
  34. data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +630 -0
  35. data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +520 -0
  36. data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +8406 -0
  37. data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +376 -0
  38. data/ext/nutcracker/contrib/yaml-0.1.4/configure +13085 -0
  39. data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
  40. data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
  41. data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
  42. data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +7357 -0
  43. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +368 -0
  44. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +123 -0
  45. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
  46. data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +92 -0
  47. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
  48. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +484 -0
  49. data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
  50. data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
  51. data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
  52. data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
  53. data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
  54. data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
  55. data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
  56. data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
  57. data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
  58. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
  59. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +675 -0
  60. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
  61. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
  62. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
  63. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
  64. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
  65. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
  66. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
  67. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
  68. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
  69. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
  70. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
  71. data/ext/nutcracker/extconf.rb +5 -0
  72. data/ext/nutcracker/m4/libtool.m4 +7376 -0
  73. data/ext/nutcracker/m4/ltoptions.m4 +368 -0
  74. data/ext/nutcracker/m4/ltsugar.m4 +123 -0
  75. data/ext/nutcracker/m4/ltversion.m4 +23 -0
  76. data/ext/nutcracker/m4/lt~obsolete.m4 +92 -0
  77. data/ext/nutcracker/notes/c-styleguide.txt +425 -0
  78. data/ext/nutcracker/notes/debug.txt +96 -0
  79. data/ext/nutcracker/notes/memcache.txt +123 -0
  80. data/ext/nutcracker/notes/recommendation.md +118 -0
  81. data/ext/nutcracker/notes/redis.md +415 -0
  82. data/ext/nutcracker/notes/socket.txt +131 -0
  83. data/ext/nutcracker/scripts/multi_get.sh +26 -0
  84. data/ext/nutcracker/scripts/nutcracker.init +73 -0
  85. data/ext/nutcracker/scripts/nutcracker.spec +52 -0
  86. data/ext/nutcracker/scripts/pipelined_read.sh +23 -0
  87. data/ext/nutcracker/scripts/pipelined_write.sh +29 -0
  88. data/ext/nutcracker/scripts/populate_memcached.sh +24 -0
  89. data/ext/nutcracker/scripts/redis-check.py +23 -0
  90. data/ext/nutcracker/scripts/redis-check.sh +564 -0
  91. data/ext/nutcracker/src/Makefile.am +46 -0
  92. data/ext/nutcracker/src/Makefile.in +726 -0
  93. data/ext/nutcracker/src/hashkit/Makefile.am +22 -0
  94. data/ext/nutcracker/src/hashkit/Makefile.in +501 -0
  95. data/ext/nutcracker/src/hashkit/nc_crc32.c +105 -0
  96. data/ext/nutcracker/src/hashkit/nc_fnv.c +82 -0
  97. data/ext/nutcracker/src/hashkit/nc_hashkit.h +74 -0
  98. data/ext/nutcracker/src/hashkit/nc_hsieh.c +93 -0
  99. data/ext/nutcracker/src/hashkit/nc_jenkins.c +230 -0
  100. data/ext/nutcracker/src/hashkit/nc_ketama.c +240 -0
  101. data/ext/nutcracker/src/hashkit/nc_md5.c +379 -0
  102. data/ext/nutcracker/src/hashkit/nc_modula.c +144 -0
  103. data/ext/nutcracker/src/hashkit/nc_murmur.c +99 -0
  104. data/ext/nutcracker/src/hashkit/nc_one_at_a_time.c +51 -0
  105. data/ext/nutcracker/src/hashkit/nc_random.c +146 -0
  106. data/ext/nutcracker/src/nc.c +573 -0
  107. data/ext/nutcracker/src/nc_array.c +204 -0
  108. data/ext/nutcracker/src/nc_array.h +73 -0
  109. data/ext/nutcracker/src/nc_client.c +189 -0
  110. data/ext/nutcracker/src/nc_client.h +28 -0
  111. data/ext/nutcracker/src/nc_conf.c +1766 -0
  112. data/ext/nutcracker/src/nc_conf.h +134 -0
  113. data/ext/nutcracker/src/nc_connection.c +392 -0
  114. data/ext/nutcracker/src/nc_connection.h +99 -0
  115. data/ext/nutcracker/src/nc_core.c +334 -0
  116. data/ext/nutcracker/src/nc_core.h +131 -0
  117. data/ext/nutcracker/src/nc_event.c +214 -0
  118. data/ext/nutcracker/src/nc_event.h +39 -0
  119. data/ext/nutcracker/src/nc_log.c +254 -0
  120. data/ext/nutcracker/src/nc_log.h +120 -0
  121. data/ext/nutcracker/src/nc_mbuf.c +285 -0
  122. data/ext/nutcracker/src/nc_mbuf.h +67 -0
  123. data/ext/nutcracker/src/nc_message.c +828 -0
  124. data/ext/nutcracker/src/nc_message.h +253 -0
  125. data/ext/nutcracker/src/nc_proxy.c +359 -0
  126. data/ext/nutcracker/src/nc_proxy.h +34 -0
  127. data/ext/nutcracker/src/nc_queue.h +788 -0
  128. data/ext/nutcracker/src/nc_rbtree.c +348 -0
  129. data/ext/nutcracker/src/nc_rbtree.h +47 -0
  130. data/ext/nutcracker/src/nc_request.c +588 -0
  131. data/ext/nutcracker/src/nc_response.c +332 -0
  132. data/ext/nutcracker/src/nc_server.c +841 -0
  133. data/ext/nutcracker/src/nc_server.h +143 -0
  134. data/ext/nutcracker/src/nc_signal.c +131 -0
  135. data/ext/nutcracker/src/nc_signal.h +34 -0
  136. data/ext/nutcracker/src/nc_stats.c +1188 -0
  137. data/ext/nutcracker/src/nc_stats.h +206 -0
  138. data/ext/nutcracker/src/nc_string.c +109 -0
  139. data/ext/nutcracker/src/nc_string.h +112 -0
  140. data/ext/nutcracker/src/nc_util.c +619 -0
  141. data/ext/nutcracker/src/nc_util.h +214 -0
  142. data/ext/nutcracker/src/proto/Makefile.am +14 -0
  143. data/ext/nutcracker/src/proto/Makefile.in +482 -0
  144. data/ext/nutcracker/src/proto/nc_memcache.c +1306 -0
  145. data/ext/nutcracker/src/proto/nc_proto.h +155 -0
  146. data/ext/nutcracker/src/proto/nc_redis.c +2102 -0
  147. data/lib/nutcracker.rb +7 -0
  148. data/lib/nutcracker/version.rb +3 -0
  149. metadata +194 -0
@@ -0,0 +1,204 @@
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 <stdlib.h>
19
+
20
+ #include <nc_core.h>
21
+
22
+ struct array *
23
+ array_create(uint32_t n, size_t size)
24
+ {
25
+ struct array *a;
26
+
27
+ ASSERT(n != 0 && size != 0);
28
+
29
+ a = nc_alloc(sizeof(*a));
30
+ if (a == NULL) {
31
+ return NULL;
32
+ }
33
+
34
+ a->elem = nc_alloc(n * size);
35
+ if (a->elem == NULL) {
36
+ nc_free(a);
37
+ return NULL;
38
+ }
39
+
40
+ a->nelem = 0;
41
+ a->size = size;
42
+ a->nalloc = n;
43
+
44
+ return a;
45
+ }
46
+
47
+ void
48
+ array_destroy(struct array *a)
49
+ {
50
+ array_deinit(a);
51
+ nc_free(a);
52
+ }
53
+
54
+ rstatus_t
55
+ array_init(struct array *a, uint32_t n, size_t size)
56
+ {
57
+ ASSERT(n != 0 && size != 0);
58
+
59
+ a->elem = nc_alloc(n * size);
60
+ if (a->elem == NULL) {
61
+ return NC_ENOMEM;
62
+ }
63
+
64
+ a->nelem = 0;
65
+ a->size = size;
66
+ a->nalloc = n;
67
+
68
+ return NC_OK;
69
+ }
70
+
71
+ void
72
+ array_deinit(struct array *a)
73
+ {
74
+ ASSERT(a->nelem == 0);
75
+
76
+ if (a->elem != NULL) {
77
+ nc_free(a->elem);
78
+ }
79
+ }
80
+
81
+ uint32_t
82
+ array_idx(struct array *a, void *elem)
83
+ {
84
+ uint8_t *p, *q;
85
+ uint32_t off, idx;
86
+
87
+ ASSERT(elem >= a->elem);
88
+
89
+ p = a->elem;
90
+ q = elem;
91
+ off = (uint32_t)(q - p);
92
+
93
+ ASSERT(off % (uint32_t)a->size == 0);
94
+
95
+ idx = off / (uint32_t)a->size;
96
+
97
+ return idx;
98
+ }
99
+
100
+ void *
101
+ array_push(struct array *a)
102
+ {
103
+ void *elem, *new;
104
+ size_t size;
105
+
106
+ if (a->nelem == a->nalloc) {
107
+
108
+ /* the array is full; allocate new array */
109
+ size = a->size * a->nalloc;
110
+ new = nc_realloc(a->elem, 2 * size);
111
+ if (new == NULL) {
112
+ return NULL;
113
+ }
114
+
115
+ a->elem = new;
116
+ a->nalloc *= 2;
117
+ }
118
+
119
+ elem = (uint8_t *)a->elem + a->size * a->nelem;
120
+ a->nelem++;
121
+
122
+ return elem;
123
+ }
124
+
125
+ void *
126
+ array_pop(struct array *a)
127
+ {
128
+ void *elem;
129
+
130
+ ASSERT(a->nelem != 0);
131
+
132
+ a->nelem--;
133
+ elem = (uint8_t *)a->elem + a->size * a->nelem;
134
+
135
+ return elem;
136
+ }
137
+
138
+ void *
139
+ array_get(struct array *a, uint32_t idx)
140
+ {
141
+ void *elem;
142
+
143
+ ASSERT(a->nelem != 0);
144
+ ASSERT(idx < a->nelem);
145
+
146
+ elem = (uint8_t *)a->elem + (a->size * idx);
147
+
148
+ return elem;
149
+ }
150
+
151
+ void *
152
+ array_top(struct array *a)
153
+ {
154
+ ASSERT(a->nelem != 0);
155
+
156
+ return array_get(a, a->nelem - 1);
157
+ }
158
+
159
+ void
160
+ array_swap(struct array *a, struct array *b)
161
+ {
162
+ struct array tmp;
163
+
164
+ tmp = *a;
165
+ *a = *b;
166
+ *b = tmp;
167
+ }
168
+
169
+ /*
170
+ * Sort nelem elements of the array in ascending order based on the
171
+ * compare comparator.
172
+ */
173
+ void
174
+ array_sort(struct array *a, array_compare_t compare)
175
+ {
176
+ ASSERT(a->nelem != 0);
177
+
178
+ qsort(a->elem, a->nelem, a->size, compare);
179
+ }
180
+
181
+ /*
182
+ * Calls the func once for each element in the array as long as func returns
183
+ * success. On failure short-circuits and returns the error status.
184
+ */
185
+ rstatus_t
186
+ array_each(struct array *a, array_each_t func, void *data)
187
+ {
188
+ uint32_t i, nelem;
189
+
190
+ ASSERT(array_n(a) != 0);
191
+ ASSERT(func != NULL);
192
+
193
+ for (i = 0, nelem = array_n(a); i < nelem; i++) {
194
+ void *elem = array_get(a, i);
195
+ rstatus_t status;
196
+
197
+ status = func(elem, data);
198
+ if (status != NC_OK) {
199
+ return status;
200
+ }
201
+ }
202
+
203
+ return NC_OK;
204
+ }
@@ -0,0 +1,73 @@
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_ARRAY_H_
19
+ #define _NC_ARRAY_H_
20
+
21
+ #include <nc_core.h>
22
+
23
+ typedef int (*array_compare_t)(const void *, const void *);
24
+ typedef rstatus_t (*array_each_t)(void *, void *);
25
+
26
+ struct array {
27
+ uint32_t nelem; /* # element */
28
+ void *elem; /* element */
29
+ size_t size; /* element size */
30
+ uint32_t nalloc; /* # allocated element */
31
+ };
32
+
33
+ #define null_array { 0, NULL, 0, 0 }
34
+
35
+ static inline void
36
+ array_null(struct array *a)
37
+ {
38
+ a->nelem = 0;
39
+ a->elem = NULL;
40
+ a->size = 0;
41
+ a->nalloc = 0;
42
+ }
43
+
44
+ static inline void
45
+ array_set(struct array *a, void *elem, size_t size, uint32_t nalloc)
46
+ {
47
+ a->nelem = 0;
48
+ a->elem = elem;
49
+ a->size = size;
50
+ a->nalloc = nalloc;
51
+ }
52
+
53
+ static inline uint32_t
54
+ array_n(const struct array *a)
55
+ {
56
+ return a->nelem;
57
+ }
58
+
59
+ struct array *array_create(uint32_t n, size_t size);
60
+ void array_destroy(struct array *a);
61
+ rstatus_t array_init(struct array *a, uint32_t n, size_t size);
62
+ void array_deinit(struct array *a);
63
+
64
+ uint32_t array_idx(struct array *a, void *elem);
65
+ void *array_push(struct array *a);
66
+ void *array_pop(struct array *a);
67
+ void *array_get(struct array *a, uint32_t idx);
68
+ void *array_top(struct array *a);
69
+ void array_swap(struct array *a, struct array *b);
70
+ void array_sort(struct array *a, array_compare_t compare);
71
+ rstatus_t array_each(struct array *a, array_each_t func, void *data);
72
+
73
+ #endif
@@ -0,0 +1,189 @@
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 <nc_core.h>
19
+ #include <nc_server.h>
20
+ #include <nc_client.h>
21
+
22
+ void
23
+ client_ref(struct conn *conn, void *owner)
24
+ {
25
+ struct server_pool *pool = owner;
26
+
27
+ ASSERT(conn->client && !conn->proxy);
28
+ ASSERT(conn->owner == NULL);
29
+
30
+ /*
31
+ * We use null pointer as the sockaddr argument in the accept() call as
32
+ * we are not interested in the address of the peer for the accepted
33
+ * connection
34
+ */
35
+ conn->family = 0;
36
+ conn->addrlen = 0;
37
+ conn->addr = NULL;
38
+
39
+ pool->nc_conn_q++;
40
+ TAILQ_INSERT_TAIL(&pool->c_conn_q, conn, conn_tqe);
41
+
42
+ /* owner of the client connection is the server pool */
43
+ conn->owner = owner;
44
+
45
+ log_debug(LOG_VVERB, "ref conn %p owner %p into pool '%.*s'", conn, pool,
46
+ pool->name.len, pool->name.data);
47
+ }
48
+
49
+ void
50
+ client_unref(struct conn *conn)
51
+ {
52
+ struct server_pool *pool;
53
+
54
+ ASSERT(conn->client && !conn->proxy);
55
+ ASSERT(conn->owner != NULL);
56
+
57
+ pool = conn->owner;
58
+ conn->owner = NULL;
59
+
60
+ ASSERT(pool->nc_conn_q != 0);
61
+ pool->nc_conn_q--;
62
+ TAILQ_REMOVE(&pool->c_conn_q, conn, conn_tqe);
63
+
64
+ log_debug(LOG_VVERB, "unref conn %p owner %p from pool '%.*s'", conn,
65
+ pool, pool->name.len, pool->name.data);
66
+ }
67
+
68
+ bool
69
+ client_active(struct conn *conn)
70
+ {
71
+ ASSERT(conn->client && !conn->proxy);
72
+
73
+ ASSERT(TAILQ_EMPTY(&conn->imsg_q));
74
+
75
+ if (!TAILQ_EMPTY(&conn->omsg_q)) {
76
+ log_debug(LOG_VVERB, "c %d is active", conn->sd);
77
+ return true;
78
+ }
79
+
80
+ if (conn->rmsg != NULL) {
81
+ log_debug(LOG_VVERB, "c %d is active", conn->sd);
82
+ return true;
83
+ }
84
+
85
+ if (conn->smsg != NULL) {
86
+ log_debug(LOG_VVERB, "c %d is active", conn->sd);
87
+ return true;
88
+ }
89
+
90
+ log_debug(LOG_VVERB, "c %d is inactive", conn->sd);
91
+
92
+ return false;
93
+ }
94
+
95
+ static void
96
+ client_close_stats(struct context *ctx, struct server_pool *pool, err_t err,
97
+ unsigned eof)
98
+ {
99
+ stats_pool_decr(ctx, pool, client_connections);
100
+
101
+ if (eof) {
102
+ stats_pool_incr(ctx, pool, client_eof);
103
+ return;
104
+ }
105
+
106
+ switch (err) {
107
+ case EPIPE:
108
+ case ETIMEDOUT:
109
+ case ECONNRESET:
110
+ case ECONNABORTED:
111
+ case ENOTCONN:
112
+ case ENETDOWN:
113
+ case ENETUNREACH:
114
+ case EHOSTDOWN:
115
+ case EHOSTUNREACH:
116
+ default:
117
+ stats_pool_incr(ctx, pool, client_err);
118
+ break;
119
+ }
120
+ }
121
+
122
+ void
123
+ client_close(struct context *ctx, struct conn *conn)
124
+ {
125
+ rstatus_t status;
126
+ struct msg *msg, *nmsg; /* current and next message */
127
+
128
+ ASSERT(conn->client && !conn->proxy);
129
+
130
+ client_close_stats(ctx, conn->owner, conn->err, conn->eof);
131
+
132
+ if (conn->sd < 0) {
133
+ conn->unref(conn);
134
+ conn_put(conn);
135
+ return;
136
+ }
137
+
138
+ msg = conn->rmsg;
139
+ if (msg != NULL) {
140
+ conn->rmsg = NULL;
141
+
142
+ ASSERT(msg->peer == NULL);
143
+ ASSERT(msg->request && !msg->done);
144
+
145
+ log_debug(LOG_INFO, "close c %d discarding pending req %"PRIu64" len "
146
+ "%"PRIu32" type %d", conn->sd, msg->id, msg->mlen,
147
+ msg->type);
148
+
149
+ req_put(msg);
150
+ }
151
+
152
+ ASSERT(conn->smsg == NULL);
153
+ ASSERT(TAILQ_EMPTY(&conn->imsg_q));
154
+
155
+ for (msg = TAILQ_FIRST(&conn->omsg_q); msg != NULL; msg = nmsg) {
156
+ nmsg = TAILQ_NEXT(msg, c_tqe);
157
+
158
+ /* dequeue the message (request) from client outq */
159
+ conn->dequeue_outq(ctx, conn, msg);
160
+
161
+ if (msg->done) {
162
+ log_debug(LOG_INFO, "close c %d discarding %s req %"PRIu64" len "
163
+ "%"PRIu32" type %d", conn->sd,
164
+ msg->error ? "error": "completed", msg->id, msg->mlen,
165
+ msg->type);
166
+ req_put(msg);
167
+ } else {
168
+ msg->swallow = 1;
169
+
170
+ ASSERT(msg->request);
171
+ ASSERT(msg->peer == NULL);
172
+
173
+ log_debug(LOG_INFO, "close c %d schedule swallow of req %"PRIu64" "
174
+ "len %"PRIu32" type %d", conn->sd, msg->id, msg->mlen,
175
+ msg->type);
176
+ }
177
+ }
178
+ ASSERT(TAILQ_EMPTY(&conn->omsg_q));
179
+
180
+ conn->unref(conn);
181
+
182
+ status = close(conn->sd);
183
+ if (status < 0) {
184
+ log_error("close c %d failed, ignored: %s", conn->sd, strerror(errno));
185
+ }
186
+ conn->sd = -1;
187
+
188
+ conn_put(conn);
189
+ }