Coverage Report

Created: 2026-08-19 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/haproxy/include/haproxy/task-t.h
Line
Count
Source
1
/*
2
 * include/haproxy/task-t.h
3
 * Macros, variables and structures for task management.
4
 *
5
 * Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation, version 2.1
10
 * exclusively.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20
 */
21
22
#ifndef _HAPROXY_TASK_T_H
23
#define _HAPROXY_TASK_T_H
24
25
#include <sys/time.h>
26
27
#include <import/ebtree-t.h>
28
29
#include <haproxy/api-t.h>
30
#include <haproxy/show_flags-t.h>
31
#include <haproxy/thread-t.h>
32
33
/* values for task->state (32 bits).
34
 * Please also update the task_show_state() function below in case of changes.
35
 */
36
0
#define TASK_SLEEPING     0x00000000  /* task sleeping */
37
0
#define TASK_RUNNING      0x00000001  /* the task is currently running */
38
/* unused                 0x00000002 */
39
0
#define TASK_QUEUED       0x00000004  /* The task has been (re-)added to the run queue */
40
#define TASK_RT           0x00000008  /* This task always skips the priority queue */
41
0
#define TASK_SELF_WAKING  0x00000010  /* task/tasklet found waking itself */
42
0
#define TASK_KILLED       0x00000020  /* task/tasklet killed, may now be freed */
43
0
#define TASK_HEAVY        0x00000080  /* this task/tasklet is extremely heavy */
44
45
0
#define TASK_WOKEN_INIT   0x00000100  /* woken up for initialisation purposes */
46
0
#define TASK_WOKEN_TIMER  0x00000200  /* woken up because of expired timer */
47
0
#define TASK_WOKEN_IO     0x00000400  /* woken up because of completed I/O */
48
0
#define TASK_WOKEN_SIGNAL 0x00000800  /* woken up by a system signal */
49
0
#define TASK_WOKEN_MSG    0x00001000  /* woken up by another task's message (see also UEVT/USR1) */
50
0
#define TASK_WOKEN_RES    0x00002000  /* woken up because of available resource */
51
0
#define TASK_WOKEN_OTHER  0x00004000  /* woken up for an unspecified reason (see also UEVT/USR1) */
52
53
/* use this to check a task state or to clean it up before queueing */
54
0
#define TASK_WOKEN_ANY    (TASK_WOKEN_OTHER|TASK_WOKEN_INIT|TASK_WOKEN_TIMER| \
55
0
                           TASK_WOKEN_IO|TASK_WOKEN_SIGNAL|TASK_WOKEN_MSG| \
56
0
                           TASK_WOKEN_RES|TASK_WOKEN_WQ)
57
58
0
#define TASK_F_TASKLET    0x00008000  /* nature of this task: 0=task 1=tasklet */
59
0
#define TASK_F_USR1       0x00010000  /* preserved user flag 1, application-specific, def:0 */
60
0
#define TASK_F_UEVT1      0x00020000  /* one-shot user event type 1, application specific, def:0 */
61
0
#define TASK_F_UEVT2      0x00040000  /* one-shot user event type 2, application specific, def:0 */
62
0
#define TASK_F_WANTS_TIME 0x00080000  /* task/tasklet wants th_ctx->sched_call_date to be set */
63
0
#define TASK_F_UEVT3      0x00100000  /* one-shot user event type 3, application specific, def:0 */
64
0
#define TASK_WOKEN_WQ     0x00200000  /* The task has been waken up only to be put in the wait queue, because its expire changed */
65
/* unused: 0x400000..0x80000000 */
66
67
/* These flags are persistent across scheduler calls */
68
#define TASK_PERSISTENT   (TASK_SELF_WAKING | TASK_KILLED | TASK_RT | \
69
                           TASK_HEAVY | TASK_F_TASKLET | TASK_F_USR1 | \
70
                           TASK_F_WANTS_TIME)
71
72
/* This function is used to report state in debugging tools. Please reflect
73
 * below any single-bit flag addition above in the same order via the
74
 * __APPEND_FLAG macro. The new end of the buffer is returned.
75
 */
