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 #ifndef _NXT_BUF_FILTER_H_INCLUDED_ 80Sigor@sysoev.ru #define _NXT_BUF_FILTER_H_INCLUDED_ 90Sigor@sysoev.ru 100Sigor@sysoev.ru 110Sigor@sysoev.ru /* 120Sigor@sysoev.ru * nxt_buf_filter is a framework intended to simplify processing file 130Sigor@sysoev.ru * buffers content by a filter. The filter should set callbacks and 140Sigor@sysoev.ru * call nxt_buf_filter_add() to start processing. 150Sigor@sysoev.ru * 160Sigor@sysoev.ru * At first buf_filter calls filter_ready() and the filter ensures 170Sigor@sysoev.ru * it may allocate or reuse its internal buffer. No real allocation 180Sigor@sysoev.ru * is performed at this step. 190Sigor@sysoev.ru * 200Sigor@sysoev.ru * TODO prevent unneeded allocaiton if no input data. 210Sigor@sysoev.ru * 220Sigor@sysoev.ru * 230Sigor@sysoev.ru * TODO: The filter can flush data buffered 240Sigor@sysoev.ru * previously, if all internal buffers are full. 250Sigor@sysoev.ru * 260Sigor@sysoev.ru * Then buf_filter looks buffer chains. There are two buffer chains: 270Sigor@sysoev.ru * the input chain is a chain of original incoming memory, file, and sync 280Sigor@sysoev.ru * buffers; and the current chain is a chain of memory/file buffers read 290Sigor@sysoev.ru * from a file-only buffer. The current chain is processed first. Since 300Sigor@sysoev.ru * buffers in this chain always contains a memory part, they can be passed 310Sigor@sysoev.ru * one by one to the filter using filter_process(). If there is an output 320Sigor@sysoev.ru * buffer after the buffer processing, it is added to output chain. The 330Sigor@sysoev.ru * output buffers are not filter internal buffers. They just point to these 340Sigor@sysoev.ru * internal buffers and one internal buffer can correspond to several output 350Sigor@sysoev.ru * buffers which point to adjoining parts of the internal buffer. Further 360Sigor@sysoev.ru * processing depends on filter_process() result code: if it returns NXT_OK, 370Sigor@sysoev.ru * then the filter internal buffer is not full and buf_filter looks the next 380Sigor@sysoev.ru * current or input buffer. If result code is NXT_AGAIN, then the filter 390Sigor@sysoev.ru * internal buffer is full and buf_filter calls filter_flush() and then 400Sigor@sysoev.ru * schedules to run nxt_buf_filter_repeat(). nxt_buf_filter_repeat() will 410Sigor@sysoev.ru * run after all ready output buffer completion handlers and will call 420Sigor@sysoev.ru * buf_filter again if no one completion handler will do it already using 430Sigor@sysoev.ru * nxt_buf_filter_enqueue(). So in any case buf_filter will run again only 440Sigor@sysoev.ru * once. 450Sigor@sysoev.ru * 460Sigor@sysoev.ru * TODO: 470Sigor@sysoev.ru * in ideal just one the filter internal buffer. 480Sigor@sysoev.ru * This allows to minimize number of the filter internal buffers if they 490Sigor@sysoev.ru * flush fast. 500Sigor@sysoev.ru * 510Sigor@sysoev.ru * If the current chain is empty, the buf_filter processes the input chain. 520Sigor@sysoev.ru * Memory buffers are passed to the filter using filter_process(). If an 530Sigor@sysoev.ru * input buffer is a file buffer, then buf_filter calls filter_flush() 540Sigor@sysoev.ru * and starts a file job to read the buffer in memory. The file job reads 550Sigor@sysoev.ru * file parts into memory/file buffers and adds them to the current chain. 560Sigor@sysoev.ru * 570Sigor@sysoev.ru * Sync buffers are passed to the filter using filter_sync(). Its 580Sigor@sysoev.ru * post-processing is similar to the filter_process() post-processing, 590Sigor@sysoev.ru * except sync buffers are always added unmodified to the output chain. 600Sigor@sysoev.ru */ 610Sigor@sysoev.ru 620Sigor@sysoev.ru typedef struct { 630Sigor@sysoev.ru nxt_job_file_t job_file; 640Sigor@sysoev.ru nxt_buf_pool_t buffers; 650Sigor@sysoev.ru } nxt_buf_filter_file_t; 660Sigor@sysoev.ru 670Sigor@sysoev.ru 680Sigor@sysoev.ru typedef struct nxt_buf_filter_s nxt_buf_filter_t; 690Sigor@sysoev.ru 700Sigor@sysoev.ru typedef struct { 710Sigor@sysoev.ru nxt_int_t (*filter_ready)(nxt_buf_filter_t *f); 720Sigor@sysoev.ru nxt_int_t (*filter_process)(nxt_buf_filter_t *f); 730Sigor@sysoev.ru nxt_int_t (*filter_flush)(nxt_buf_filter_t *f); 740Sigor@sysoev.ru 750Sigor@sysoev.ru nxt_int_t (*filter_sync_nobuf)(nxt_buf_filter_t *f); 760Sigor@sysoev.ru nxt_int_t (*filter_sync_flush)(nxt_buf_filter_t *f); 770Sigor@sysoev.ru nxt_int_t (*filter_sync_last)(nxt_buf_filter_t *f); 780Sigor@sysoev.ru 790Sigor@sysoev.ru void (*filter_next)(nxt_buf_filter_t *f); 80*1Sigor@sysoev.ru nxt_work_handler_t filter_error; 810Sigor@sysoev.ru 820Sigor@sysoev.ru nxt_buf_filter_file_t *(*job_file_create)(nxt_buf_filter_t *f); 830Sigor@sysoev.ru void (*job_file_retain)(nxt_buf_filter_t *f); 840Sigor@sysoev.ru void (*job_file_release)(nxt_buf_filter_t *f); 850Sigor@sysoev.ru } nxt_buf_filter_ops_t; 860Sigor@sysoev.ru 870Sigor@sysoev.ru 880Sigor@sysoev.ru struct nxt_buf_filter_s { 890Sigor@sysoev.ru nxt_buf_t *current; 900Sigor@sysoev.ru nxt_buf_t *input; 910Sigor@sysoev.ru nxt_buf_t *output; 920Sigor@sysoev.ru nxt_buf_t *last; 930Sigor@sysoev.ru 940Sigor@sysoev.ru nxt_work_queue_t *work_queue; 950Sigor@sysoev.ru nxt_buf_filter_file_t *filter_file; 960Sigor@sysoev.ru void *data; 970Sigor@sysoev.ru nxt_mem_pool_t *mem_pool; 980Sigor@sysoev.ru 990Sigor@sysoev.ru const nxt_buf_filter_ops_t *run; 1000Sigor@sysoev.ru 1010Sigor@sysoev.ru uint8_t mmap; /* 1 bit */ 1020Sigor@sysoev.ru uint8_t done; /* 1 bit */ 1030Sigor@sysoev.ru uint8_t queued; /* 1 bit */ 1040Sigor@sysoev.ru uint8_t reading; /* 1 bit */ 1050Sigor@sysoev.ru uint8_t buffering; /* 1 bit */ 1060Sigor@sysoev.ru }; 1070Sigor@sysoev.ru 1080Sigor@sysoev.ru 109*1Sigor@sysoev.ru NXT_EXPORT void nxt_buf_filter_add(nxt_task_t *task, nxt_buf_filter_t *f, 1100Sigor@sysoev.ru nxt_buf_t *b); 111*1Sigor@sysoev.ru NXT_EXPORT void nxt_buf_filter(nxt_task_t *task, void *obj, void *data); 112*1Sigor@sysoev.ru NXT_EXPORT void nxt_buf_filter_enqueue(nxt_task_t *task, nxt_buf_filter_t *f); 1130Sigor@sysoev.ru 1140Sigor@sysoev.ru 1150Sigor@sysoev.ru #endif /* _NXT_BUF_FILTER_H_INCLUDED_ */ 116