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; 2126Sigor@sysoev.ru b->mem.end = (u_char *) start + size; 224Sigor@sysoev.ru } 234Sigor@sysoev.ru 244Sigor@sysoev.ru 250Sigor@sysoev.ru nxt_buf_t * 26*65Sigor@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 30*65Sigor@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) { 40*65Sigor@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 * 55*65Sigor@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 59*65Sigor@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) { 70*65Sigor@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 * 85*65Sigor@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 89*65Sigor@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 * 106*65Sigor@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 110*65Sigor@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 { 161*65Sigor@sysoev.ru nxt_mp_t *mp; 162*65Sigor@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