76
static forceinline char *task_show_state(char *buf, size_t len, const char *delim, uint flg)
77
0
{
78
0
#define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__)
79
0
  /* prologue */
80
0
  _(0);
81
0
  /* flags */
82
0
  _(TASK_RUNNING, _(TASK_QUEUED, _(TASK_SELF_WAKING,
83
0
  _(TASK_KILLED, _(TASK_HEAVY, _(TASK_WOKEN_INIT,
84
0
  _(TASK_WOKEN_TIMER, _(TASK_WOKEN_IO, _(TASK_WOKEN_SIGNAL,
85
0
  _(TASK_WOKEN_MSG, _(TASK_WOKEN_RES, _(TASK_WOKEN_OTHER,
86
0
  _(TASK_F_TASKLET, _(TASK_F_USR1, _(TASK_WOKEN_WQ)))))))))))))));
87
0
  /* epilogue */
88
0
  _(~0U);
89
0
  return buf;
90
0
#undef _
91
0
}
Unexecuted instantiation: fuzz_hpack_decode.c:task_show_state
Unexecuted instantiation: fuzz_h1_htx.c:task_show_state
Unexecuted instantiation: chunk.c:task_show_state
Unexecuted instantiation: debug.c:task_show_state
Unexecuted instantiation: fd.c:task_show_state
Unexecuted instantiation: h1_htx.c:task_show_state
Unexecuted instantiation: haproxy.c:task_show_state
Unexecuted instantiation: http.c:task_show_state
Unexecuted instantiation: http_htx.c:task_show_state
Unexecuted instantiation: htx.c:task_show_state
Unexecuted instantiation: limits.c:task_show_state
Unexecuted instantiation: listener.c:task_show_state
Unexecuted instantiation: log.c:task_show_state
Unexecuted instantiation: mworker.c:task_show_state
Unexecuted instantiation: peers.c:task_show_state
Unexecuted instantiation: pool.c:task_show_state
Unexecuted instantiation: proto_sockpair.c:task_show_state
Unexecuted instantiation: protocol.c:task_show_state
Unexecuted instantiation: proxy.c:task_show_state
Unexecuted instantiation: resolvers.c:task_show_state
Unexecuted instantiation: ring.c:task_show_state
Unexecuted instantiation: sample.c:task_show_state
Unexecuted instantiation: server.c:task_show_state
Unexecuted instantiation: session.c:task_show_state
Unexecuted instantiation: signal.c:task_show_state
Unexecuted instantiation: sink.c:task_show_state
Unexecuted instantiation: sock.c:task_show_state
Unexecuted instantiation: sock_inet.c:task_show_state
Unexecuted instantiation: stats-proxy.c:task_show_state
Unexecuted instantiation: stats.c:task_show_state
Unexecuted instantiation: stconn.c:task_show_state
Unexecuted instantiation: stick_table.c:task_show_state
Unexecuted instantiation: stream.c:task_show_state
Unexecuted instantiation: systemd.c:task_show_state
Unexecuted instantiation: task.c:task_show_state
Unexecuted instantiation: tcp_rules.c:task_show_state
Unexecuted instantiation: tcpcheck.c:task_show_state
Unexecuted instantiation: thread.c:task_show_state
Unexecuted instantiation: tools.c:task_show_state
Unexecuted instantiation: trace.c:task_show_state
Unexecuted instantiation: uri_auth.c:task_show_state
Unexecuted instantiation: vars.c:task_show_state
Unexecuted instantiation: version.c:task_show_state
Unexecuted instantiation: acl.c:task_show_state
Unexecuted instantiation: action.c:task_show_state
Unexecuted instantiation: activity.c:task_show_state
Unexecuted instantiation: applet.c:task_show_state
Unexecuted instantiation: arg.c:task_show_state
Unexecuted instantiation: auth.c:task_show_state
Unexecuted instantiation: backend.c:task_show_state
Unexecuted instantiation: cfgparse-listen.c:task_show_state
Unexecuted instantiation: cfgparse.c:task_show_state
Unexecuted instantiation: channel.c:task_show_state
Unexecuted instantiation: check.c:task_show_state
Unexecuted instantiation: cli.c:task_show_state
Unexecuted instantiation: clock.c:task_show_state
Unexecuted instantiation: connection.c:task_show_state
Unexecuted instantiation: counters.c:task_show_state
Unexecuted instantiation: dgram.c:task_show_state
Unexecuted instantiation: dns.c:task_show_state
Unexecuted instantiation: dns_ring.c:task_show_state
Unexecuted instantiation: dynbuf.c:task_show_state
Unexecuted instantiation: errors.c:task_show_state
Unexecuted instantiation: event_hdl.c:task_show_state
Unexecuted instantiation: extcheck.c:task_show_state
Unexecuted instantiation: filters.c:task_show_state
Unexecuted instantiation: fix.c:task_show_state
Unexecuted instantiation: flt_http_comp.c:task_show_state
Unexecuted instantiation: freq_ctr.c:task_show_state
Unexecuted instantiation: frontend.c:task_show_state
Unexecuted instantiation: guid.c:task_show_state
Unexecuted instantiation: h1.c:task_show_state
Unexecuted instantiation: haterm.c:task_show_state
Unexecuted instantiation: http_ana.c:task_show_state
Unexecuted instantiation: http_ext.c:task_show_state
Unexecuted instantiation: http_fetch.c:task_show_state
Unexecuted instantiation: http_rules.c:task_show_state
Unexecuted instantiation: lb_chash.c:task_show_state
Unexecuted instantiation: lb_fas.c:task_show_state
Unexecuted instantiation: lb_fwlc.c:task_show_state
Unexecuted instantiation: lb_fwrr.c:task_show_state
Unexecuted instantiation: lb_map.c:task_show_state
Unexecuted instantiation: lb_ss.c:task_show_state
Unexecuted instantiation: mailers.c:task_show_state
Unexecuted instantiation: mqtt.c:task_show_state
Unexecuted instantiation: mux_spop.c:task_show_state
Unexecuted instantiation: pattern.c:task_show_state
Unexecuted instantiation: payload.c:task_show_state
Unexecuted instantiation: pipe.c:task_show_state
Unexecuted instantiation: proto_rhttp.c:task_show_state
Unexecuted instantiation: queue.c:task_show_state
Unexecuted instantiation: regex.c:task_show_state
Unexecuted instantiation: stats-file.c:task_show_state
Unexecuted instantiation: stats-html.c:task_show_state
Unexecuted instantiation: stats-json.c:task_show_state
Unexecuted instantiation: cache.c:task_show_state
Unexecuted instantiation: cfgcond.c:task_show_state
Unexecuted instantiation: cfgparse-global.c:task_show_state
Unexecuted instantiation: compression.c:task_show_state
Unexecuted instantiation: fcgi-app.c:task_show_state
Unexecuted instantiation: flt_spoe.c:task_show_state
Unexecuted instantiation: proto_tcp.c:task_show_state
Unexecuted instantiation: shctx.c:task_show_state
Unexecuted instantiation: fuzz_http.c:task_show_state
Unexecuted instantiation: fuzz_cfg_parser.c:task_show_state
Unexecuted instantiation: fuzz_h1_parse.c:task_show_state
92
93
/* these wakeup types are used to indicate how a task/tasklet was woken up, for
94
 * debugging purposes.
95
 */
