Files
nginx-unit/src/nxt_buf.h
Alejandro Colomar 952bcc50bf Fixed #define style.
We had a mix of styles for declaring function-like macros:

Style A:
 #define                    \
 foo()                      \
     do {                   \
         ...                \
     } while (0)

Style B:
 #define foo()              \
     do {                   \
         ...                \
     } while (0)

We had a similar number of occurences of each style:

 $ grep -rnI '^\w*(.*\\' | wc -l
 244
 $ grep -rn 'define.*(.*)' | wc -l
 239

(Those regexes aren't perfect, but a very decent approximation.)

Real examples:

 $ find src -type f | xargs sed -n '/^nxt_double_is_zero/,/^$/p'
 nxt_double_is_zero(f)                                                         \
     (fabs(f) <= FLT_EPSILON)

 $ find src -type f | xargs sed -n '/define nxt_http_field_set/,/^$/p'
 #define nxt_http_field_set(_field, _name, _value)                             \
     do {                                                                      \
         (_field)->name_length = nxt_length(_name);                            \
         (_field)->value_length = nxt_length(_value);                          \
         (_field)->name = (u_char *) _name;                                    \
         (_field)->value = (u_char *) _value;                                  \
     } while (0)

I'd like to standardize on a single style for them, and IMO,
having the identifier in the same line as #define is a better
option for the following reasons:

- Programmers are used to `#define foo() ...` (readability).
- One less line of code.
- The program for finding them is really simple (see below).

 function grep_ngx_func()
 {
     if (($# != 1)); then
         >&2 echo "Usage: ${FUNCNAME[0]} <func>";
         return 1;
     fi;

     find src -type f \
     | grep '\.[ch]$' \
     | xargs grep -l "$1" \
     | sort \
     | xargs pcregrep -Mn "(?s)^\$[\w\s*]+?^$1\(.*?^}";

     find src -type f \
     | grep '\.[ch]$' \
     | xargs grep -l "$1" \
     | sort \
     | xargs pcregrep -Mn "(?s)define $1\(.*?^$" \
     | sed -E '1s/^[^:]+:[0-9]+:/&\n\n/';
 }

 $ grep_ngx_func
 Usage: grep_ngx_func <func>

 $ grep_ngx_func nxt_http_field_set
 src/nxt_http.h:98:

 #define nxt_http_field_set(_field, _name, _value)                             \
     do {                                                                      \
         (_field)->name_length = nxt_length(_name);                            \
         (_field)->value_length = nxt_length(_value);                          \
         (_field)->name = (u_char *) _name;                                    \
         (_field)->value = (u_char *) _value;                                  \
     } while (0)

 $ grep_ngx_func nxt_sprintf
 src/nxt_sprintf.c:56:

 u_char * nxt_cdecl
 nxt_sprintf(u_char *buf, u_char *end, const char *fmt, ...)
 {
     u_char   *p;
     va_list  args;

     va_start(args, fmt);
     p = nxt_vsprintf(buf, end, fmt, args);
     va_end(args);

     return p;
 }

................
Scripted change:
................

$ find src -type f \
  | grep '\.[ch]$' \
  | xargs sed -i '/define *\\$/{N;s/ *\\\n/ /;s/        //}'
2022-05-03 12:11:14 +02:00

270 lines
8.9 KiB
C

/*
* Copyright (C) Igor Sysoev
* Copyright (C) NGINX, Inc.
*/
#ifndef _NXT_BUF_H_INCLUDED_
#define _NXT_BUF_H_INCLUDED_
/*
* There are four types of buffers. They are different sizes, so they
* should be allocated by appropriate nxt_buf_XXX_alloc() function.
*
* 1) Memory-only buffers, their size is less than nxt_buf_t size, it
* is equal to offsetof(nxt_buf_t, file_pos), that is it is nxt_buf_t
* without file and mmap part. The buffers are frequently used, so
* the reduction allows to save 20-32 bytes depending on platform.
*
* 2) Memory/file buffers, on Unix their size is exactly nxt_buf_t size,
* since nxt_mem_map_file_ctx_t() is empty macro. On Windows the size
* equals offsetof(nxt_buf_t, mmap), that is it is nxt_buf_t without
* memory map context part. The buffers can contain both memory and
* file pointers at once, or only memory or file pointers.
*
* 3) Memory mapped buffers are similar to the memory/file buffers. Their
* size is exactly nxt_buf_t size. The buffers can contain both memory
* and file pointers at once, or only memory or file pointers. If a
* buffer is not currently mapped in memory, its mapping size is stored
* in the mem.end field and available via nxt_buf_mem_size() macro.
*
* 4) Sync buffers, their size is the same size as memory-only buffers
* size. A sync buffer can be smaller but for memory pool cache
* purpose it is better to allocate it as frequently used memory-only
* buffer. The buffers are used to synchronize pipeline processing
* completion, because data buffers in the pipeline can be completed
* and freed before their final output will even be passed to a peer.
* For this purpose a sync buffer is allocated with the stop flag which
* stops buffer chain completion processing on the sync buffer in
* nxt_sendbuf_update() and nxt_sendbuf_completion().
* Clearing the stop flag allows to continue completion processing.
*
* The last flag means the end of the output and must be set only
* in a sync buffer. The last flag is not permitted in memory and
* file buffers since it requires special handling while conversion
* one buffer to another.
*
* The nxt_buf_used_size() macro treats a sync buffer as a memory-only
* buffer which has NULL pointers, thus the buffer content size is zero.
* If allocated size of sync buffer would be lesser than memory-only
* buffer, then the special memory flag would be required because
* currently presence of memory part is indicated by non-NULL pointer
* to a content in memory.
*
* All types of buffers can have the flush flag that means the buffer
* should be sent as much as possible.
*/
typedef struct {
u_char *pos;
u_char *free;
u_char *start;
u_char *end;
} nxt_buf_mem_t;
struct nxt_buf_s {
void *data;
nxt_work_handler_t completion_handler;
void *parent;
/*
* The next link, flags, and nxt_buf_mem_t should
* reside together to improve cache locality.
*/
nxt_buf_t *next;
uint32_t retain;
uint8_t cache_hint;
uint8_t is_file:1;
uint8_t is_mmap:1;
uint8_t is_port_mmap:1;
uint8_t is_sync:1;
uint8_t is_nobuf:1;
uint8_t is_flush:1;
uint8_t is_last:1;
uint8_t is_port_mmap_sent:1;
uint8_t is_ts:1;
nxt_buf_mem_t mem;
/* The file and mmap parts are not allocated by nxt_buf_mem_alloc(). */
nxt_file_t *file;
nxt_off_t file_pos;
nxt_off_t file_end;
/* The mmap part is not allocated by nxt_buf_file_alloc(). */
nxt_mem_map_file_ctx_t (mmap)
};
#define NXT_BUF_SYNC_SIZE offsetof(nxt_buf_t, mem.free)
#define NXT_BUF_MEM_SIZE offsetof(nxt_buf_t, file)
#define NXT_BUF_FILE_SIZE sizeof(nxt_buf_t)
#define NXT_BUF_MMAP_SIZE NXT_BUF_FILE_SIZE
#define NXT_BUF_PORT_MMAP_SIZE NXT_BUF_MEM_SIZE
#define NXT_BUF_SYNC_NOBUF 1
#define NXT_BUF_SYNC_FLUSH 2
#define NXT_BUF_SYNC_LAST 4
#define nxt_buf_is_mem(b) \
((b)->mem.pos != NULL)
#define nxt_buf_is_file(b) \
((b)->is_file)
#define nxt_buf_set_file(b) \
(b)->is_file = 1
#define nxt_buf_clear_file(b) \
(b)->is_file = 0
#define nxt_buf_is_mmap(b) \
((b)->is_mmap)
#define nxt_buf_set_mmap(b) \
(b)->is_mmap = 1
#define nxt_buf_clear_mmap(b) \
(b)->is_mmap = 0
#define nxt_buf_is_port_mmap(b) \
((b)->is_port_mmap)
#define nxt_buf_set_port_mmap(b) \
(b)->is_port_mmap = 1
#define nxt_buf_clear_port_mmap(b) \
(b)->is_port_mmap = 0
#define nxt_buf_is_sync(b) \
((b)->is_sync)
#define nxt_buf_set_sync(b) \
(b)->is_sync = 1
#define nxt_buf_clear_sync(b) \
(b)->is_sync = 0
#define nxt_buf_is_nobuf(b) \
((b)->is_nobuf)
#define nxt_buf_set_nobuf(b) \
(b)->is_nobuf = 1
#define nxt_buf_clear_nobuf(b) \
(b)->is_nobuf = 0
#define nxt_buf_is_flush(b) \
((b)->is_flush)
#define nxt_buf_set_flush(b) \
(b)->is_flush = 1
#define nxt_buf_clear_flush(b) \
(b)->is_flush = 0
#define nxt_buf_is_last(b) \
((b)->is_last)
#define nxt_buf_set_last(b) \
(b)->is_last = 1
#define nxt_buf_clear_last(b) \
(b)->is_last = 0
#define nxt_buf_mem_set_size(bm, size) \
do { \
(bm)->start = 0; \
(bm)->end = (void *) size; \
} while (0)
#define nxt_buf_mem_size(bm) \
((bm)->end - (bm)->start)
#define nxt_buf_mem_used_size(bm) \
((bm)->free - (bm)->pos)
#define nxt_buf_mem_free_size(bm) \
((bm)->end - (bm)->free)
#define nxt_buf_used_size(b) \
(nxt_buf_is_file(b) ? (b)->file_end - (b)->file_pos: \
nxt_buf_mem_used_size(&(b)->mem))
NXT_EXPORT void nxt_buf_mem_init(nxt_buf_t *b, void *start, size_t size);
NXT_EXPORT nxt_buf_t *nxt_buf_mem_alloc(nxt_mp_t *mp, size_t size,
nxt_uint_t flags);
NXT_EXPORT nxt_buf_t *nxt_buf_mem_ts_alloc(nxt_task_t *task, nxt_mp_t *mp,
size_t size);
NXT_EXPORT nxt_buf_t *nxt_buf_file_alloc(nxt_mp_t *mp, size_t size,
nxt_uint_t flags);
NXT_EXPORT nxt_buf_t *nxt_buf_mmap_alloc(nxt_mp_t *mp, size_t size);
NXT_EXPORT nxt_buf_t *nxt_buf_sync_alloc(nxt_mp_t *mp, nxt_uint_t flags);
NXT_EXPORT nxt_int_t nxt_buf_ts_handle(nxt_task_t *task, void *obj, void *data);
NXT_EXPORT void nxt_buf_parent_completion(nxt_task_t *task, nxt_buf_t *parent);
NXT_EXPORT nxt_buf_t *nxt_buf_make_plain(nxt_mp_t *mp, nxt_buf_t *src,
size_t size);
nxt_inline nxt_buf_t *
nxt_buf_chk_make_plain(nxt_mp_t *mp, nxt_buf_t *src, size_t size)
{
if (nxt_slow_path(src != NULL && src->next != NULL)) {
return nxt_buf_make_plain(mp, src, size);
}
return src;
}
#define nxt_buf_free(mp, b) \
nxt_mp_free((mp), (b))
NXT_EXPORT void nxt_buf_chain_add(nxt_buf_t **head, nxt_buf_t *in);
NXT_EXPORT size_t nxt_buf_chain_length(nxt_buf_t *b);
nxt_inline nxt_buf_t *
nxt_buf_cpy(nxt_buf_t *b, const void *src, size_t length)
{
nxt_memcpy(b->mem.free, src, length);
b->mem.free += length;
return b;
}
nxt_inline nxt_buf_t *
nxt_buf_cpystr(nxt_buf_t *b, const nxt_str_t *str)
{
return nxt_buf_cpy(b, str->start, str->length);
}
nxt_inline void
nxt_buf_dummy_completion(nxt_task_t *task, void *obj, void *data)
{
}
#endif /* _NXT_BUF_H_INCLIDED_ */