prepare v1.1.4
[awesomized/libmemcached] / src / libmemcached / allocators.cc
1 /*
2 +--------------------------------------------------------------------+
3 | libmemcached-awesome - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020-2021 Michael Wallner https://awesome.co/ |
13 +--------------------------------------------------------------------+
14 */
15
16 #include "libmemcached/common.h"
17
18 void _libmemcached_free(const memcached_st *, void *mem, void *) {
19 if (mem) {
20 std::free(mem);
21 }
22 }
23
24 void *_libmemcached_malloc(const memcached_st *, size_t size, void *) {
25 return std::malloc(size);
26 }
27
28 void *_libmemcached_realloc(const memcached_st *, void *mem, size_t size, void *) {
29 return std::realloc(mem, size);
30 }
31
32 void *_libmemcached_calloc(const memcached_st *self, size_t nelem, size_t size, void *context) {
33 if (self->allocators.malloc != _libmemcached_malloc) {
34 void *ret = _libmemcached_malloc(self, nelem * size, context);
35 if (ret) {
36 memset(ret, 0, nelem * size);
37 }
38
39 return ret;
40 }
41
42 return std::calloc(nelem, size);
43 }
44
45 struct memcached_allocator_t memcached_allocators_return_default(void) {
46 static struct memcached_allocator_t global_default_allocator = {
47 _libmemcached_calloc, _libmemcached_free, _libmemcached_malloc, _libmemcached_realloc, 0};
48 return global_default_allocator;
49 }
50
51 memcached_return_t memcached_set_memory_allocators(memcached_st *shell,
52 memcached_malloc_fn mem_malloc,
53 memcached_free_fn mem_free,
54 memcached_realloc_fn mem_realloc,
55 memcached_calloc_fn mem_calloc, void *context) {
56 Memcached *self = memcached2Memcached(shell);
57 if (self == NULL) {
58 return MEMCACHED_INVALID_ARGUMENTS;
59 }
60
61 /* All should be set, or none should be set */
62 if (mem_malloc == NULL and mem_free == NULL and mem_realloc == NULL and mem_calloc == NULL) {
63 self->allocators = memcached_allocators_return_default();
64 } else if (mem_malloc == NULL or mem_free == NULL or mem_realloc == NULL or mem_calloc == NULL) {
65 return memcached_set_error(
66 *self, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
67 memcached_literal_param("NULL parameter provided for one or more allocators"));
68 } else {
69 self->allocators.malloc = mem_malloc;
70 self->allocators.free = mem_free;
71 self->allocators.realloc = mem_realloc;
72 self->allocators.calloc = mem_calloc;
73 self->allocators.context = context;
74 }
75
76 return MEMCACHED_SUCCESS;
77 }
78
79 void *memcached_get_memory_allocators_context(const memcached_st *shell) {
80 const Memcached *self = memcached2Memcached(shell);
81 if (self) {
82 return self->allocators.context;
83 }
84
85 return NULL;
86 }
87
88 void memcached_get_memory_allocators(const memcached_st *shell, memcached_malloc_fn *mem_malloc,
89 memcached_free_fn *mem_free, memcached_realloc_fn *mem_realloc,
90 memcached_calloc_fn *mem_calloc) {
91 const Memcached *self = memcached2Memcached(shell);
92 if (self) {
93 if (mem_malloc) {
94 *mem_malloc = self->allocators.malloc;
95 }
96
97 if (mem_free) {
98 *mem_free = self->allocators.free;
99 }
100
101 if (mem_realloc) {
102 *mem_realloc = self->allocators.realloc;
103 }
104
105 if (mem_calloc) {
106 *mem_calloc = self->allocators.calloc;
107 }
108 }
109 }