Coverage Report

Created: 2025-12-08 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pjsip/pjlib/src/pj/pool_buf.c
Line
Count
Source
1
/* 
2
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
3
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
 */
19
#include <pj/pool_buf.h>
20
#include <pj/assert.h>
21
#include <pj/os.h>
22
23
static struct pj_pool_factory stack_based_factory;
24
25
struct creation_param
26
{
27
    void        *stack_buf;
28
    pj_size_t    size;
29
};
30
31
static int is_initialized;
32
static long tls = -1;
33
static void* stack_alloc(pj_pool_factory *factory, pj_size_t size);
34
35
static void pool_buf_cleanup(void)
36
0
{
37
0
    if (tls != -1) {
38
0
        pj_thread_local_free(tls);
39
0
        tls = -1;
40
0
    }
41
0
    if (is_initialized)
42
0
        is_initialized = 0;
43
0
}
44
45
static pj_status_t pool_buf_initialize(void)
46
1
{
47
1
    pj_atexit(&pool_buf_cleanup);
48
49
1
    stack_based_factory.policy.block_alloc = &stack_alloc;
50
1
    return pj_thread_local_alloc(&tls);
51
1
}
52
53
static void* stack_alloc(pj_pool_factory *factory, pj_size_t size)
54
1.17k
{
55
1.17k
    struct creation_param *param;
56
1.17k
    void *buf;
57
58
1.17k
    PJ_UNUSED_ARG(factory);
59
60
1.17k
    param = (struct creation_param*) pj_thread_local_get(tls);
61
1.17k
    if (param == NULL) {
62
        /* Don't assert(), this is normal no-memory situation */
63
0
        return NULL;
64
0
    }
65
66
1.17k
    pj_thread_local_set(tls, NULL);
67
68
1.17k
    PJ_ASSERT_RETURN(size <= param->size, NULL);
69
70
1.17k
    buf = param->stack_buf;
71
72
    /* Prevent the buffer from being reused */
73
1.17k
    param->stack_buf = NULL;
74
75
1.17k
    return buf;
76
1.17k
}
77
78
79
PJ_DEF(pj_pool_t*) pj_pool_create_on_buf(const char *name,
80
                                         void *buf,
81
                                         pj_size_t size)
82
1.17k
{
83
1.17k
#if PJ_HAS_POOL_ALT_API == 0
84
1.17k
    struct creation_param param;
85
1.17k
    pj_size_t align_diff;
86
87
1.17k
    PJ_ASSERT_RETURN(buf && size, NULL);
88
89
1.17k
    if (!is_initialized) {
90
1
        if (pool_buf_initialize() != PJ_SUCCESS)
91
0
            return NULL;
92
1
        is_initialized = 1;
93
1
    }
94
95
    /* Check and align buffer */
96
1.17k
    align_diff = (pj_size_t)buf;
97
1.17k
    if (align_diff & (PJ_POOL_ALIGNMENT-1)) {
98
0
        align_diff &= (PJ_POOL_ALIGNMENT-1);
99
0
        buf = (void*) (((char*)buf) + align_diff);
100
0
        size -= align_diff;
101
0
    }
102
103
1.17k
    param.stack_buf = buf;
104
1.17k
    param.size = size;
105
1.17k
    pj_thread_local_set(tls, &param);
106
107
1.17k
    return pj_pool_create_int(&stack_based_factory, name, size, 0, 
108
1.17k
                              PJ_POOL_ALIGNMENT,
109
1.17k
                              pj_pool_factory_default_policy.callback);
110
#else
111
    PJ_UNUSED_ARG(buf);
112
    PJ_UNUSED_ARG(pool_buf_initialize);
113
    return pj_pool_create(NULL, name, size, size, NULL);
114
#endif
115
1.17k
}
116