LCOV - code coverage report
Current view: top level - core/core/memory/pool - SPMemPoolApr.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 162 0.0 %
Date: 2024-05-12 00:16:13 Functions: 0 62 0.0 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2020-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #include "SPMemPoolInterface.h"
      25             : #include "SPMemPoolApi.h"
      26             : 
      27             : #if MODULE_STAPPLER_APR
      28             : #define SP_APR_EXPORT SP_EXTERN_C
      29             : #else
      30             : #define SP_APR_EXPORT static
      31             : #endif
      32             : 
      33             : using apr_status_t = int;
      34             : using apr_size_t = size_t;
      35             : using apr_abortfunc_t = int (*)(int retcode);
      36             : 
      37             : typedef struct apr_allocator_t apr_allocator_t;
      38             : typedef struct apr_pool_t apr_pool_t;
      39             : typedef struct apr_thread_mutex_t apr_thread_mutex_t;
      40             : 
      41             : typedef struct serenity_memaddr_t serenity_memaddr_t;
      42             : typedef struct serenity_allocmngr_t serenity_allocmngr_t;
      43             : 
      44             : SP_APR_EXPORT apr_status_t apr_allocator_create(apr_allocator_t **allocator) __attribute__((nonnull(1)));
      45             : SP_APR_EXPORT void apr_allocator_destroy(apr_allocator_t *allocator) __attribute__((nonnull(1)));
      46             : SP_APR_EXPORT void apr_allocator_mutex_set(apr_allocator_t *allocator, apr_thread_mutex_t *mutex) __attribute__((nonnull(1)));
      47             : SP_APR_EXPORT void apr_allocator_owner_set(apr_allocator_t *allocator, apr_pool_t *pool) __attribute__((nonnull(1)));
      48             : SP_APR_EXPORT apr_pool_t * apr_allocator_owner_get(apr_allocator_t *allocator) __attribute__((nonnull(1)));
      49             : SP_APR_EXPORT void apr_allocator_max_free_set(apr_allocator_t *allocator, apr_size_t size) __attribute__((nonnull(1)));
      50             : 
      51             : SP_APR_EXPORT void apr_pool_initialize();
      52             : SP_APR_EXPORT void apr_pool_terminate();
      53             : 
      54             : SP_APR_EXPORT apr_status_t apr_pool_create_unmanaged_ex(apr_pool_t **newpool,
      55             :                 apr_abortfunc_t abort_fn, apr_allocator_t *allocator) __attribute__((nonnull(1)));
      56             : 
      57             : SP_APR_EXPORT apr_status_t apr_pool_create_ex(apr_pool_t **newpool, apr_pool_t *parent,
      58             :                 apr_abortfunc_t abort_fn, apr_allocator_t *allocator) __attribute__((nonnull(1)));
      59             : 
      60             : SP_APR_EXPORT void apr_pool_tag(apr_pool_t *pool, const char *tag) __attribute__((nonnull(1)));
      61             : SP_APR_EXPORT void apr_pool_destroy(apr_pool_t *p) __attribute__((nonnull(1)));
      62             : SP_APR_EXPORT void apr_pool_clear(apr_pool_t *p) __attribute__((nonnull(1)));
      63             : SP_APR_EXPORT void *apr_palloc(apr_pool_t *p, apr_size_t size) __attribute__((alloc_size(2))) __attribute__((nonnull(1)));
      64             : 
      65             : SP_APR_EXPORT void apr_pool_cleanup_kill(apr_pool_t *p, const void *data,
      66             :                 apr_status_t (*cleanup)(void *)) __attribute__((nonnull(3)));
      67             : 
      68             : SP_APR_EXPORT apr_status_t apr_pool_cleanup_null(void *data);
      69             : 
      70             : SP_APR_EXPORT void apr_pool_cleanup_register( apr_pool_t *p, const void *data,
      71             :                 apr_status_t (*plain_cleanup)(void *), apr_status_t (*child_cleanup)(void *)) __attribute__((nonnull(3,4)));
      72             : 
      73             : SP_APR_EXPORT void apr_pool_pre_cleanup_register( apr_pool_t *p, const void *data,
      74             :                 apr_status_t (*plain_cleanup)(void *)) __attribute__((nonnull(3)));
      75             : 
      76             : SP_APR_EXPORT apr_status_t apr_pool_userdata_set(const void *data, const char *key,
      77             :                 apr_status_t (*cleanup)(void *), apr_pool_t *pool) __attribute__((nonnull(2,4)));
      78             : 
      79             : SP_APR_EXPORT apr_status_t apr_pool_userdata_setn(const void *data, const char *key,
      80             :                 apr_status_t (*cleanup)(void *), apr_pool_t *pool) __attribute__((nonnull(2,4)));
      81             : 
      82             : SP_APR_EXPORT apr_status_t apr_pool_userdata_get(void **data, const char *key, apr_pool_t *pool) __attribute__((nonnull(1,2,3)));
      83             : 
      84             : SP_APR_EXPORT apr_allocator_t *apr_pool_allocator_get(apr_pool_t *pool) __attribute__((nonnull(1)));
      85             : 
      86             : SP_APR_EXPORT void * apr_pmemdup(apr_pool_t *p, const void *m, apr_size_t n) __attribute__((alloc_size(3)));
      87             : SP_APR_EXPORT char * apr_pstrdup(apr_pool_t *p, const char *s);
      88             : 
      89             : SP_APR_EXPORT apr_thread_mutex_t *apr_allocator_mutex_get(apr_allocator_t *allocator) __attribute__((nonnull(1)));
      90             : 
      91             : namespace STAPPLER_VERSIONIZED stappler::mempool::apr {
      92             : 
      93             : using pool_t = apr_pool_t;
      94             : using status_t = apr_status_t;
      95             : using allocator_t = apr_allocator_t;
      96             : using cleanup_fn = status_t(*)(void *);
      97             : 
      98             : }
      99             : 
     100             : namespace STAPPLER_VERSIONIZED stappler::mempool::apr::allocator {
     101             : 
     102           0 : SPUNUSED static allocator_t *create() {
     103           0 :         allocator_t *ret = nullptr;
     104           0 :         apr_allocator_create(&ret);
     105           0 :         return ret;
     106             : }
     107             : 
     108           0 : SPUNUSED static allocator_t *create(void *mutex) {
     109           0 :         if (!mutex) {
     110           0 :                 abort();
     111             :         }
     112           0 :         allocator_t *ret = nullptr;
     113           0 :         apr_allocator_create(&ret);
     114           0 :         apr_allocator_mutex_set(ret, (apr_thread_mutex_t *)mutex);
     115           0 :         return ret;
     116             : }
     117             : 
     118           0 : SPUNUSED static void destroy(allocator_t *alloc) {
     119           0 :         apr_allocator_destroy(alloc);
     120           0 : }
     121           0 : SPUNUSED static void owner_set(allocator_t *alloc, pool_t *pool) {
     122           0 :         apr_allocator_owner_set(alloc, pool);
     123           0 : }
     124           0 : SPUNUSED static pool_t * owner_get(allocator_t *alloc) {
     125           0 :         return apr_allocator_owner_get(alloc);
     126             : }
     127           0 : SPUNUSED static void max_free_set(allocator_t *alloc, size_t size) {
     128           0 :         apr_allocator_max_free_set(alloc, size);
     129           0 : }
     130             : 
     131             : }
     132             : 
     133             : 
     134             : namespace STAPPLER_VERSIONIZED stappler::mempool::apr::pool {
     135             : 
     136             : struct wrapper_pool_t {
     137             :         apr_pool_t *parent;
     138             :         apr_pool_t *child;
     139             :         apr_pool_t *sibling;
     140             :         apr_pool_t **ref;
     141             :         void *cleanups;
     142             :         void *free_cleanups;
     143             :         apr_allocator_t *allocator;
     144             :         struct process_chain *subprocesses;
     145             :         apr_abortfunc_t abort_fn;
     146             :         void *user_data;
     147             :         const char *tag;
     148             : };
     149             : 
     150             : static custom::AllocManager *allocmngr_get(pool_t *pool);
     151             : 
     152           0 : SPUNUSED static void initialize() {
     153           0 :         apr_pool_initialize();
     154           0 : }
     155             : 
     156           0 : SPUNUSED static void terminate() {
     157           0 :         apr_pool_terminate();
     158           0 : }
     159             : 
     160           0 : SPUNUSED static pool_t *create() {
     161           0 :         pool_t *ret = nullptr;
     162           0 :         apr_pool_create_unmanaged_ex(&ret, NULL, NULL);
     163           0 :         return ret;
     164             : }
     165             : 
     166           0 : SPUNUSED static pool_t *create(apr_allocator_t *alloc) {
     167           0 :         pool_t *ret = nullptr;
     168           0 :         apr_pool_create_unmanaged_ex(&ret, NULL, alloc);
     169           0 :         return ret;
     170             : }
     171             : 
     172           0 : SPUNUSED static pool_t *create(pool_t *p) {
     173           0 :         pool_t *ret = nullptr;
     174           0 :         if (!p) {
     175           0 :                 apr_pool_create_ex(&ret, nullptr, nullptr, nullptr);
     176             :         } else {
     177           0 :                 apr_pool_create_ex(&ret, p, nullptr, nullptr);
     178             :         }
     179           0 :         return ret;
     180             : }
     181             : 
     182           0 : SPUNUSED static pool_t *createTagged(const char *tag) {
     183           0 :         auto ret = create();
     184           0 :         apr_pool_tag(ret, tag);
     185           0 :         return ret;
     186             : }
     187             : 
     188           0 : SPUNUSED static pool_t *createTagged(pool_t *p, const char *tag) {
     189           0 :         auto ret = create(p);
     190           0 :         apr_pool_tag(ret, tag);
     191           0 :         return ret;
     192             : }
     193             : 
     194           0 : SPUNUSED static void destroy(pool_t *p) {
     195           0 :         apr_pool_destroy(p);
     196           0 : }
     197             : 
     198           0 : SPUNUSED static void clear(pool_t *p) {
     199           0 :         apr_pool_clear(p);
     200           0 : }
     201             : 
     202           0 : SPUNUSED static void *alloc(pool_t *p, size_t &size) {
     203           0 :         if (auto mngr = allocmngr_get(p)) {
     204           0 :                 if (size >= custom::BlockThreshold) {
     205           0 :                         return mngr->alloc(size, [] (void *p, size_t s) { return apr_palloc((pool_t *)p, s); });
     206             :                 } else {
     207           0 :                         mngr->increment_alloc(size);
     208             :                 }
     209             :         }
     210           0 :         return apr_palloc(p, size);
     211             : }
     212             : 
     213           0 : SPUNUSED static void free(pool_t *p, void *ptr, size_t size) {
     214           0 :         if (size >= custom::BlockThreshold) {
     215           0 :                 if (auto m = allocmngr_get(p)) {
     216           0 :                         return m->free(ptr, size, [] (void *p, size_t s) { return apr_palloc((pool_t *)p, s); });
     217             :                 }
     218             :         }
     219             : }
     220             : 
     221           0 : SPUNUSED static void *palloc(pool_t *p, size_t size) {
     222           0 :         return pool::alloc(p, size);
     223             : }
     224             : 
     225           0 : SPUNUSED static void *calloc(pool_t *p, size_t count, size_t eltsize) {
     226           0 :         size_t s = count * eltsize;
     227           0 :         auto ptr = pool::alloc(p, s);
     228           0 :         memset(ptr, 0, s);
     229           0 :         return ptr;
     230             : }
     231             : 
     232           0 : SPUNUSED static void cleanup_kill(pool_t *p, void *ptr, status_t(*cb)(void *)) {
     233           0 :         apr_pool_cleanup_kill(p, ptr, cb);
     234           0 : }
     235             : 
     236             : struct __CleaupData {
     237             :         void *data;
     238             :         pool_t *pool;
     239             :         status_t(*callback)(void *);
     240             : 
     241           0 :         static status_t doCleanup(void *data) {
     242           0 :                 if (auto d = (__CleaupData *)data) {
     243           0 :                         memory::pool::push((memory::pool_t *)d->pool);
     244           0 :                         d->callback(d->data);
     245           0 :                         memory::pool::pop();
     246             :                 }
     247           0 :                 return 0;
     248             :         }
     249             : };
     250             : 
     251           0 : SPUNUSED static void cleanup_register(pool_t *p, void *ptr, status_t(*cb)(void *)) {
     252           0 :         auto data = (__CleaupData *)apr_palloc(p, sizeof(__CleaupData));
     253           0 :         data->data = ptr;
     254           0 :         data->pool = p;
     255           0 :         data->callback = cb;
     256           0 :         apr_pool_cleanup_register(p, data, &__CleaupData::doCleanup, apr_pool_cleanup_null);
     257           0 : }
     258             : 
     259           0 : SPUNUSED static void pre_cleanup_register(pool_t *p, void *ptr, status_t(*cb)(void *)) {
     260           0 :         auto data = (__CleaupData *)apr_palloc(p, sizeof(__CleaupData));
     261           0 :         data->data = ptr;
     262           0 :         data->pool = p;
     263           0 :         data->callback = cb;
     264           0 :         apr_pool_pre_cleanup_register(p, data, &__CleaupData::doCleanup);
     265           0 : }
     266             : 
     267           0 : SPUNUSED static status_t userdata_set(const void *data, const char *key, cleanup_fn cb, pool_t *pool) {
     268           0 :         return apr_pool_userdata_set(data, key, cb, pool);
     269             : }
     270             : 
     271           0 : SPUNUSED static status_t userdata_setn(const void *data, const char *key, cleanup_fn cb, pool_t *pool) {
     272           0 :         return apr_pool_userdata_setn(data, key, cb, pool);
     273             : }
     274             : 
     275           0 : SPUNUSED static status_t userdata_get(void **data, const char *key, pool_t *pool) {
     276           0 :         return apr_pool_userdata_get(data, key, pool);
     277             : }
     278             : 
     279           0 : SPUNUSED static size_t get_allocated_bytes(pool_t *p) {
     280           0 :         return allocmngr_get(p)->get_alloc();
     281             : }
     282           0 : SPUNUSED static size_t get_return_bytes(pool_t *p) {
     283           0 :         return allocmngr_get(p)->get_return();
     284             : }
     285             : 
     286           0 : SPUNUSED static allocator_t *get_allocator(pool_t *p) {
     287           0 :         return apr_pool_allocator_get(p);
     288             : }
     289             : 
     290           0 : SPUNUSED static void *pmemdup(pool_t *a, const void *m, size_t n) { return apr_pmemdup(a, m, n); }
     291           0 : SPUNUSED static char *pstrdup(pool_t *a, const char *s) { return apr_pstrdup(a, s); }
     292             : 
     293           0 : SPUNUSED static void setPoolInfo(pool_t *p, uint32_t tag, const void *ptr) {
     294           0 :         if (auto mngr = allocmngr_get(p)) {
     295           0 :                 if (tag > mngr->tag) {
     296           0 :                         mngr->tag = tag;
     297             :                 }
     298           0 :                 mngr->ptr = ptr;
     299             :         }
     300           0 : }
     301             : 
     302           0 : SPUNUSED static bool isThreadSafeAsParent(pool_t *pool) {
     303           0 :         if (auto a = apr_pool_allocator_get(pool)) {
     304           0 :                 return apr_allocator_mutex_get(a) != nullptr;
     305             :         }
     306           0 :         return false;
     307             : }
     308             : 
     309           0 : static custom::AllocManager *allocmngr_get(pool_t *pool) {
     310           0 :         return nullptr;
     311             : 
     312             :         /*wrapper_pool_t *p = (wrapper_pool_t *)pool;
     313             :         if (p->tag) {
     314             :                 auto m = (custom::AllocManager *)p->tag;
     315             :                 if (m->pool == pool) {
     316             :                         return m;
     317             :                 }
     318             :         }
     319             : 
     320             :         auto m = (custom::AllocManager *)apr_palloc(pool, sizeof(custom::AllocManager *));
     321             :         m->pool = pool;
     322             :         m->name = p->tag;
     323             : 
     324             :         cleanup_register(pool, m, [] (void *ptr) {
     325             :                 auto m = (custom::AllocManager *)ptr;
     326             : 
     327             :                 wrapper_pool_t *p = (wrapper_pool_t *)m->pool;
     328             :                 p->tag = m->name;
     329             :                 return 0;
     330             :         });
     331             : 
     332             :         p->tag = (const char *)m;
     333             :         return m;*/
     334             : }
     335             : 
     336           0 : SPUNUSED static const char *get_tag(pool_t *pool) {
     337           0 :         wrapper_pool_t *p = (wrapper_pool_t *)pool;
     338           0 :         if (p->tag) {
     339           0 :                 auto m = (custom::AllocManager *)p->tag;
     340           0 :                 if (m->pool == pool) {
     341           0 :                         return m->name;
     342             :                 }
     343           0 :                 return p->tag;
     344             :         }
     345           0 :         return NULL;
     346             : }
     347             : 
     348             : }
     349             : 
     350             : #ifndef MODULE_STAPPLER_APR
     351             : 
     352           0 : SP_APR_EXPORT apr_status_t apr_allocator_create(apr_allocator_t **allocator) { return 0; }
     353           0 : SP_APR_EXPORT void apr_allocator_destroy(apr_allocator_t *allocator) { }
     354           0 : SP_APR_EXPORT void apr_allocator_mutex_set(apr_allocator_t *allocator, apr_thread_mutex_t *mutex) { }
     355           0 : SP_APR_EXPORT void apr_allocator_owner_set(apr_allocator_t *allocator, apr_pool_t *pool) { }
     356           0 : SP_APR_EXPORT apr_pool_t * apr_allocator_owner_get(apr_allocator_t *allocator) { return nullptr; }
     357           0 : SP_APR_EXPORT void apr_allocator_max_free_set(apr_allocator_t *allocator, apr_size_t size) { }
     358             : 
     359           0 : SP_APR_EXPORT void apr_pool_initialize() { }
     360           0 : SP_APR_EXPORT void apr_pool_terminate() { }
     361             : 
     362           0 : SP_APR_EXPORT apr_status_t apr_pool_create_unmanaged_ex(apr_pool_t **newpool,
     363           0 :                 apr_abortfunc_t abort_fn, apr_allocator_t *allocator) { return 0; }
     364             : 
     365           0 : SP_APR_EXPORT apr_status_t apr_pool_create_ex(apr_pool_t **newpool, apr_pool_t *parent,
     366           0 :                 apr_abortfunc_t abort_fn, apr_allocator_t *allocator) { return 0; }
     367             : 
     368           0 : SP_APR_EXPORT void apr_pool_tag(apr_pool_t *pool, const char *tag) { }
     369           0 : SP_APR_EXPORT void apr_pool_destroy(apr_pool_t *p) { }
     370           0 : SP_APR_EXPORT void apr_pool_clear(apr_pool_t *p) { }
     371           0 : SP_APR_EXPORT void *apr_palloc(apr_pool_t *p, apr_size_t size) { return nullptr; }
     372             : 
     373           0 : SP_APR_EXPORT void apr_pool_cleanup_kill(apr_pool_t *p, const void *data,
     374           0 :                 apr_status_t (*cleanup)(void *)) { }
     375             : 
     376           0 : SP_APR_EXPORT apr_status_t apr_pool_cleanup_null(void *data) { return 0; }
     377             : 
     378           0 : SP_APR_EXPORT void apr_pool_cleanup_register( apr_pool_t *p, const void *data,
     379           0 :                 apr_status_t (*plain_cleanup)(void *), apr_status_t (*child_cleanup)(void *)) { }
     380             : 
     381           0 : SP_APR_EXPORT void apr_pool_pre_cleanup_register( apr_pool_t *p, const void *data,
     382           0 :                 apr_status_t (*plain_cleanup)(void *)) { }
     383             : 
     384           0 : SP_APR_EXPORT apr_status_t apr_pool_userdata_set(const void *data, const char *key,
     385           0 :                 apr_status_t (*cleanup)(void *), apr_pool_t *pool) { return 0; }
     386             : 
     387           0 : SP_APR_EXPORT apr_status_t apr_pool_userdata_setn(const void *data, const char *key,
     388           0 :                 apr_status_t (*cleanup)(void *), apr_pool_t *pool) { return 0; }
     389             : 
     390           0 : SP_APR_EXPORT apr_status_t apr_pool_userdata_get(void **data, const char *key, apr_pool_t *pool) { return 0; }
     391             : 
     392           0 : SP_APR_EXPORT apr_allocator_t *apr_pool_allocator_get(apr_pool_t *pool) { return nullptr; }
     393             : 
     394           0 : SP_APR_EXPORT void * apr_pmemdup(apr_pool_t *p, const void *m, apr_size_t n) { return nullptr; }
     395           0 : SP_APR_EXPORT char * apr_pstrdup(apr_pool_t *p, const char *s) { return nullptr; }
     396             : 
     397           0 : SP_APR_EXPORT apr_thread_mutex_t *apr_allocator_mutex_get(apr_allocator_t *allocator) { return nullptr; }
     398             : 
     399             : #endif

Generated by: LCOV version 1.14