nxt_unit.h (743:e0f0cd7d244a) nxt_unit.h (828:b9f7635e6be2)
1
2/*
3 * Copyright (C) NGINX, Inc.
4 */
5
6#ifndef _NXT_UNIT_H_INCLUDED_
7#define _NXT_UNIT_H_INCLUDED_
8
9
10#include <inttypes.h>
11#include <sys/types.h>
12#include <string.h>
13
14#include "nxt_unit_typedefs.h"
15
16enum {
17 NXT_UNIT_OK = 0,
18 NXT_UNIT_ERROR = 1,
19};
20
21enum {
22 NXT_UNIT_LOG_ALERT = 0,
23 NXT_UNIT_LOG_ERR = 1,
24 NXT_UNIT_LOG_WARN = 2,
25 NXT_UNIT_LOG_NOTICE = 3,
26 NXT_UNIT_LOG_INFO = 4,
27 NXT_UNIT_LOG_DEBUG = 5,
28};
29
30#define NXT_UNIT_INIT_ENV "NXT_UNIT_INIT"
31
32/*
33 * Mostly opaque structure with library state.
34 *
35 * Only user defined 'data' pointer exposed here. The rest is unit
36 * implementation specific and hidden.
37 */
38struct nxt_unit_s {
39 void *data; /* User defined data. */
40};
41
42/*
43 * Thread context.
44 *
45 * First (main) context is provided 'for free'. To receive and process
46 * requests in other thread, one need to allocate context and use it
47 * further in this thread.
48 */
49struct nxt_unit_ctx_s {
50 void *data; /* User context-specific data. */
51 nxt_unit_t *unit;
52};
53
54/*
55 * Unit port identification structure.
56 *
57 * Each port can be uniquely identified by listen process id (pid) and port id.
58 * This identification is required to refer the port from different process.
59 */
60struct nxt_unit_port_id_s {
61 pid_t pid;
62 uint32_t hash;
63 uint16_t id;
64};
65
66/*
67 * unit provides port storage which is able to store and find the following
68 * data structures.
69 */
70struct nxt_unit_port_s {
71 nxt_unit_port_id_t id;
72
73 int in_fd;
74 int out_fd;
75
76 void *data;
77};
78
79
80struct nxt_unit_buf_s {
81 char *start;
82 char *free;
83 char *end;
84};
85
86
87struct nxt_unit_request_info_s {
88 nxt_unit_t *unit;
89 nxt_unit_ctx_t *ctx;
90
91 nxt_unit_port_id_t request_port;
92 nxt_unit_port_id_t response_port;
93
94 nxt_unit_request_t *request;
95 nxt_unit_buf_t *request_buf;
96
97 nxt_unit_response_t *response;
98 nxt_unit_buf_t *response_buf;
99 uint32_t response_max_fields;
100
101 nxt_unit_buf_t *content_buf;
102 uint64_t content_length;
103
104 void *data;
105};
106
107/*
108 * Set of application-specific callbacks. Application may leave all optional
109 * callbacks as NULL.
110 */
111struct nxt_unit_callbacks_s {
112 /*
113 * Process request data. Unlike all other callback, this callback
114 * need to be defined by application.
115 */
116 void (*request_handler)(nxt_unit_request_info_t *req);
117
118 /* Add new Unit port to communicate with process pid. Optional. */
119 int (*add_port)(nxt_unit_ctx_t *, nxt_unit_port_t *port);
120
121 /* Remove previously added port. Optional. */
122 void (*remove_port)(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id);
123
124 /* Remove all data associated with process pid including ports. Optional. */
125 void (*remove_pid)(nxt_unit_ctx_t *, pid_t pid);
126
127 /* Gracefully quit the application. Optional. */
128 void (*quit)(nxt_unit_ctx_t *);
129
130 /* Send data and control to process pid using port id. Optional. */
131 ssize_t (*port_send)(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id,
132 const void *buf, size_t buf_size,
133 const void *oob, size_t oob_size);
134
135 /* Receive data on port id. Optional. */
136 ssize_t (*port_recv)(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id,
137 void *buf, size_t buf_size, void *oob, size_t oob_size);
138
139};
140
141
142struct nxt_unit_init_s {
143 void *data; /* Opaque pointer to user-defined data. */
144 void *ctx_data; /* Opaque pointer to user-defined data. */
145 int max_pending_requests;
146
147 uint32_t request_data_size;
148
149 nxt_unit_callbacks_t callbacks;
150
151 nxt_unit_port_t ready_port;
152 uint32_t ready_stream;
153 nxt_unit_port_t read_port;
154 int log_fd;
155};
156
157
158typedef ssize_t (*nxt_unit_read_func_t)(nxt_unit_read_info_t *read_info,
159 void *dst, size_t size);
160
161
162struct nxt_unit_read_info_s {
163 nxt_unit_read_func_t read;
164 int eof;
165 uint32_t buf_size;
166 void *data;
167};
168
169
170/*
171 * Initialize Unit application library with necessary callbacks and
172 * ready/reply port parameters, send 'READY' response to master.
173 */
174nxt_unit_ctx_t *nxt_unit_init(nxt_unit_init_t *);
175
176/*
177 * Process received message, invoke configured callbacks.
178 *
179 * If application implements it's own event loop, each datagram received
180 * from port socket should be initially processed by unit. This function
181 * may invoke other application-defined callback for message processing.
182 */
183int nxt_unit_process_msg(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id,
184 void *buf, size_t buf_size, void *oob, size_t oob_size);
185
186/*
187 * Main function useful in case when application does not have it's own
188 * event loop. nxt_unit_run() starts infinite message wait and process loop.
189 *
190 * for (;;) {
191 * app_lib->port_recv(...);
192 * nxt_unit_process_msg(...);
193 * }
194 *
195 * The normally function returns when QUIT message received from Unit.
196 */
197int nxt_unit_run(nxt_unit_ctx_t *);
198
1
2/*
3 * Copyright (C) NGINX, Inc.
4 */
5
6#ifndef _NXT_UNIT_H_INCLUDED_
7#define _NXT_UNIT_H_INCLUDED_
8
9
10#include <inttypes.h>
11#include <sys/types.h>
12#include <string.h>
13
14#include "nxt_unit_typedefs.h"
15
16enum {
17 NXT_UNIT_OK = 0,
18 NXT_UNIT_ERROR = 1,
19};
20
21enum {
22 NXT_UNIT_LOG_ALERT = 0,
23 NXT_UNIT_LOG_ERR = 1,
24 NXT_UNIT_LOG_WARN = 2,
25 NXT_UNIT_LOG_NOTICE = 3,
26 NXT_UNIT_LOG_INFO = 4,
27 NXT_UNIT_LOG_DEBUG = 5,
28};
29
30#define NXT_UNIT_INIT_ENV "NXT_UNIT_INIT"
31
32/*
33 * Mostly opaque structure with library state.
34 *
35 * Only user defined 'data' pointer exposed here. The rest is unit
36 * implementation specific and hidden.
37 */
38struct nxt_unit_s {
39 void *data; /* User defined data. */
40};
41
42/*
43 * Thread context.
44 *
45 * First (main) context is provided 'for free'. To receive and process
46 * requests in other thread, one need to allocate context and use it
47 * further in this thread.
48 */
49struct nxt_unit_ctx_s {
50 void *data; /* User context-specific data. */
51 nxt_unit_t *unit;
52};
53
54/*
55 * Unit port identification structure.
56 *
57 * Each port can be uniquely identified by listen process id (pid) and port id.
58 * This identification is required to refer the port from different process.
59 */
60struct nxt_unit_port_id_s {
61 pid_t pid;
62 uint32_t hash;
63 uint16_t id;
64};
65
66/*
67 * unit provides port storage which is able to store and find the following
68 * data structures.
69 */
70struct nxt_unit_port_s {
71 nxt_unit_port_id_t id;
72
73 int in_fd;
74 int out_fd;
75
76 void *data;
77};
78
79
80struct nxt_unit_buf_s {
81 char *start;
82 char *free;
83 char *end;
84};
85
86
87struct nxt_unit_request_info_s {
88 nxt_unit_t *unit;
89 nxt_unit_ctx_t *ctx;
90
91 nxt_unit_port_id_t request_port;
92 nxt_unit_port_id_t response_port;
93
94 nxt_unit_request_t *request;
95 nxt_unit_buf_t *request_buf;
96
97 nxt_unit_response_t *response;
98 nxt_unit_buf_t *response_buf;
99 uint32_t response_max_fields;
100
101 nxt_unit_buf_t *content_buf;
102 uint64_t content_length;
103
104 void *data;
105};
106
107/*
108 * Set of application-specific callbacks. Application may leave all optional
109 * callbacks as NULL.
110 */
111struct nxt_unit_callbacks_s {
112 /*
113 * Process request data. Unlike all other callback, this callback
114 * need to be defined by application.
115 */
116 void (*request_handler)(nxt_unit_request_info_t *req);
117
118 /* Add new Unit port to communicate with process pid. Optional. */
119 int (*add_port)(nxt_unit_ctx_t *, nxt_unit_port_t *port);
120
121 /* Remove previously added port. Optional. */
122 void (*remove_port)(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id);
123
124 /* Remove all data associated with process pid including ports. Optional. */
125 void (*remove_pid)(nxt_unit_ctx_t *, pid_t pid);
126
127 /* Gracefully quit the application. Optional. */
128 void (*quit)(nxt_unit_ctx_t *);
129
130 /* Send data and control to process pid using port id. Optional. */
131 ssize_t (*port_send)(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id,
132 const void *buf, size_t buf_size,
133 const void *oob, size_t oob_size);
134
135 /* Receive data on port id. Optional. */
136 ssize_t (*port_recv)(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id,
137 void *buf, size_t buf_size, void *oob, size_t oob_size);
138
139};
140
141
142struct nxt_unit_init_s {
143 void *data; /* Opaque pointer to user-defined data. */
144 void *ctx_data; /* Opaque pointer to user-defined data. */
145 int max_pending_requests;
146
147 uint32_t request_data_size;
148
149 nxt_unit_callbacks_t callbacks;
150
151 nxt_unit_port_t ready_port;
152 uint32_t ready_stream;
153 nxt_unit_port_t read_port;
154 int log_fd;
155};
156
157
158typedef ssize_t (*nxt_unit_read_func_t)(nxt_unit_read_info_t *read_info,
159 void *dst, size_t size);
160
161
162struct nxt_unit_read_info_s {
163 nxt_unit_read_func_t read;
164 int eof;
165 uint32_t buf_size;
166 void *data;
167};
168
169
170/*
171 * Initialize Unit application library with necessary callbacks and
172 * ready/reply port parameters, send 'READY' response to master.
173 */
174nxt_unit_ctx_t *nxt_unit_init(nxt_unit_init_t *);
175
176/*
177 * Process received message, invoke configured callbacks.
178 *
179 * If application implements it's own event loop, each datagram received
180 * from port socket should be initially processed by unit. This function
181 * may invoke other application-defined callback for message processing.
182 */
183int nxt_unit_process_msg(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id,
184 void *buf, size_t buf_size, void *oob, size_t oob_size);
185
186/*
187 * Main function useful in case when application does not have it's own
188 * event loop. nxt_unit_run() starts infinite message wait and process loop.
189 *
190 * for (;;) {
191 * app_lib->port_recv(...);
192 * nxt_unit_process_msg(...);
193 * }
194 *
195 * The normally function returns when QUIT message received from Unit.
196 */
197int nxt_unit_run(nxt_unit_ctx_t *);
198
199int nxt_unit_run_once(nxt_unit_ctx_t *ctx);
200
199/* Destroy application library object. */
200void nxt_unit_done(nxt_unit_ctx_t *);
201
202/*
203 * Allocate and initialize new execution context with new listen port to
204 * process requests in other thread.
205 */
206nxt_unit_ctx_t *nxt_unit_ctx_alloc(nxt_unit_ctx_t *, void *);
207
208/* Free unused context. It is not required to free main context. */
209void nxt_unit_ctx_free(nxt_unit_ctx_t *);
210
211/* Initialize port_id, calculate hash. */
212void nxt_unit_port_id_init(nxt_unit_port_id_t *port_id, pid_t pid, uint16_t id);
213
214/*
215 * Create extra incoming port, perform all required actions to propogate
216 * the port to Unit server. Fills structure referenced by port_id with
217 * current pid and new port id.
218 */
219int nxt_unit_create_send_port(nxt_unit_ctx_t *, nxt_unit_port_id_t *dst,
220 nxt_unit_port_id_t *port_id);
221
222/* Default 'add_port' implementation. */
223int nxt_unit_add_port(nxt_unit_ctx_t *, nxt_unit_port_t *port);
224
225/* Find previously added port. */
226nxt_unit_port_t *nxt_unit_find_port(nxt_unit_ctx_t *,
227 nxt_unit_port_id_t *port_id);
228
229/* Find, fill output 'port' and remove port from storage. */
230void nxt_unit_find_remove_port(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id,
231 nxt_unit_port_t *port);
232
233/* Default 'remove_port' implementation. */
234void nxt_unit_remove_port(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id);
235
236/* Default 'remove_pid' implementation. */
237void nxt_unit_remove_pid(nxt_unit_ctx_t *, pid_t pid);
238
239/* Default 'quit' implementation. */
240void nxt_unit_quit(nxt_unit_ctx_t *);
241
242/* Default 'port_send' implementation. */
243ssize_t nxt_unit_port_send(nxt_unit_ctx_t *, int fd,
244 const void *buf, size_t buf_size,
245 const void *oob, size_t oob_size);
246
247/* Default 'port_recv' implementation. */
248ssize_t nxt_unit_port_recv(nxt_unit_ctx_t *, int fd, void *buf, size_t buf_size,
249 void *oob, size_t oob_size);
250
251/* Calculates hash for given field name. */
252uint16_t nxt_unit_field_hash(const char* name, size_t name_length);
253
254/* Split host for server name and port. */
255void nxt_unit_split_host(char *host_start, uint32_t host_length,
256 char **name, uint32_t *name_length, char **port, uint32_t *port_length);
257
258/* Group duplicate fields for easy enumeration. */
259void nxt_unit_request_group_dup_fields(nxt_unit_request_info_t *req);
260
261/*
262 * Allocate response structure capable to store limited numer of fields.
263 * The structure may be accessed directly via req->response pointer or
264 * filled step-by-step using functions add_field and add_content.
265 */
266int nxt_unit_response_init(nxt_unit_request_info_t *req,
267 uint16_t status, uint32_t max_fields_count, uint32_t max_fields_size);
268
269int nxt_unit_response_realloc(nxt_unit_request_info_t *req,
270 uint32_t max_fields_count, uint32_t max_fields_size);
271
272int nxt_unit_response_is_init(nxt_unit_request_info_t *req);
273
274int nxt_unit_response_add_field(nxt_unit_request_info_t *req,
275 const char* name, uint8_t name_length,
276 const char* value, uint32_t value_length);
277
278int nxt_unit_response_add_content(nxt_unit_request_info_t *req,
279 const void* src, uint32_t size);
280
281/*
282 * Send prepared response to Unit server. Response structure destroyed during
283 * this call.
284 */
285int nxt_unit_response_send(nxt_unit_request_info_t *req);
286
287int nxt_unit_response_is_sent(nxt_unit_request_info_t *req);
288
289nxt_unit_buf_t *nxt_unit_response_buf_alloc(nxt_unit_request_info_t *req,
290 uint32_t size);
291
292int nxt_unit_buf_send(nxt_unit_buf_t *buf);
293
294void nxt_unit_buf_free(nxt_unit_buf_t *buf);
295
296nxt_unit_buf_t *nxt_unit_buf_next(nxt_unit_buf_t *buf);
297
298uint32_t nxt_unit_buf_max(void);
299
300uint32_t nxt_unit_buf_min(void);
301
302int nxt_unit_response_write(nxt_unit_request_info_t *req, const void *start,
303 size_t size);
304
305int nxt_unit_response_write_cb(nxt_unit_request_info_t *req,
306 nxt_unit_read_info_t *read_info);
307
308ssize_t nxt_unit_request_read(nxt_unit_request_info_t *req, void *dst,
309 size_t size);
310
311void nxt_unit_request_done(nxt_unit_request_info_t *req, int rc);
312
313
314void nxt_unit_log(nxt_unit_ctx_t *ctx, int level, const char* fmt, ...);
315
316void nxt_unit_req_log(nxt_unit_request_info_t *req, int level,
317 const char* fmt, ...);
318
319#if (NXT_DEBUG)
320
321#define nxt_unit_debug(ctx, fmt, ARGS...) \
322 nxt_unit_log(ctx, NXT_UNIT_LOG_DEBUG, fmt, ##ARGS)
323
324#define nxt_unit_req_debug(req, fmt, ARGS...) \
325 nxt_unit_req_log(req, NXT_UNIT_LOG_DEBUG, fmt, ##ARGS)
326
327#else
328
329#define nxt_unit_debug(ctx, fmt, ARGS...)
330
331#define nxt_unit_req_debug(req, fmt, ARGS...)
332
333#endif
334
335
336#define nxt_unit_warn(ctx, fmt, ARGS...) \
337 nxt_unit_log(ctx, NXT_UNIT_LOG_WARN, fmt, ##ARGS)
338
339#define nxt_unit_req_warn(req, fmt, ARGS...) \
340 nxt_unit_req_log(req, NXT_UNIT_LOG_WARN, fmt, ##ARGS)
341
342#define nxt_unit_error(ctx, fmt, ARGS...) \
343 nxt_unit_log(ctx, NXT_UNIT_LOG_ERR, fmt, ##ARGS)
344
345#define nxt_unit_req_error(req, fmt, ARGS...) \
346 nxt_unit_req_log(req, NXT_UNIT_LOG_ERR, fmt, ##ARGS)
347
348#define nxt_unit_alert(ctx, fmt, ARGS...) \
349 nxt_unit_log(ctx, NXT_UNIT_LOG_ALERT, fmt, ##ARGS)
350
351#define nxt_unit_req_alert(req, fmt, ARGS...) \
352 nxt_unit_req_log(req, NXT_UNIT_LOG_ALERT, fmt, ##ARGS)
353
354
355#endif /* _NXT_UNIT_H_INCLUDED_ */
201/* Destroy application library object. */
202void nxt_unit_done(nxt_unit_ctx_t *);
203
204/*
205 * Allocate and initialize new execution context with new listen port to
206 * process requests in other thread.
207 */
208nxt_unit_ctx_t *nxt_unit_ctx_alloc(nxt_unit_ctx_t *, void *);
209
210/* Free unused context. It is not required to free main context. */
211void nxt_unit_ctx_free(nxt_unit_ctx_t *);
212
213/* Initialize port_id, calculate hash. */
214void nxt_unit_port_id_init(nxt_unit_port_id_t *port_id, pid_t pid, uint16_t id);
215
216/*
217 * Create extra incoming port, perform all required actions to propogate
218 * the port to Unit server. Fills structure referenced by port_id with
219 * current pid and new port id.
220 */
221int nxt_unit_create_send_port(nxt_unit_ctx_t *, nxt_unit_port_id_t *dst,
222 nxt_unit_port_id_t *port_id);
223
224/* Default 'add_port' implementation. */
225int nxt_unit_add_port(nxt_unit_ctx_t *, nxt_unit_port_t *port);
226
227/* Find previously added port. */
228nxt_unit_port_t *nxt_unit_find_port(nxt_unit_ctx_t *,
229 nxt_unit_port_id_t *port_id);
230
231/* Find, fill output 'port' and remove port from storage. */
232void nxt_unit_find_remove_port(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id,
233 nxt_unit_port_t *port);
234
235/* Default 'remove_port' implementation. */
236void nxt_unit_remove_port(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id);
237
238/* Default 'remove_pid' implementation. */
239void nxt_unit_remove_pid(nxt_unit_ctx_t *, pid_t pid);
240
241/* Default 'quit' implementation. */
242void nxt_unit_quit(nxt_unit_ctx_t *);
243
244/* Default 'port_send' implementation. */
245ssize_t nxt_unit_port_send(nxt_unit_ctx_t *, int fd,
246 const void *buf, size_t buf_size,
247 const void *oob, size_t oob_size);
248
249/* Default 'port_recv' implementation. */
250ssize_t nxt_unit_port_recv(nxt_unit_ctx_t *, int fd, void *buf, size_t buf_size,
251 void *oob, size_t oob_size);
252
253/* Calculates hash for given field name. */
254uint16_t nxt_unit_field_hash(const char* name, size_t name_length);
255
256/* Split host for server name and port. */
257void nxt_unit_split_host(char *host_start, uint32_t host_length,
258 char **name, uint32_t *name_length, char **port, uint32_t *port_length);
259
260/* Group duplicate fields for easy enumeration. */
261void nxt_unit_request_group_dup_fields(nxt_unit_request_info_t *req);
262
263/*
264 * Allocate response structure capable to store limited numer of fields.
265 * The structure may be accessed directly via req->response pointer or
266 * filled step-by-step using functions add_field and add_content.
267 */
268int nxt_unit_response_init(nxt_unit_request_info_t *req,
269 uint16_t status, uint32_t max_fields_count, uint32_t max_fields_size);
270
271int nxt_unit_response_realloc(nxt_unit_request_info_t *req,
272 uint32_t max_fields_count, uint32_t max_fields_size);
273
274int nxt_unit_response_is_init(nxt_unit_request_info_t *req);
275
276int nxt_unit_response_add_field(nxt_unit_request_info_t *req,
277 const char* name, uint8_t name_length,
278 const char* value, uint32_t value_length);
279
280int nxt_unit_response_add_content(nxt_unit_request_info_t *req,
281 const void* src, uint32_t size);
282
283/*
284 * Send prepared response to Unit server. Response structure destroyed during
285 * this call.
286 */
287int nxt_unit_response_send(nxt_unit_request_info_t *req);
288
289int nxt_unit_response_is_sent(nxt_unit_request_info_t *req);
290
291nxt_unit_buf_t *nxt_unit_response_buf_alloc(nxt_unit_request_info_t *req,
292 uint32_t size);
293
294int nxt_unit_buf_send(nxt_unit_buf_t *buf);
295
296void nxt_unit_buf_free(nxt_unit_buf_t *buf);
297
298nxt_unit_buf_t *nxt_unit_buf_next(nxt_unit_buf_t *buf);
299
300uint32_t nxt_unit_buf_max(void);
301
302uint32_t nxt_unit_buf_min(void);
303
304int nxt_unit_response_write(nxt_unit_request_info_t *req, const void *start,
305 size_t size);
306
307int nxt_unit_response_write_cb(nxt_unit_request_info_t *req,
308 nxt_unit_read_info_t *read_info);
309
310ssize_t nxt_unit_request_read(nxt_unit_request_info_t *req, void *dst,
311 size_t size);
312
313void nxt_unit_request_done(nxt_unit_request_info_t *req, int rc);
314
315
316void nxt_unit_log(nxt_unit_ctx_t *ctx, int level, const char* fmt, ...);
317
318void nxt_unit_req_log(nxt_unit_request_info_t *req, int level,
319 const char* fmt, ...);
320
321#if (NXT_DEBUG)
322
323#define nxt_unit_debug(ctx, fmt, ARGS...) \
324 nxt_unit_log(ctx, NXT_UNIT_LOG_DEBUG, fmt, ##ARGS)
325
326#define nxt_unit_req_debug(req, fmt, ARGS...) \
327 nxt_unit_req_log(req, NXT_UNIT_LOG_DEBUG, fmt, ##ARGS)
328
329#else
330
331#define nxt_unit_debug(ctx, fmt, ARGS...)
332
333#define nxt_unit_req_debug(req, fmt, ARGS...)
334
335#endif
336
337
338#define nxt_unit_warn(ctx, fmt, ARGS...) \
339 nxt_unit_log(ctx, NXT_UNIT_LOG_WARN, fmt, ##ARGS)
340
341#define nxt_unit_req_warn(req, fmt, ARGS...) \
342 nxt_unit_req_log(req, NXT_UNIT_LOG_WARN, fmt, ##ARGS)
343
344#define nxt_unit_error(ctx, fmt, ARGS...) \
345 nxt_unit_log(ctx, NXT_UNIT_LOG_ERR, fmt, ##ARGS)
346
347#define nxt_unit_req_error(req, fmt, ARGS...) \
348 nxt_unit_req_log(req, NXT_UNIT_LOG_ERR, fmt, ##ARGS)
349
350#define nxt_unit_alert(ctx, fmt, ARGS...) \
351 nxt_unit_log(ctx, NXT_UNIT_LOG_ALERT, fmt, ##ARGS)
352
353#define nxt_unit_req_alert(req, fmt, ARGS...) \
354 nxt_unit_req_log(req, NXT_UNIT_LOG_ALERT, fmt, ##ARGS)
355
356
357#endif /* _NXT_UNIT_H_INCLUDED_ */