Skip to content

Commit 954c0af

Browse files
committed
Fix memory allocate during request processing
Before introducing a txn memory region box_txn_alloc() allocates memory using the fiber.gc region and can be used without box_txn_begin(). Now the similar trick doesn't work (a transaction must be started). To allocate memory on region without start a transaction, the region was added to struct memcached_connection. Fixes #53
1 parent d6e2a6f commit 954c0af

File tree

5 files changed

+27
-7
lines changed

5 files changed

+27
-7
lines changed

memcached/internal/memcached.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,17 @@ memcached_flush(struct memcached_connection *con) {
7878
return total;
7979
}
8080

81+
static void
82+
memcached_connection_gc(struct memcached_connection *con)
83+
{
84+
if (region_used(&con->gc) < 128 * 1024) {
85+
region_reset(&con->gc);
86+
return;
87+
}
88+
89+
region_free(&con->gc);
90+
}
91+
8192
static inline int
8293
memcached_loop_read(struct memcached_connection *con, size_t to_read)
8394
{
@@ -176,7 +187,10 @@ memcached_loop(struct memcached_connection *con)
176187
}
177188
assert(!con->close_connection);
178189
rc = 0;
179-
if (!con->noprocess) rc = con->cb.process_request(con);
190+
if (!con->noprocess) {
191+
rc = con->cb.process_request(con);
192+
memcached_connection_gc(con);
193+
}
180194
con->write_end = obuf_create_svp(con->out);
181195
memcached_skip_request(con);
182196
if (rc == -1)
@@ -233,6 +247,8 @@ memcached_handler(struct memcached_service *p, int fd)
233247
assert(0); /* unreacheable */
234248
}
235249

250+
region_create(&con.gc, cord_slab_cache());
251+
236252
/* read-write cycle */
237253
con.cfg->stat.curr_conns++;
238254
con.cfg->stat.total_conns++;
@@ -242,6 +258,7 @@ memcached_handler(struct memcached_service *p, int fd)
242258
iobuf_delete(con.in, con.out);
243259
memcached_sasl_connection_destroy(&con);
244260
free((void *)con.sasl_ctx);
261+
region_destroy(&con.gc);
245262
const box_error_t *err = box_error_last();
246263
if (err)
247264
say_error("%s", box_error_message(err));

memcached/internal/memcached.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212

1313
#include <small/obuf.h>
14+
#include <small/region.h>
1415
#include "constants.h"
1516

1617
struct memcached_connection;
@@ -142,6 +143,8 @@ struct memcached_connection {
142143
memcached_loop_func_t process_request;
143144
memcached_error_func_t process_error;
144145
} cb; /* protocol specific callbacks */
146+
/* A garbage collected memory pool used in request processing. */
147+
struct region gc;
145148
};
146149

147150
struct memcached_stat *

memcached/internal/memcached_layer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ memcached_tuple_set(struct memcached_connection *con,
7171
mp_sizeof_str (vlen) +
7272
mp_sizeof_uint (cas) +
7373
mp_sizeof_uint (flags);
74-
char *begin = (char *)box_txn_alloc(len);
74+
char *begin = (char *)region_alloc(&con->gc, len);
7575
if (begin == NULL) {
7676
memcached_error_ENOMEM(len, "tuple");
7777
return -1;
@@ -95,7 +95,7 @@ memcached_tuple_get(struct memcached_connection *con,
9595
/* Create key for getting previous tuple from space */
9696
uint32_t len = mp_sizeof_array(1) +
9797
mp_sizeof_str (key_len);
98-
char *begin = (char *)box_txn_alloc(len);
98+
char *begin = (char *)region_alloc(&con->gc, len);
9999
if (begin == NULL) {
100100
memcached_error_ENOMEM(len, "key");
101101
return -1;

memcached/internal/proto_bin.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ memcached_bin_process_delete(struct memcached_connection *con)
324324
con->cfg->stat.cmd_delete++;
325325
uint32_t len = mp_sizeof_array(1) +
326326
mp_sizeof_str (b->key_len);
327-
char *begin = (char *)box_txn_alloc(len);
327+
char *begin = (char *)region_alloc(&con->gc, len);
328328
if (begin == NULL) {
329329
memcached_error_ENOMEM(len, "key");
330330
return -1;
@@ -682,7 +682,7 @@ memcached_bin_process_pend(struct memcached_connection *con)
682682
mp_next(&pos); /* skip cas */
683683
flags = mp_decode_uint(&pos);
684684

685-
char *begin = (char *)box_txn_alloc(b->val_len + vlen);
685+
char *begin = (char *)region_alloc(&con->gc, b->val_len + vlen);
686686
if (begin == NULL) {
687687
memcached_error_ENOMEM(b->val_len + vlen, "value");
688688
return -1;

memcached/internal/proto_txt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ memcached_txt_process_pend(struct memcached_connection *con)
288288
mp_next(&pos); /* skip cas */
289289
flags = mp_decode_uint(&pos);
290290

291-
char *begin = (char *)box_txn_alloc(data_len + vlen);
291+
char *begin = (char *)region_alloc(&con->gc, data_len + vlen);
292292
if (begin == NULL) {
293293
memcached_error_ENOMEM(data_len + vlen, "value");
294294
return -1;
@@ -322,7 +322,7 @@ memcached_txt_process_delete(struct memcached_connection *con)
322322
con->cfg->stat.cmd_delete++;
323323
uint32_t len = mp_sizeof_array(1) +
324324
mp_sizeof_str (key_len);
325-
char *begin = (char *)box_txn_alloc(len);
325+
char *begin = (char *)region_alloc(&con->gc, len);
326326
if (begin == NULL) {
327327
memcached_error_ENOMEM(len, "key");
328328
return -1;

0 commit comments

Comments
 (0)