MySQL 8.0.39
Source Code Documentation
task.h
Go to the documentation of this file.
1/* Copyright (c) 2012, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef TASK_H
25#define TASK_H
26
27#include "xcom/xcom_profile.h"
28
29#include <assert.h>
30#include <errno.h>
31#ifndef XCOM_STANDALONE
32#include "my_compiler.h"
33#endif
34#include "xcom/simset.h"
35#include "xcom/task_arg.h"
36#include "xcom/x_platform.h"
37#include "xcom/xcom_common.h"
38
40#include "xcom/result.h"
41
42/** \file
43 Rudimentary task system in portable C, based on Tom Duff's switch-based
44 coroutine trick
45 and a stack of environment structs. (continuations?)
46 Nonblocking IO and event handling need to be rewritten for each new OS.
47*/
48
49#ifdef TASK_EVENT_TRACE
50void add_base_event(double when, char const *file, int state);
51#define ADD_BASE_EVENT \
52 { \
53 add_base_event(seconds(), __FILE__, __LINE__); \
54 add_event(EVENT_DUMP_PAD, string_arg(__func__)); \
55 }
56
57#define ADD_DBG(d, x) \
58 if (do_dbg(d)) { \
59 ADD_BASE_EVENT x; \
60 add_event(EVENT_DUMP_PAD, end_arg()); \
61 }
62
63#define ADD_EVENTS(x) ADD_DBG(D_BUG, x)
64
65#define ADD_T_EV(when, file, state, what)
66#define ADD_WAIT_EV(when, file, state, what, milli)
67
68#else
69#define ADD_EVENTS(x)
70#define ADD_DBG(d, x)
71#define ADD_T_EV(when, file, state, what)
72#define ADD_WAIT_EV(when, file, state, what, milli)
73#endif
74
75static inline void set_int_arg(task_arg *arg, int value) {
76 arg->type = a_int;
77 arg->val.i = value;
78}
79
80static inline int get_int_arg(task_arg arg) {
81 assert(arg.type == a_int);
82 return arg.val.i;
83}
84
85static inline void set_long_arg(task_arg *arg, long value) {
86 arg->type = a_long;
87 arg->val.l = value;
88}
89
90static inline long get_long_arg(task_arg arg) {
91 assert(arg.type == a_long);
92 return arg.val.l;
93}
94
95static inline void set_uint_arg(task_arg *arg, unsigned int value) {
96 arg->type = a_uint;
97 arg->val.u_i = value;
98}
99
100static inline unsigned int get_uint_arg(task_arg arg) {
101 assert(arg.type == a_uint);
102 return arg.val.u_i;
103}
104
105static inline void set_ulong_arg(task_arg *arg, unsigned long value) {
106 arg->type = a_ulong;
107 arg->val.u_l = value;
108}
109
110static inline void set_ulong_long_arg(task_arg *arg, unsigned long long value) {
111 arg->type = a_ulong_long;
112 arg->val.u_ll = value;
113}
114
115static inline unsigned long get_ulong_arg(task_arg arg) {
116 assert(arg.type == a_ulong);
117 return arg.val.u_l;
118}
119
120static inline unsigned long long get_ulong_long_arg(task_arg arg) {
121 assert(arg.type == a_ulong_long);
122 return arg.val.u_l;
123}
124
125static inline void set_float_arg(task_arg *arg, float value) {
126 arg->type = a_float;
127 arg->val.f = value;
128}
129
130static inline float get_float_arg(task_arg arg) {
131 assert(arg.type == a_float);
132 return arg.val.f;
133}
134
135static inline void set_double_arg(task_arg *arg, double value) {
136 arg->type = a_double;
137 arg->val.d = value;
138}
139
140static inline double get_double_arg(task_arg arg) {
141 assert(arg.type == a_double);
142 return arg.val.d;
143}
144
145static inline void set_string_arg(task_arg *arg, char const *value) {
146 arg->type = a_string;
147 arg->val.s = value;
148}
149
150static inline void set_void_arg(task_arg *arg, void *value) {
151 arg->type = a_void;
152 arg->val.v = value;
153}
154
155static inline char const *get_string_arg(task_arg arg) {
156 assert(arg.type == a_string);
157 return (char const *)arg.val.v;
158}
159
160static inline void *get_void_arg(task_arg arg) {
161 assert(arg.type == a_void);
162 return arg.val.v;
163}
164
165static inline task_arg int_arg(int i) {
166 task_arg retval;
167 set_int_arg(&retval, i);
168 return retval;
169}
170
171static inline task_arg uint_arg(unsigned int i) {
172 task_arg retval;
173 set_uint_arg(&retval, i);
174 return retval;
175}
176
177static inline task_arg ulong_arg(unsigned long l) {
178 task_arg retval;
179 set_ulong_arg(&retval, l);
180 return retval;
181}
182
183static inline task_arg ulong_long_arg(unsigned long long ll) {
184 task_arg retval;
185 set_ulong_long_arg(&retval, ll);
186 return retval;
187}
188
189static inline task_arg double_arg(double i) {
190 task_arg retval;
191 set_double_arg(&retval, i);
192 return retval;
193}
194
195static inline task_arg string_arg(char const *v) {
196 task_arg retval;
197 set_string_arg(&retval, v);
198 return retval;
199}
200
201static inline task_arg void_arg(void *v) {
202 task_arg retval;
203 set_void_arg(&retval, v);
204 return retval;
205}
206
207static inline task_arg end_arg() {
208 task_arg retval;
209 retval.type = a_end;
210 return retval;
211}
212
213/* Combined environment pointer and state variable */
214struct task_ptr {
215 int state;
216 void *ptr;
217};
218
219typedef struct task_ptr TaskAlign;
220
221struct task_env;
222
223/* All task functions have this signature */
224typedef int (*task_func)(task_arg arg);
225
226/* Increase this if tasks need bigger stacks, or use a linked list for the stack
227 */
228#define TASK_POOL_ELEMS 1000
229
230typedef enum terminate_enum {
231 RUN = 0,
232 KILL = 1,
233 TERMINATED = 2
235
236/* A complete task.
237 The buffer buf is used for a heap which grows upwards and a stack which grows
238 downwards.
239 The stack contains pointers to environment structs, which are allocated from
240 the heap.
241 */
242struct task_env {
243 linkage l; /* Used for runnable tasks and wait queues */
244 linkage all; /* Links all tasks */
245 int heap_pos; /* Index in time priority queue, necessary for efficient removal
246 */
248 terminate; /* Set this and activate task to make it terminate */
249 int refcnt; /* Number of references to task */
250 int taskret; /* Return value from task function */
251 task_func func; /* The task function */
252 task_arg arg; /* Argument passed to the task */
253 const char *name; /* The task name */
254 TaskAlign *where; /* High water mark in heap */
255 TaskAlign *stack_top; /* The stack top */
256 TaskAlign *sp; /* The current stack pointer */
257 double time; /* Time when the task should be activated */
258 TaskAlign buf[TASK_POOL_ELEMS]; /* Heap and stack */
259 int debug;
261 int interrupt; /* Set if timeout while waiting */
262};
263
264typedef struct task_env task_env;
265
266#define MAXTASKS 1000
267
268/* Priority queue of task_env */
270 int curn;
272};
273typedef struct task_queue task_queue;
274
275#define _ep ((struct env *)(stack->sp->ptr))
276
277#define TASK_ALLOC(pool, type) (task_allocate(pool, (unsigned int)sizeof(type)))
278
279#if 0
280#define TASK_DEBUG(x) \
281 if (stack->debug) { \
282 IFDBG(D_NONE, FN; STRLIT(x " task "); PTREXP((void *)stack); \
283 STRLIT(stack->name); NDBG(stack->sp->state, d)); \
284 }
285#else
286#define TASK_DEBUG(x)
287#endif
288
289/* Place cleanup code after this label */
290#define FINALLY \
291 task_cleanup:
292
293/* We have reached the top of the stack when sp == stack_top + 1 since the stack
294 * grows downwards */
295#define ON_STACK_TOP (stack->sp == stack->stack_top + 1)
296
297/* If we have climbed the stack to the top, check the terminate flag.
298 Execute cleanup code and exit this stack frame if terminate is set.
299 */
300#define TERM_CHECK \
301 if (ON_STACK_TOP && stack->terminate) goto task_cleanup
302
303#define TERMINATE goto task_cleanup
304
305/* Switch on task state. The first time, allocate a new stack frame and check
306 * for termination */
307#define TASK_BEGIN \
308 /* assert(ep); */ \
309 ADD_DBG( \
310 D_TASK, \
311 if (stack->sp->state) { \
312 add_event(EVENT_DUMP_PAD, string_arg("state")); \
313 add_event(EVENT_DUMP_PAD, int_arg(stack->sp->state)); \
314 } add_event(EVENT_DUMP_PAD, string_arg("TASK_BEGIN")); \
315 add_event(EVENT_DUMP_PAD, void_arg(stack));); \
316 TASK_DEBUG("TASK_BEGIN"); \
317 switch (stack->sp->state) { \
318 case 0: \
319 pushp(stack, TASK_ALLOC(stack, struct env)); \
320 ep = _ep; \
321 assert(ep); \
322 ep->init(); \
323 TERM_CHECK;
324
325/* This stack frame is finished, deallocate it and return 0 to signal exit */
326#define TASK_END \
327 ADD_DBG( \
328 D_TASK, \
329 if (stack->sp->state) { \
330 add_event(EVENT_DUMP_PAD, string_arg("state")); \
331 add_event(EVENT_DUMP_PAD, int_arg(stack->sp->state)); \
332 } add_event(EVENT_DUMP_PAD, string_arg("TASK_END")); \
333 add_event(EVENT_DUMP_PAD, void_arg(stack));); \
334 TASK_DEBUG("TASK_END"); \
335 stack->sp->state = 0; \
336 stack->where = (TaskAlign *)stack->sp->ptr; \
337 assert(stack->where); \
338 popp(stack); \
339 return 0; \
340 } \
341 return 0
342
343/* Assign a return value, execute cleanup code, and exit this stack frame */
344#define TASK_RETURN(x) \
345 { \
346 *ret = (x); \
347 goto task_cleanup; \
348 }
349
350#define TASK_DUMP_ERR \
351 if (errno || SOCK_ERRNO || task_errno) { \
352 IFDBG(D_NONE, FN; NDBG(errno, d); STREXP(strerror(errno)); \
353 NDBG(SOCK_ERRNO, d); STREXP(strerror(SOCK_ERRNO)); \
354 NDBG(task_errno, d); STREXP(strerror(task_errno))); \
355 }
356
357/* Assign -1 as exit code, execute cleanup code, and exit this stack frame */
358#define TASK_FAIL \
359 { \
360 *ret = (-1); \
361 TASK_DUMP_ERR; \
362 IFDBG(D_NONE, FN; STRLIT("TASK_FAIL")); \
363 ADD_DBG(D_TASK, add_event(EVENT_DUMP_PAD, string_arg("task failed"))); \
364 goto task_cleanup; \
365 }
366
367/* Capture the line number in the state variable, and return.
368 When called again (after the switch label), check for termination.
369*/
370#define TASK_YIELD \
371 { \
372 TASK_DEBUG("TASK_YIELD"); \
373 stack->sp->state = __LINE__; \
374 return 1; \
375 case __LINE__: \
376 TASK_DEBUG("RETURN FROM YIELD"); \
377 ep = _ep; \
378 assert(ep); \
379 TERM_CHECK; \
380 }
381
382#define TASK_DEACTIVATE \
383 { \
384 TASK_DEBUG("TASK_DEACTIVATE"); \
385 task_deactivate(stack); \
386 TASK_YIELD; \
387 }
388
389/* Put the task in the queue of tasks waiting for timeout, then yield.
390 Wait until current time + t seconds.
391 */
392#define TASK_DELAY(t) \
393 { \
394 TASK_DEBUG("TASK_DELAY"); \
395 task_delay_until(seconds() + t); \
396 TASK_YIELD; \
397 }
398
399/* Put the task in the queue of tasks waiting for timeout, then yield.
400 Wait until t.
401 */
402#define TASK_DELAY_UNTIL(t) \
403 { \
404 TASK_DEBUG("TASK_DELAY_UNTIL"); \
405 task_delay_until(t); \
406 TASK_YIELD; \
407 }
408
409/* Put the task in a wait queue, then yield */
410#define TASK_WAIT(queue) \
411 { \
412 TASK_DEBUG("TASK_WAIT"); \
413 task_wait(stack, queue); \
414 TASK_YIELD; \
415 }
416
417/* Put the task in a wait queue with timeout, then yield */
418#define TIMED_TASK_WAIT(queue, t) \
419 { \
420 TASK_DEBUG("TIMED_TASK_WAIT"); \
421 task_delay_until(seconds() + (t)); \
422 task_wait(stack, queue); \
423 TASK_YIELD; \
424 }
425
426/* A channel has a queue of data elements and a queue of waiting tasks */
427struct channel {
430};
431
432typedef struct channel channel;
433
434/* Channel construction */
435channel *channel_init(channel *c, unsigned int type);
436
437/* Put data in channel. No wait, since channels can never be full */
438void channel_put(channel *c, linkage *data); /* Append to queue */
440 linkage *data); /* Insert in front of queue */
441
442/* Wait until there is data in the channel, then extract and cast to type */
443#define CHANNEL_GET(channel, ptr, type) \
444 { \
445 while (link_empty(&(channel)->data)) { \
446 TASK_WAIT(&(channel)->queue); \
447 } \
448 *(ptr) = (type *)link_extract_first(&(channel)->data); \
449 IFDBG(D_TRANSPORT, FN; STRLIT("CHANNEL_GET "); PTREXP(*(ptr)); \
450 PTREXP(&((channel)->data))); \
451 }
452
453#define CHANNEL_PEEK(channel, ptr, type) \
454 { \
455 while (link_empty(&(channel)->data)) { \
456 TASK_WAIT(&(channel)->queue); \
457 } \
458 *(ptr) = (type *)link_first(&(channel)->data); \
459 }
460
461#define CHANNEL_GET_REVERSE(channel, ptr, type) \
462 { \
463 while (link_empty(&(channel)->data)) { \
464 TASK_WAIT(&(channel)->queue); \
465 } \
466 *(ptr) = (type *)link_extract_last(&(channel)->data); \
467 }
468
469/*
470 The first time, reset the state of the stack frame of the called function.
471 Keep calling the function until it returns 0, which signals exit.
472 Yield after each call.
473 */
474#define TASK_CALL(funcall) \
475 { \
476 reset_state(stack); \
477 TASK_DEBUG("BEFORE CALL"); \
478 do { \
479 stack->sp--; \
480 stack->taskret = funcall; \
481 stack->sp++; \
482 TERM_CHECK; \
483 if (stack->taskret) TASK_YIELD; \
484 } while (stack->taskret); \
485 TASK_DEBUG("AFTER CALL"); \
486 }
487
488/* Define the typeless struct which is the container for all variables in the
489 * stack frame */
490#define DECL_ENV struct env {
491/*Define a code block where we can init ENV variables. It only works nested
492 within DECL_ENV
493*/
494#define ENV_INIT void init() {
495/*Ends the default initialization block*/
496#define END_ENV_INIT }
497
498/* Define a pointer to the environment struct */
499#define END_ENV \
500 } \
501 ; \
502 [[maybe_unused]] struct env *ep
503
504/* Try to lock a fd for read or write.
505 Yield and spin until it succeeds.
506*/
507#define LOCK_FD(fd, op) \
508 { \
509 while (!lock_fd( \
510 fd, stack, \
511 op)) { /* Effectively a spin lock, but should not happen very often */ \
512 wait_io(stack, fd, op); \
513 TASK_YIELD; \
514 /* TASK_DELAY(1.0); */ \
515 } \
516 }
517
518/* Unlock a fd */
519#define UNLOCK_FD(fd, op) unlock_fd(fd, stack, op)
520
521#ifdef TASK_EVENT_TRACE
522enum { EVENT_DUMP_PAD = 1, EVENT_DUMP_HEX = 2 };
523
524struct task_event {
525 task_arg arg;
526 int flag;
527};
528
529typedef struct task_event task_event;
530
531void add_event(int flag, task_arg te);
532void add_task_event(double when, char const *file, int state, char const *what);
533void add_wait_event(double when, char const *file, int state, char const *what,
534 int milli);
535void dump_task_events();
536void reset_task_events();
537#endif
538
539/* The current task */
540extern task_env *stack;
541
542extern void *task_allocate(task_env *p, unsigned int bytes);
543extern void reset_state(task_env *p);
544extern void pushp(task_env *p, void *ptr);
545extern void popp(task_env *p);
546
547extern double seconds(); /* Return time as double */
548extern double task_now(); /* Return result of last call to seconds() */
549extern void task_delay_until(double time);
550
551extern int unblock_fd(int fd);
552extern int block_fd(int fd);
553
555 void *buf, int n);
556
557extern result con_read(connection_descriptor const *rfd, void *buf, int n);
558extern result con_pipe_read(connection_descriptor const *rfd, void *buf, int n);
559
560extern int task_read(connection_descriptor const *con, void *buf, int n,
561 int64_t *ret,
562 connnection_read_method read_function = con_read);
563
565 void *buf, int n);
566result con_write(connection_descriptor const *wfd, void *buf, int n);
567result con_pipe_write(connection_descriptor const *wfd, void *buf, int n);
568
569extern int task_write(connection_descriptor const *con, void *buf, uint32_t n,
570 int64_t *ret);
571extern int is_locked(int fd);
572extern int lock_fd(int fd, task_env *t, int lock);
573extern int unlock_fd(int fd, task_env *t, int lock);
574
575extern void task_sys_init();
576extern task_env *task_new(task_func func, task_arg arg, const char *name,
577 int debug);
578#define xstr(s) #s
579/* #define task_new(func, arg) _task_new(func, arg, __FILE__":" xstr(__LINE__))
580 */
581extern void task_loop();
582extern void task_wait(task_env *t, linkage *queue);
583extern void task_wakeup(linkage *queue);
585extern void set_task(task_env **p, task_env *t);
586extern void task_terminate_all();
587extern void remove_and_wakeup(int i);
588extern int task_errno;
589extern int is_only_task();
592extern const char *task_name();
593extern task_env *wait_io(task_env *t, int fd, int op);
594
595extern result con_write(connection_descriptor const *wfd, void *buf, int n);
596extern result set_nodelay(int fd);
597
598extern task_env *timed_wait_io(task_env *t, int fd, int op, double timeout);
599
600extern xcom_proto const my_min_xcom_version; /* The minimum protocol version I
601 am able to understand */
602extern xcom_proto const
603 my_xcom_version; /* The maximum protocol version I am able to understand */
604
605#endif
static char * add_event(const char *var, LEX_CSTRING event, const char *data, size_t data_length)
Definition: audit_null.cc:303
const char * p
Definition: ctype-mb.cc:1237
static int flag
Definition: hp_test1.cc:40
Header for compiler-dependent features.
static QUEUE queue
Definition: myisampack.cc:207
Definition: buf0block_hint.cc:30
Definition: os0file.h:86
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:79
static bool timeout(bool(*wait_condition)())
Timeout function.
Definition: log0meb.cc:496
struct result result
Definition: result.h:34
required string type
Definition: replication_group_member_actions.proto:34
case opt name
Definition: sslopt-case.h:33
Definition: task.h:427
linkage queue
Definition: task.h:429
linkage data
Definition: task.h:428
Definition: node_connection.h:47
Definition: simset.h:36
Definition: result.h:30
Definition: task_arg.h:42
unsigned long u_l
Definition: task_arg.h:48
float f
Definition: task_arg.h:50
double d
Definition: task_arg.h:51
void * v
Definition: task_arg.h:53
long l
Definition: task_arg.h:46
union task_arg::@16 val
unsigned int u_i
Definition: task_arg.h:47
char const * s
Definition: task_arg.h:52
arg_type type
Definition: task_arg.h:43
unsigned long long u_ll
Definition: task_arg.h:49
int i
Definition: task_arg.h:45
Definition: task.h:242
task_func func
Definition: task.h:251
linkage l
Definition: task.h:243
TaskAlign * sp
Definition: task.h:256
int interrupt
Definition: task.h:261
int waitfd
Definition: task.h:260
TaskAlign * stack_top
Definition: task.h:255
task_arg arg
Definition: task.h:252
double time
Definition: task.h:257
linkage all
Definition: task.h:244
int taskret
Definition: task.h:250
int refcnt
Definition: task.h:249
int heap_pos
Definition: task.h:245
int debug
Definition: task.h:259
TaskAlign * where
Definition: task.h:254
terminate_enum terminate
Definition: task.h:248
const char * name
Definition: task.h:253
Definition: task.h:214
int state
Definition: task.h:215
void * ptr
Definition: task.h:216
Definition: task.h:269
int curn
Definition: task.h:270
task_env * x[MAXTASKS+1]
Definition: task.h:271
static double get_double_arg(task_arg arg)
Definition: task.h:140
int task_errno
Definition: task.cc:134
void task_sys_init()
Definition: task.cc:1270
void channel_put(channel *c, linkage *data)
Definition: task.cc:594
static void set_ulong_long_arg(task_arg *arg, unsigned long long value)
Definition: task.h:110
static void set_ulong_arg(task_arg *arg, unsigned long value)
Definition: task.h:105
#define MAXTASKS
Definition: task.h:266
static void set_int_arg(task_arg *arg, int value)
Definition: task.h:75
static task_arg string_arg(char const *v)
Definition: task.h:195
#define TASK_POOL_ELEMS
Definition: task.h:228
void task_wakeup(linkage *queue)
Definition: task.cc:569
static unsigned long long get_ulong_long_arg(task_arg arg)
Definition: task.h:120
task_env * task_deactivate(task_env *t)
Definition: task.cc:716
void popp(task_env *p)
Definition: task.cc:665
result con_write(connection_descriptor const *wfd, void *buf, int n)
Definition: task.cc:978
int unlock_fd(int fd, task_env *t, int lock)
result con_read(connection_descriptor const *rfd, void *buf, int n)
Definition: task.cc:891
static task_arg void_arg(void *v)
Definition: task.h:201
double seconds()
Definition: task.cc:310
static void set_float_arg(task_arg *arg, float value)
Definition: task.h:125
static task_arg uint_arg(unsigned int i)
Definition: task.h:171
static unsigned int get_uint_arg(task_arg arg)
Definition: task.h:100
static task_arg ulong_arg(unsigned long l)
Definition: task.h:177
void channel_put_front(channel *c, linkage *data)
Definition: task.cc:600
terminate_enum
Definition: task.h:230
@ TERMINATED
Definition: task.h:233
@ RUN
Definition: task.h:231
@ KILL
Definition: task.h:232
int(* task_func)(task_arg arg)
Definition: task.h:224
static task_arg int_arg(int i)
Definition: task.h:165
void task_delay_until(double time)
Definition: task.cc:553
task_env * task_terminate(task_env *t)
Definition: task.cc:719
task_env * timed_wait_io(task_env *t, int fd, int op, double timeout)
int task_write(connection_descriptor const *con, void *buf, uint32_t n, int64_t *ret)
Definition: task.cc:1024
int task_read(connection_descriptor const *con, void *buf, int n, int64_t *ret, connnection_read_method read_function=con_read)
Definition: task.cc:934
result con_pipe_read(connection_descriptor const *rfd, void *buf, int n)
Definition: task.cc:917
static void set_string_arg(task_arg *arg, char const *value)
Definition: task.h:145
static task_arg end_arg()
Definition: task.h:207
int is_only_task()
Definition: task.cc:1118
result set_nodelay(int fd)
Definition: xcom_transport.cc:134
result(* connnection_read_method)(connection_descriptor const *rfd, void *buf, int n)
Definition: task.h:554
const char * task_name()
Definition: task.cc:1292
static task_arg ulong_long_arg(unsigned long long ll)
Definition: task.h:183
xcom_proto const my_xcom_version
Definition: xcom_transport.cc:82
result(* connnection_write_method)(connection_descriptor const *rfd, void *buf, int n)
Definition: task.h:564
channel * channel_init(channel *c, unsigned int type)
Definition: task.cc:588
int unblock_fd(int fd)
Definition: task.cc:1080
void reset_state(task_env *p)
Definition: task.cc:645
void remove_and_wakeup(int i)
Definition: task.cc:864
static void set_long_arg(task_arg *arg, long value)
Definition: task.h:85
static void * get_void_arg(task_arg arg)
Definition: task.h:160
void task_wait(task_env *t, linkage *queue)
Definition: task.cc:561
static void set_uint_arg(task_arg *arg, unsigned int value)
Definition: task.h:95
static task_arg double_arg(double i)
Definition: task.h:189
static int get_int_arg(task_arg arg)
Definition: task.h:80
result con_pipe_write(connection_descriptor const *wfd, void *buf, int n)
Definition: task.cc:1006
xcom_proto const my_min_xcom_version
Definition: xcom_transport.cc:80
static float get_float_arg(task_arg arg)
Definition: task.h:130
static long get_long_arg(task_arg arg)
Definition: task.h:90
double task_now()
Definition: task.cc:318
task_env * stack
Definition: task.cc:876
void task_loop()
Definition: task.cc:1139
void * task_allocate(task_env *p, unsigned int bytes)
Allocate bytes from pool, initialized to zero.
Definition: task.cc:627
void set_task(task_env **p, task_env *t)
Definition: task.cc:1286
task_env * task_activate(task_env *t)
Definition: task.cc:714
task_env * task_new(task_func func, task_arg arg, const char *name, int debug)
Definition: task.cc:606
int lock_fd(int fd, task_env *t, int lock)
task_env * wait_io(task_env *t, int fd, int op)
Definition: task.cc:878
int block_fd(int fd)
Definition: task.cc:1098
int is_locked(int fd)
static char const * get_string_arg(task_arg arg)
Definition: task.h:155
void task_terminate_all()
Definition: task.cc:732
static unsigned long get_ulong_arg(task_arg arg)
Definition: task.h:115
static void set_double_arg(task_arg *arg, double value)
Definition: task.h:135
static void set_void_arg(task_arg *arg, void *value)
Definition: task.h:150
void pushp(task_env *p, void *ptr)
Definition: task.cc:654
@ a_int
Definition: task_arg.h:29
@ a_double
Definition: task_arg.h:35
@ a_end
Definition: task_arg.h:38
@ a_ulong_long
Definition: task_arg.h:33
@ a_uint
Definition: task_arg.h:31
@ a_long
Definition: task_arg.h:30
@ a_void
Definition: task_arg.h:36
@ a_float
Definition: task_arg.h:34
@ a_string
Definition: task_arg.h:37
@ a_ulong
Definition: task_arg.h:32
int n
Definition: xcom_base.cc:509