xref: /unit/src/nxt_buf.c (revision 98)
10Sigor@sysoev.ru 
20Sigor@sysoev.ru /*
30Sigor@sysoev.ru  * Copyright (C) Igor Sysoev
40Sigor@sysoev.ru  * Copyright (C) NGINX, Inc.
50Sigor@sysoev.ru  */
60Sigor@sysoev.ru 
70Sigor@sysoev.ru #include <nxt_main.h>
80Sigor@sysoev.ru 
90Sigor@sysoev.ru 
101Sigor@sysoev.ru static void nxt_buf_completion(nxt_task_t *task, void *obj, void *data);
110Sigor@sysoev.ru 
120Sigor@sysoev.ru 
134Sigor@sysoev.ru void
144Sigor@sysoev.ru nxt_buf_mem_init(nxt_buf_t *b, void *start, size_t size)
154Sigor@sysoev.ru {
164Sigor@sysoev.ru     b->size = NXT_BUF_MEM_SIZE;
174Sigor@sysoev.ru 
184Sigor@sysoev.ru     b->mem.start = start;
194Sigor@sysoev.ru     b->mem.pos = start;
204Sigor@sysoev.ru     b->mem.free = start;
21*98Svbart@nginx.com     b->mem.end = nxt_pointer_to(start, size);
224Sigor@sysoev.ru }
234Sigor@sysoev.ru 
244Sigor@sysoev.ru 
250Sigor@sysoev.ru nxt_buf_t *
2665Sigor@sysoev.ru nxt_buf_mem_alloc(nxt_mp_t *mp, size_t size, nxt_uint_t flags)
270Sigor@sysoev.ru {
280Sigor@sysoev.ru     nxt_buf_t  *b;
290Sigor@sysoev.ru 
3065Sigor@sysoev.ru     b = nxt_mp_zalloc(mp, NXT_BUF_MEM_SIZE);
310Sigor@sysoev.ru     if (nxt_slow_path(b == NULL)) {
320Sigor@sysoev.ru         return NULL;
330Sigor@sysoev.ru     }
340Sigor@sysoev.ru 
350Sigor@sysoev.ru     b->data = mp;
360Sigor@sysoev.ru     b->completion_handler = nxt_buf_completion;
370Sigor@sysoev.ru     b->size = NXT_BUF_MEM_SIZE;
380Sigor@sysoev.ru 
390Sigor@sysoev.ru     if (size != 0) {
4065Sigor@sysoev.ru         b->mem.start = nxt_mp_alloc(mp, size);
410Sigor@sysoev.ru         if (nxt_slow_path(b->mem.start == NULL)) {
420Sigor@sysoev.ru             return NULL;
430Sigor@sysoev.ru         }
440Sigor@sysoev.ru 
450Sigor@sysoev.ru         b->mem.pos = b->mem.start;
460Sigor@sysoev.ru         b->mem.free = b->mem.start;
470Sigor@sysoev.ru         b->mem.end = b->mem.start + size;
480Sigor@sysoev.ru     }
490Sigor@sysoev.ru 
500Sigor@sysoev.ru     return b;
510Sigor@sysoev.ru }
520Sigor@sysoev.ru 
530Sigor@sysoev.ru 
540Sigor@sysoev.ru nxt_buf_t *
5565Sigor@sysoev.ru nxt_buf_file_alloc(nxt_mp_t *mp, size_t size, nxt_uint_t flags)
560Sigor@sysoev.ru {
570Sigor@sysoev.ru     nxt_buf_t  *b;
580Sigor@sysoev.ru 
5965Sigor@sysoev.ru     b = nxt_mp_zalloc(mp, NXT_BUF_FILE_SIZE);
600Sigor@sysoev.ru     if (nxt_slow_path(b == NULL)) {
610Sigor@sysoev.ru         return NULL;
620Sigor@sysoev.ru     }
630Sigor@sysoev.ru 
640Sigor@sysoev.ru     b->data = mp;
650Sigor@sysoev.ru     b->completion_handler = nxt_buf_completion;
660Sigor@sysoev.ru     b->size = NXT_BUF_FILE_SIZE;
670Sigor@sysoev.ru     nxt_buf_set_file(b);
680Sigor@sysoev.ru 
690Sigor@sysoev.ru     if (size != 0) {
7065Sigor@sysoev.ru         b->mem.start = nxt_mp_alloc(mp, size);
710Sigor@sysoev.ru         if (nxt_slow_path(b->mem.start == NULL)) {
720Sigor@sysoev.ru             return NULL;
730Sigor@sysoev.ru         }
740Sigor@sysoev.ru 
750Sigor@sysoev.ru         b->mem.pos = b->mem.start;
760Sigor@sysoev.ru         b->mem.free = b->mem.start;
770Sigor@sysoev.ru         b->mem.end = b->mem.start + size;
780Sigor@sysoev.ru     }
790Sigor@sysoev.ru 
800Sigor@sysoev.ru     return b;
810Sigor@sysoev.ru }
820Sigor@sysoev.ru 
830Sigor@sysoev.ru 
840Sigor@sysoev.ru nxt_buf_t *
8565Sigor@sysoev.ru nxt_buf_mmap_alloc(nxt_mp_t *mp, size_t size)
860Sigor@sysoev.ru {
870Sigor@sysoev.ru     nxt_buf_t  *b;
880Sigor@sysoev.ru 
8965Sigor@sysoev.ru     b = nxt_mp_zalloc(mp, NXT_BUF_MMAP_SIZE);
900Sigor@sysoev.ru 
910Sigor@sysoev.ru     if (nxt_fast_path(b != NULL)) {
920Sigor@sysoev.ru         b->data = mp;
930Sigor@sysoev.ru         b->completion_handler = nxt_buf_completion;
940Sigor@sysoev.ru         b->size = NXT_BUF_MMAP_SIZE;
950Sigor@sysoev.ru 
960Sigor@sysoev.ru         nxt_buf_set_file(b);
970Sigor@sysoev.ru         nxt_buf_set_mmap(b);
980Sigor@sysoev.ru         nxt_buf_mem_set_size(&b->mem, size);
990Sigor@sysoev.ru     }
1000Sigor@sysoev.ru 
1010Sigor@sysoev.ru     return b;
1020Sigor@sysoev.ru }
1030Sigor@sysoev.ru 
1040Sigor@sysoev.ru 
1050Sigor@sysoev.ru nxt_buf_t *
10665Sigor@sysoev.ru nxt_buf_sync_alloc(nxt_mp_t *mp, nxt_uint_t flags)
1070Sigor@sysoev.ru {
1080Sigor@sysoev.ru     nxt_buf_t  *b;
1090Sigor@sysoev.ru 
11065Sigor@sysoev.ru     b = nxt_mp_zalloc(mp, NXT_BUF_SYNC_SIZE);
1110Sigor@sysoev.ru 
1120Sigor@sysoev.ru     if (nxt_fast_path(b != NULL)) {
1130Sigor@sysoev.ru         b->data = mp;
1140Sigor@sysoev.ru         b->completion_handler = nxt_buf_completion;
1150Sigor@sysoev.ru         b->size = NXT_BUF_SYNC_SIZE;
1160Sigor@sysoev.ru 
1170Sigor@sysoev.ru         nxt_buf_set_sync(b);
1180Sigor@sysoev.ru         b->is_nobuf = ((flags & NXT_BUF_SYNC_NOBUF) != 0);
1190Sigor@sysoev.ru         b->is_flush = ((flags & NXT_BUF_SYNC_FLUSH) != 0);
1200Sigor@sysoev.ru         b->is_last = ((flags & NXT_BUF_SYNC_LAST) != 0);
1210Sigor@sysoev.ru     }
1220Sigor@sysoev.ru 
1230Sigor@sysoev.ru     return b;
1240Sigor@sysoev.ru }
1250Sigor@sysoev.ru 
1260Sigor@sysoev.ru 
1270Sigor@sysoev.ru void
1280Sigor@sysoev.ru nxt_buf_chain_add(nxt_buf_t **head, nxt_buf_t *in)
1290Sigor@sysoev.ru {
1300Sigor@sysoev.ru     nxt_buf_t  *b, **prev;
1310Sigor@sysoev.ru 
1320Sigor@sysoev.ru     prev = head;
1330Sigor@sysoev.ru 
1340Sigor@sysoev.ru     for (b = *head; b != NULL; b = b->next) {
1350Sigor@sysoev.ru         prev = &b->next;
1360Sigor@sysoev.ru     }
1370Sigor@sysoev.ru 
1380Sigor@sysoev.ru     *prev = in;
1390Sigor@sysoev.ru }
1400Sigor@sysoev.ru 
1410Sigor@sysoev.ru 
1420Sigor@sysoev.ru size_t
1430Sigor@sysoev.ru nxt_buf_chain_length(nxt_buf_t *b)
1440Sigor@sysoev.ru {
1450Sigor@sysoev.ru     size_t  length;
1460Sigor@sysoev.ru 
1470Sigor@sysoev.ru     length = 0;
1480Sigor@sysoev.ru 
1490Sigor@sysoev.ru     while (b != NULL) {
1500Sigor@sysoev.ru         length += b->mem.free - b->mem.pos;
1510Sigor@sysoev.ru         b = b->next;
1520Sigor@sysoev.ru     }
1530Sigor@sysoev.ru 
1540Sigor@sysoev.ru     return length;
1550Sigor@sysoev.ru }
1560Sigor@sysoev.ru 
1570Sigor@sysoev.ru 
1580Sigor@sysoev.ru static void
1591Sigor@sysoev.ru nxt_buf_completion(nxt_task_t *task, void *obj, void *data)
1600Sigor@sysoev.ru {
16165Sigor@sysoev.ru     nxt_mp_t   *mp;
16265Sigor@sysoev.ru     nxt_buf_t  *b, *parent;
1630Sigor@sysoev.ru 
1640Sigor@sysoev.ru     b = obj;
1650Sigor@sysoev.ru     parent = data;
1660Sigor@sysoev.ru 
1671Sigor@sysoev.ru     nxt_debug(task, "buf completion: %p %p", b, b->mem.start);
1680Sigor@sysoev.ru 
1690Sigor@sysoev.ru     mp = b->data;
1700Sigor@sysoev.ru     nxt_buf_free(mp, b);
1710Sigor@sysoev.ru 
1720Sigor@sysoev.ru     if (parent != NULL) {
1731Sigor@sysoev.ru         nxt_debug(task, "parent retain:%uD", parent->retain);
1740Sigor@sysoev.ru 
1750Sigor@sysoev.ru         parent->retain--;
1760Sigor@sysoev.ru 
1770Sigor@sysoev.ru         if (parent->retain == 0) {
1780Sigor@sysoev.ru             parent->mem.pos = parent->mem.free;
1790Sigor@sysoev.ru 
1801Sigor@sysoev.ru             parent->completion_handler(task, parent, parent->parent);
1810Sigor@sysoev.ru         }
1820Sigor@sysoev.ru     }
1830Sigor@sysoev.ru }
184