xref: /unit/src/nxt_work_queue.h (revision 0:a63ceefd6ab0)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #ifndef _NXT_WORK_QUEUE_H_INCLUDED_
8 #define _NXT_WORK_QUEUE_H_INCLUDED_
9 
10 
11 /*
12  * A work handler with just the obj and data arguments instead
13  * of pointer to a possibly large a work struct allows to call
14  * the handler not only via a work queue but also directly.
15  * The only obj argument is enough for the most cases expect the
16  * source filters, so the data argument has been introduced and
17  * is used where appropriate.
18  */
19 typedef void (*nxt_work_handler_t)(nxt_thread_t *thr, void *obj, void *data);
20 
21 typedef struct nxt_work_s  nxt_work_t;
22 
23 
24 struct nxt_work_s {
25     nxt_work_t                  *next;
26     nxt_work_handler_t          handler;
27     void                        *obj;
28     void                        *data;
29     nxt_log_t                   *log;
30 };
31 
32 
33 typedef struct nxt_work_queue_chunk_s  nxt_work_queue_chunk_t;
34 
35 struct nxt_work_queue_chunk_s {
36     nxt_work_queue_chunk_t      *next;
37     nxt_work_t                  work;
38 };
39 
40 
41 typedef struct {
42     nxt_work_t                  *next;
43     nxt_work_t                  *spare;
44     nxt_work_queue_chunk_t      *chunk;
45     size_t                      chunk_size;
46 } nxt_work_queue_cache_t;
47 
48 
49 typedef struct nxt_work_queue_s  nxt_work_queue_t;
50 
51 struct nxt_work_queue_s {
52     nxt_work_t                  *head;
53     nxt_work_t                  *tail;
54     nxt_work_queue_t            *next;
55 #if (NXT_DEBUG)
56     const char                  *name;
57 #endif
58 };
59 
60 
61 typedef struct {
62     nxt_work_queue_t            *head;
63     nxt_work_queue_t            *tail;
64     nxt_work_queue_t            main;
65     nxt_work_queue_t            last;
66     nxt_work_queue_cache_t      cache;
67 } nxt_thread_work_queue_t;
68 
69 
70 typedef struct {
71     nxt_thread_spinlock_t       lock;
72     nxt_work_t                  *head;
73     nxt_work_t                  *tail;
74     nxt_work_queue_cache_t      cache;
75 } nxt_locked_work_queue_t;
76 
77 
78 NXT_EXPORT void nxt_thread_work_queue_create(nxt_thread_t *thr,
79     size_t chunk_size);
80 NXT_EXPORT void nxt_thread_work_queue_destroy(nxt_thread_t *thr);
81 NXT_EXPORT void nxt_thread_work_queue_add(nxt_thread_t *thr,
82     nxt_work_queue_t *wq,
83     nxt_work_handler_t handler, void *obj, void *data, nxt_log_t *log);
84 NXT_EXPORT void nxt_thread_work_queue_push(nxt_thread_t *thr,
85     nxt_work_queue_t *wq, nxt_work_handler_t handler, void *obj, void *data,
86     nxt_log_t *log);
87 NXT_EXPORT void nxt_work_queue_attach(nxt_thread_t *thr, nxt_work_queue_t *wq);
88 NXT_EXPORT nxt_work_handler_t nxt_thread_work_queue_pop(nxt_thread_t *thr,
89     void **obj, void **data, nxt_log_t **log);
90 NXT_EXPORT void nxt_thread_work_queue_drop(nxt_thread_t *thr, void *data);
91 
92 
93 #define                                                                       \
94 nxt_thread_current_work_queue_add(thr, handler, obj, data, log)               \
95     do {                                                                      \
96         nxt_thread_t  *_thr = thr;                                            \
97                                                                               \
98         nxt_thread_work_queue_add(_thr, _thr->work_queue.head,                \
99                                   handler, obj, data, log);                   \
100     } while (0)
101 
102 
103 NXT_EXPORT void nxt_work_queue_destroy(nxt_work_queue_t *wq);
104 
105 
106 #if (NXT_DEBUG)
107 
108 #define                                                                       \
109 nxt_work_queue_name(_wq, _name)                                               \
110     (_wq)->name = _name
111 
112 #else
113 
114 #define                                                                       \
115 nxt_work_queue_name(_wq, _name)
116 
117 #endif
118 
119 
120 NXT_EXPORT void nxt_thread_last_work_queue_add(nxt_thread_t *thr,
121     nxt_work_handler_t handler, void *obj, void *data, nxt_log_t *log);
122 NXT_EXPORT nxt_work_handler_t nxt_thread_last_work_queue_pop(nxt_thread_t *thr,
123     void **obj, void **data, nxt_log_t **log);
124 
125 
126 NXT_EXPORT void nxt_locked_work_queue_create(nxt_locked_work_queue_t *lwq,
127     size_t chunk_size);
128 NXT_EXPORT void nxt_locked_work_queue_destroy(nxt_locked_work_queue_t *lwq);
129 NXT_EXPORT void nxt_locked_work_queue_add(nxt_locked_work_queue_t *lwq,
130     nxt_work_handler_t handler, void *obj, void *data, nxt_log_t *log);
131 NXT_EXPORT nxt_work_handler_t nxt_locked_work_queue_pop(
132     nxt_locked_work_queue_t *lwq, void **obj, void **data, nxt_log_t **log);
133 NXT_EXPORT void nxt_locked_work_queue_move(nxt_thread_t *thr,
134     nxt_locked_work_queue_t *lwq, nxt_work_queue_t *wq);
135 
136 
137 #endif /* _NXT_WORK_QUEUE_H_INCLUDED_ */
138