oceanbase

Форк
0
/
easy_buf.c 
312 строк · 7.8 Кб
1
#include <stdarg.h>
2
#include <unistd.h>
3
#include <sys/time.h>
4
#include "util/easy_buf.h"
5
#include "util/easy_string.h"
6
#include "io/easy_log.h"
7
#include "easy_define.h"
8
#include "io/easy_connection.h"
9

10

11
/**
12
 * 创建一个新的easy_buf_t
13
 */
14
easy_buf_t *easy_buf_create(easy_pool_t *pool, uint32_t size)
15
{
16
    easy_buf_t              *b;
17

18
    if ((b = (easy_buf_t *)easy_pool_calloc(pool, sizeof(easy_buf_t))) == NULL)
19
        return NULL;
20

21
    // 一个page大小
22
    if (size == 0)
23
        size = pool->end - pool->last;
24

25
    if ((b->data = (char *)easy_pool_alloc(pool, size)) == NULL)
26
        return NULL;
27

28
    b->pos = b->data;
29
    b->last = b->pos;
30
    b->end = b->last + size;
31
    b->cleanup = NULL;
32
    b->args = pool;
33
    easy_list_init(&b->node);
34

35
    return b;
36
}
37

38
static uint64_t priv_pool_created = 0;
39
static uint64_t priv_pool_destroyed = 0;
40
static void easy_buf_free_private_pool(easy_buf_t * b, easy_pool_t * pool)
41
{
42
    easy_debug_log("easy free residual buffer: %p remain=%d\n", b, easy_buf_len(b));
43
    easy_pool_destroy(pool);
44
    priv_pool_destroyed++;
45
}
46

47
easy_buf_t* easy_buf_clone_with_private_pool(easy_buf_t* b)
48
{
49
    easy_buf_t* nb = NULL;
50
    int64_t data_len = easy_buf_len(b);
51
    easy_pool_t* pool = easy_pool_create(data_len + sizeof(*b) + sizeof(*pool));
52
    if (NULL != pool) {
53
        nb = easy_buf_create(pool, data_len);
54
    }
55
    if (NULL != nb) {
56
        memcpy(nb->last, b->pos, data_len);
57
        nb->last += data_len;
58
        nb->cleanup = (easy_buf_cleanup_pt*)easy_buf_free_private_pool;
59
        {
60
            if ((priv_pool_created & 0x1ff) == 0) {
61
                easy_info_log("easy created (%ld) private pools, and destoyed (%ld) pools.\n",
62
                              priv_pool_created, priv_pool_destroyed);
63
            }
64
            priv_pool_created++;
65
        }
66
    } else {
67
        if (NULL != pool) {
68
            easy_pool_destroy(pool);
69
        }
70
    }
71
    return nb;
72
}
73
/**
74
 * 把data包成easy_buf_t
75
 */
76
easy_buf_t *easy_buf_pack(easy_pool_t *pool, const void *data, uint32_t size)
77
{
78
    easy_buf_t              *b;
79

80
    if ((b = (easy_buf_t *)easy_pool_calloc(pool, sizeof(easy_buf_t))) == NULL)
81
        return NULL;
82

83
    easy_buf_set_data(pool, b, data, size);
84

85
    return b;
86
}
87

88
/**
89
 * 设置数据到b里
90
 */
91
void easy_buf_set_data(easy_pool_t *pool, easy_buf_t *b, const void *data, uint32_t size)
92
{
93
    b->data = (char *)data;
94
    b->pos = b->data;
95
    b->last = b->pos + size;
96
    b->end = b->last;
97
    b->cleanup = NULL;
98
    b->args = pool;
99
    b->flags = 0;
100
    easy_list_init(&b->node);
101
}
102

103
/**
104
 * 创建一个easy_file_buf_t, 用于sendfile等
105
 */
106
easy_file_buf_t *easy_file_buf_create(easy_pool_t *pool)
107
{
108
    easy_file_buf_t         *b;
109

110
    b = (easy_file_buf_t *)easy_pool_calloc(pool, sizeof(easy_file_buf_t));
111
    b->flags = EASY_BUF_FILE;
112
    b->cleanup = NULL;
113
    b->args = pool;
114
    easy_list_init(&b->node);
115

116
    return b;
117
}
118

119
void easy_file_buf_set_close(easy_file_buf_t *b)
120
{
121
    if ((b->flags & EASY_BUF_FILE))
122
        b->flags = EASY_BUF_CLOSE_FILE;
123
}
124

125
void easy_buf_set_cleanup(easy_buf_t *b, easy_buf_cleanup_pt *cleanup, void *args)
126
{
127
    b->cleanup = cleanup;
128
    b->args = args;
129
}
130