96
enum {
97
  WAKEUP_TYPE_UNSET = 0,
98
  WAKEUP_TYPE_TASK_WAKEUP,
99
  WAKEUP_TYPE_TASK_INSTANT_WAKEUP,
100
  WAKEUP_TYPE_TASKLET_WAKEUP,
101
  WAKEUP_TYPE_TASKLET_WAKEUP_AFTER,
102
  WAKEUP_TYPE_TASK_SCHEDULE,
103
  WAKEUP_TYPE_TASK_QUEUE,
104
  WAKEUP_TYPE_APPCTX_WAKEUP,
105
};
106
107
struct notification {
108
  struct list purge_me; /* Part of the list of signals to be purged in the
109
                           case of the LUA execution stack crash. */
110
  struct mt_list wake_me; /* thread safe signal list */
111
  struct task *task; /* The task to be wake if an event occurs. */
112
  __decl_thread(HA_SPINLOCK_T lock);
113
};
114
115
#ifdef DEBUG_TASK
116
/* prev_caller keeps a copy of the previous value of the <caller> field. */
117
#define TASK_DEBUG_STORAGE                   \
118
  struct {                             \
119
    const struct ha_caller *prev_caller; \
120
  } debug
121
#else
122
#define TASK_DEBUG_STORAGE
123
#endif
124
125
/* This part is common between struct task and struct tasklet so that tasks
126
 * can be used as-is as tasklets.
127
 *
128
 * Note that the process() function must ALWAYS return the task/tasklet's
129
 * pointer if the task/tasklet remains valid, and return NULL if it has been
130
 * deleted. The scheduler relies on this to know if it should update its state
131
 * on return.
132
 *
133
 * Keep in mind that tasks can be cast to tasklets while in the final tasklet
134
 * queues, and will be listed via the tasklet's <list> instead of the task's
135
 * <rq>. However other fields (wq, common) must remain totally valid for the
136
 * task during this time. This explains why certain elements are present in
137
 * the common part even though pure tasklets do not need them.
138
 */
