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 10*1Sigor@sysoev.ru static void nxt_buf_completion(nxt_task_t *task, void *obj, void *data); 110Sigor@sysoev.ru 120Sigor@sysoev.ru 130Sigor@sysoev.ru nxt_buf_t * 140Sigor@sysoev.ru nxt_buf_mem_alloc(nxt_mem_pool_t *mp, size_t size, nxt_uint_t flags) 150Sigor@sysoev.ru { 160Sigor@sysoev.ru nxt_buf_t *b; 170Sigor@sysoev.ru 180Sigor@sysoev.ru b = nxt_mem_cache_zalloc0(mp, NXT_BUF_MEM_SIZE); 190Sigor@sysoev.ru if (nxt_slow_path(b == NULL)) { 200Sigor@sysoev.ru return NULL; 210Sigor@sysoev.ru } 220Sigor@sysoev.ru 230Sigor@sysoev.ru b->data = mp; 240Sigor@sysoev.ru b->completion_handler = nxt_buf_completion; 250Sigor@sysoev.ru b->size = NXT_BUF_MEM_SIZE; 260Sigor@sysoev.ru 270Sigor@sysoev.ru if (size != 0) { 280Sigor@sysoev.ru b->mem.start = nxt_mem_buf(mp, &size, flags); 290Sigor@sysoev.ru if (nxt_slow_path(b->mem.start == NULL)) { 300Sigor@sysoev.ru return NULL; 310Sigor@sysoev.ru } 320Sigor@sysoev.ru 330Sigor@sysoev.ru b->mem.pos = b->mem.start; 340Sigor@sysoev.ru b->mem.free = b->mem.start; 350Sigor@sysoev.ru b->mem.end = b->mem.start + size; 360Sigor@sysoev.ru } 370Sigor@sysoev.ru 380Sigor@sysoev.ru return b; 390Sigor@sysoev.ru } 400Sigor@sysoev.ru 410Sigor@sysoev.ru 420Sigor@sysoev.ru nxt_buf_t * 430Sigor@sysoev.ru nxt_buf_file_alloc(nxt_mem_pool_t *mp, size_t size, nxt_uint_t flags) 440Sigor@sysoev.ru { 450Sigor@sysoev.ru nxt_buf_t *b; 460Sigor@sysoev.ru 470Sigor@sysoev.ru b = nxt_mem_cache_zalloc0(mp, NXT_BUF_FILE_SIZE); 480Sigor@sysoev.ru if (nxt_slow_path(b == NULL)) { 490Sigor@sysoev.ru return NULL; 500Sigor@sysoev.ru } 510Sigor@sysoev.ru 520Sigor@sysoev.ru b->data = mp; 530Sigor@sysoev.ru b->completion_handler = nxt_buf_completion; 540Sigor@sysoev.ru b->size = NXT_BUF_FILE_SIZE; 550Sigor@sysoev.ru nxt_buf_set_file(b); 560Sigor@sysoev.ru 570Sigor@sysoev.ru if (size != 0) { 580Sigor@sysoev.ru b->mem.start = nxt_mem_buf(mp, &size, flags); 590Sigor@sysoev.ru if (nxt_slow_path(b->mem.start == NULL)) { 600Sigor@sysoev.ru return NULL; 610Sigor@sysoev.ru } 620Sigor@sysoev.ru 630Sigor@sysoev.ru b->mem.pos = b->mem.start; 640Sigor@sysoev.ru b->mem.free = b->mem.start; 650Sigor@sysoev.ru b->mem.end = b->mem.start + size; 660Sigor@sysoev.ru } 670Sigor@sysoev.ru 680Sigor@sysoev.ru return b; 690Sigor@sysoev.ru } 700Sigor@sysoev.ru 710Sigor@sysoev.ru 720Sigor@sysoev.ru nxt_buf_t * 730Sigor@sysoev.ru nxt_buf_mmap_alloc(nxt_mem_pool_t *mp, size_t size) 740Sigor@sysoev.ru { 750Sigor@sysoev.ru nxt_buf_t *b; 760Sigor@sysoev.ru 770Sigor@sysoev.ru b = nxt_mem_cache_zalloc0(mp, NXT_BUF_MMAP_SIZE); 780Sigor@sysoev.ru 790Sigor@sysoev.ru if (nxt_fast_path(b != NULL)) { 800Sigor@sysoev.ru b->data = mp; 810Sigor@sysoev.ru b->completion_handler = nxt_buf_completion; 820Sigor@sysoev.ru b->size = NXT_BUF_MMAP_SIZE; 830Sigor@sysoev.ru 840Sigor@sysoev.ru nxt_buf_set_file(b); 850Sigor@sysoev.ru nxt_buf_set_mmap(b); 860Sigor@sysoev.ru nxt_buf_mem_set_size(&b->mem, size); 870Sigor@sysoev.ru } 880Sigor@sysoev.ru 890Sigor@sysoev.ru return b; 900Sigor@sysoev.ru } 910Sigor@sysoev.ru 920Sigor@sysoev.ru 930Sigor@sysoev.ru nxt_buf_t * 940Sigor@sysoev.ru nxt_buf_sync_alloc(nxt_mem_pool_t *mp, nxt_uint_t flags) 950Sigor@sysoev.ru { 960Sigor@sysoev.ru nxt_buf_t *b; 970Sigor@sysoev.ru 980Sigor@sysoev.ru b = nxt_mem_cache_zalloc0(mp, NXT_BUF_SYNC_SIZE); 990Sigor@sysoev.ru 1000Sigor@sysoev.ru if (nxt_fast_path(b != NULL)) { 1010Sigor@sysoev.ru b->data = mp; 1020Sigor@sysoev.ru b->completion_handler = nxt_buf_completion; 1030Sigor@sysoev.ru b->size = NXT_BUF_SYNC_SIZE; 1040Sigor@sysoev.ru 1050Sigor@sysoev.ru nxt_buf_set_sync(b); 1060Sigor@sysoev.ru b->is_nobuf = ((flags & NXT_BUF_SYNC_NOBUF) != 0); 1070Sigor@sysoev.ru b->is_flush = ((flags & NXT_BUF_SYNC_FLUSH) != 0); 1080Sigor@sysoev.ru b->is_last = ((flags & NXT_BUF_SYNC_LAST) != 0); 1090Sigor@sysoev.ru } 1100Sigor@sysoev.ru 1110Sigor@sysoev.ru return b; 1120Sigor@sysoev.ru } 1130Sigor@sysoev.ru 1140Sigor@sysoev.ru 1150Sigor@sysoev.ru void 1160Sigor@sysoev.ru nxt_buf_chain_add(nxt_buf_t **head, nxt_buf_t *in) 1170Sigor@sysoev.ru { 1180Sigor@sysoev.ru nxt_buf_t *b, **prev; 1190Sigor@sysoev.ru 1200Sigor@sysoev.ru prev = head; 1210Sigor@sysoev.ru 1220Sigor@sysoev.ru for (b = *head; b != NULL; b = b->next) { 1230Sigor@sysoev.ru prev = &b->next; 1240Sigor@sysoev.ru } 1250Sigor@sysoev.ru 1260Sigor@sysoev.ru *prev = in; 1270Sigor@sysoev.ru } 1280Sigor@sysoev.ru 1290Sigor@sysoev.ru 1300Sigor@sysoev.ru size_t 1310Sigor@sysoev.ru nxt_buf_chain_length(nxt_buf_t *b) 1320Sigor@sysoev.ru { 1330Sigor@sysoev.ru size_t length; 1340Sigor@sysoev.ru 1350Sigor@sysoev.ru length = 0; 1360Sigor@sysoev.ru 1370Sigor@sysoev.ru while (b != NULL) { 1380Sigor@sysoev.ru length += b->mem.free - b->mem.pos; 1390Sigor@sysoev.ru b = b->next; 1400Sigor@sysoev.ru } 1410Sigor@sysoev.ru 1420Sigor@sysoev.ru return length; 1430Sigor@sysoev.ru } 1440Sigor@sysoev.ru 1450Sigor@sysoev.ru 1460Sigor@sysoev.ru static void 147*1Sigor@sysoev.ru nxt_buf_completion(nxt_task_t *task, void *obj, void *data) 1480Sigor@sysoev.ru { 1490Sigor@sysoev.ru nxt_buf_t *b, *parent; 1500Sigor@sysoev.ru nxt_mem_pool_t *mp; 1510Sigor@sysoev.ru 1520Sigor@sysoev.ru b = obj; 1530Sigor@sysoev.ru parent = data; 1540Sigor@sysoev.ru 155*1Sigor@sysoev.ru nxt_debug(task, "buf completion: %p %p", b, b->mem.start); 1560Sigor@sysoev.ru 1570Sigor@sysoev.ru mp = b->data; 1580Sigor@sysoev.ru nxt_buf_free(mp, b); 1590Sigor@sysoev.ru 1600Sigor@sysoev.ru if (parent != NULL) { 161*1Sigor@sysoev.ru nxt_debug(task, "parent retain:%uD", parent->retain); 1620Sigor@sysoev.ru 1630Sigor@sysoev.ru parent->retain--; 1640Sigor@sysoev.ru 1650Sigor@sysoev.ru if (parent->retain == 0) { 1660Sigor@sysoev.ru parent->mem.pos = parent->mem.free; 1670Sigor@sysoev.ru 168*1Sigor@sysoev.ru parent->completion_handler(task, parent, parent->parent); 1690Sigor@sysoev.ru } 1700Sigor@sysoev.ru } 1710Sigor@sysoev.ru } 172