131
void easy_buf_destroy(easy_buf_t *b)
132
{
133
    easy_session_t *s;
134
    easy_buf_cleanup_pt *cleanup;
135
    ev_tstamp easy_hold_time;
136

137
    /*
138
     * Session must be got before cleanup is called, because cleanup may free
139
     * the memory pool and then the memory space of b becomes illegal.
140
     */
141
    s = b->session;
142
    easy_list_del(&b->node);
143
    if ((b->flags & EASY_BUF_CLOSE_FILE) == EASY_BUF_CLOSE_FILE) {
144
        close(((easy_file_buf_t *)b)->fd);
145
    }
146

147
    /*
148
     * cleanup is set to easy_request_cleanup in RX side, or set to
149
     * easy_buf_free_private_pool when session is allocated in private pool.
150
     */
151
    if ((cleanup = b->cleanup)) {
152
        b->cleanup = NULL;
153
        (*cleanup)(b, b->args);
154
    }
155

156
    /*
157
     * session is set in TX side.
158
     */
159
    if (s != NULL) {
160
        if ((s->type == EASY_TYPE_SESSION) ||
161
                (s->type == EASY_TYPE_KEEPALIVE_SESSION) ||
162
                (s->type == EASY_TYPE_RL_SESSION)) {
163
            s->buf_count--;
164
            s->sent_buf_count++;
165
            if (unlikely(s->enable_trace)) {
166
                easy_debug_log("destroy buffer, session=%p, count=%ld, on_write_success=%p",
167
                               s, s->buf_count, s->on_write_success);
168
            }
169
            if (s->buf_count == 0) {
170
                easy_hold_time = ev_time() - s->now;
171
                if ((easy_hold_time > 1.0) && (EASY_REACH_TIME_INTERVAL(1 * 1000 * 1000))) {
172
                    easy_info_log("Session hold by easy for too much time, session(%p), time(%fs), "
173
                            "packet_id(%" PRId64 "), conn(%p).", s, easy_hold_time, s->packet_id, s->c);
174
                }
175

176
                s->nextb = NULL;
177
                if (s->on_write_success) {
178
                    s->on_write_success(s);
179
                    s = NULL;
180
                }
181
            }
182
        }
183

184
        /*
185
         * Free packet buffer in TX side.
186
         */
187
        if ((s != NULL) && (s->tx_buf_separated > 0) && (s->tx_buf != NULL)) {
188
            easy_pool_realloc(s->tx_buf, 0);
189
            s->tx_buf = NULL;
190
        }
191
    }
192
}
193

194
/**
195
 * 空间不够,分配出一块来,保留之前的空间
196
 */
197
int easy_buf_check_read_space(easy_pool_t *pool, easy_buf_t *b, uint32_t size)
198
{
199
    int                     dsize;
200
    char                    *ptr;
201

202
    if ((b->end - b->last) >= (int)size)
203
        return EASY_OK;
204

205
    // 需要大小
206
    dsize = (b->last - b->pos);
207
    size = easy_max(dsize * 3 / 2, size + dsize);
208
    size = easy_align(size, EASY_POOL_PAGE_SIZE);
209

210
    // alloc
211
    if ((ptr = (char *)easy_pool_alloc(pool, size)) == NULL)
212
        return EASY_ERROR;
213

214
    // copy old buf to new buf
215
    if (dsize > 0)
216
        memcpy(ptr, b->pos, dsize);
217

218
    b->data = ptr;
219
    b->pos = ptr;
220
    b->last = b->pos + dsize;
221
    b->end = b->pos + size;
222

223
    return EASY_OK;
224
}
225

226
/**
227
 * 空间不够,分配出一块来,保留之前的空间
228
 */
229
easy_buf_t *easy_buf_check_write_space(easy_pool_t *pool, easy_list_t *bc, uint32_t size)
230
{
231
    easy_buf_t              *b = easy_list_get_last(bc, easy_buf_t, node);
232

233
    if (b != NULL && (b->end - b->last) >= (int)size)
234
        return b;
235

236
    // 重新生成一个buf,放入buf_chain_t中
237
    size = easy_align(size, EASY_POOL_PAGE_SIZE);
238

239
    if ((b = easy_buf_create(pool, size)) == NULL)
240
        return NULL;
241

242
    easy_list_add_tail(&b->node, bc);
243

244
    return b;
245
}
246

247
/**
248
 * 清除掉
249
 */
250
void easy_buf_chain_clear(easy_list_t *l)
251
{
252
    easy_buf_t              *b, *b1;
253

254
    easy_list_for_each_entry_safe(b, b1, l, node) {
255
        easy_debug_log("easy_buf_chain_clear, b(%), b1(p).\n", b, b1);
256
        easy_buf_destroy(b);
257
    }
258
    easy_list_init(l);
259
}
260

261
/**
262
 * 加到后面
263
 */
264
void easy_buf_chain_offer(easy_list_t *l, easy_buf_t *b)
265
{
266
    if (!l->next) easy_list_init(l);
267

268
    easy_list_add_tail(&b->node, l);
269
}
270

271
/**
272
 * 把s复制到d上
273
 */
274
int easy_buf_string_copy(easy_pool_t *pool, easy_buf_string_t *d, const easy_buf_string_t *s)
275
{
276
    if (s->len > 0) {
277
        d->data = (char *)easy_pool_alloc(pool, s->len + 1);
278
        memcpy(d->data, s->data, s->len);
279
        d->data[s->len] = '\0';
280
        d->len = s->len;
281
    }
282

283
    return s->len;
284
}
285

286
int easy_buf_string_printf(easy_pool_t *pool, easy_buf_string_t *d, const char *fmt, ...)
287
{
288
    int                     len;
289
    char                    buffer[2048];
290

291
    va_list                 args;
292
    va_start(args, fmt);
293
    len = easy_vsnprintf(buffer, 2048, fmt, args);
294
    va_end(args);
295
    d->data = (char *)easy_pool_alloc(pool, len + 1);
296
    memcpy(d->data, buffer, len);
297
    d->data[len] = '\0';
298
    d->len = len;
299
    return len;
300
}
301

302
int easy_buf_list_len(easy_list_t *l)
303
{
304
    easy_buf_t              *b;
305
    int                     len = 0;
306

307
    easy_list_for_each_entry(b, l, node) {
308
        len += easy_buf_len(b);
309
    }
310

311
    return len;
312
}
313

314

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.