139
#define TASK_COMMON             \
140
  unsigned int state; /* task state : bitfield of TASK_ */ \
141
  int tid;            /* tid of task/tasklet. <0 = local for tasklet, unbound for task */ \
142
  struct task *(*process)(struct task *t, void *ctx, unsigned int state); /* the function which processes the task */ \
143
  void *context; /* the task's context */     \
144
  const struct ha_caller *caller;  /* call place of last wakeup(); 0 on init, -1 on free */ \
145
  uint32_t wake_date;              /* date of the last task wakeup */ \
146
  unsigned int calls;              /* number of times process was called */ \
147
  TASK_DEBUG_STORAGE;         \
148
  short last_run;                  /* 16-bit now_ms of last run */          \
149
  short nice;                      /* task prio from -1024 to +1024 */      \
150
  int expire;                      /* next expiration date for this task, in ticks */
151
  /* total: 36 or 48 bytes on 32/64 bit platforms */
152
153
/* The base for all tasks */
154
struct task {
155
  TASK_COMMON;      /* must be at the beginning! */
156
  struct eb32_node rq;    /* ebtree node used to hold the task in the run queue */
157
  /* WARNING: the struct task is often aliased as a struct tasklet when
158
   * it is NOT in the run queue. The tasklet has its struct list here
159
   * where rq starts and this works because both are exclusive. Never
160
   * ever reorder these fields without taking this into account!
161
   */
162
  struct eb32_node wq;    /* ebtree node used to hold the task in the wait queue */
163
};
164
165
/* lightweight tasks, without priority, mainly used for I/Os */
166
struct tasklet {
167
  TASK_COMMON;      /* must be at the beginning! */
168
  struct list list;
169
  /* WARNING: the struct task is often aliased as a struct tasklet when
170
   * it is not in the run queue. The task has its struct rq here where
171
   * list starts and this works because both are exclusive. Never ever
172
   * reorder these fields without taking this into account!
173
   */
174
};
175
176
/* Note: subscribing to these events is only valid after the caller has really
177
 * attempted to perform the operation, and failed to proceed or complete.
178
 */
179
enum sub_event_type {
180
  SUB_RETRY_RECV       = 0x00000001,  /* Schedule the tasklet when we can attempt to recv again */
181
  SUB_RETRY_SEND       = 0x00000002,  /* Schedule the tasklet when we can attempt to send again */
182
};
183
184
/* Describes a set of subscriptions. Multiple events may be registered at the
185
 * same time. The callee should assume everything not pending for completion is
186
 * implicitly possible. It's illegal to change the tasklet if events are still
187
 * registered.
188
 */
189
struct wait_event {
190
  struct tasklet *tasklet;
191
  int events;             /* set of enum sub_event_type above */
192
};
193
194
/*
195
 * The task callback (->process) is responsible for updating ->expire. It must
196
 * return a pointer to the task itself, except if the task has been deleted, in
197
 * which case it returns NULL so that the scheduler knows it must not check the
198
 * expire timer. The scheduler will requeue the task at the proper location.
199
 */
200
201
202
#endif /* _HAPROXY_TASK_T_H */
203
204
/*
205
 * Local variables:
206
 *  c-indent-level: 8
207
 *  c-basic-offset: 8
208
 * End:
209
 */