MySQL  8.0.19
Source Code Documentation
task.h
Go to the documentation of this file.
1 /* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
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 also distributed 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 included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef TASK_H
24 #define TASK_H
25 
26 #include <assert.h>
27 #include <errno.h>
28 #ifndef XCOM_STANDALONE
29 #include "my_compiler.h"
30 #endif
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
43 
44 /** \file
45  Rudimentary task system in portable C, based on Tom Duff's switch-based
46  coroutine trick
47  and a stack of environment structs. (continuations?)
48  Nonblocking IO and event handling need to be rewritten for each new OS.
49 */
50 
51 #ifdef TASK_EVENT_TRACE
52 void add_base_event(double when, char const *file, int state);
53 #define ADD_BASE_EVENT \
54  { \
55  add_base_event(seconds(), __FILE__, __LINE__); \
56  add_event(string_arg(__func__)); \
57  }
58 #define ADD_EVENTS(x) \
59  { \
60  ADD_BASE_EVENT x; \
61  add_event(end_arg()); \
62  }
63 
64 #define ADD_T_EV(when, file, state, what) \
65  add_task_event(when, file, state, what)
66 #define ADD_WAIT_EV(when, file, state, what, milli) \
67  add_wait_event(when, file, state, what, milli)
68 #else
69 #define ADD_EVENTS(x)
70 
71 #define ADD_T_EV(when, file, state, what)
72 #define ADD_WAIT_EV(when, file, state, what, milli)
73 #endif
74 
75 static inline void set_int_arg(task_arg *arg, int value) {
76  arg->type = a_int;
77  arg->val.i = value;
78 }
79 
80 static inline int get_int_arg(task_arg arg) {
81  assert(arg.type == a_int);
82  return arg.val.i;
83 }
84 
85 static inline void set_long_arg(task_arg *arg, long value) {
86  arg->type = a_long;
87  arg->val.l = value;
88 }
89 
90 static inline long get_long_arg(task_arg arg) {
91  assert(arg.type == a_long);
92  return arg.val.l;
93 }
94 
95 static inline void set_uint_arg(task_arg *arg, unsigned int value) {
96  arg->type = a_uint;
97  arg->val.u_i = value;
98 }
99 
100 static inline unsigned int get_uint_arg(task_arg arg) {
101  assert(arg.type == a_uint);
102  return arg.val.u_i;
103 }
104 
105 static inline void set_ulong_arg(task_arg *arg, unsigned long value) {
106  arg->type = a_ulong;
107  arg->val.u_l = value;
108 }
109 
110 static 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 
115 static inline unsigned long get_ulong_arg(task_arg arg) {
116  assert(arg.type == a_ulong);
117  return arg.val.u_l;
118 }
119 
120 static 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 
125 static inline void set_float_arg(task_arg *arg, float value) {
126  arg->type = a_float;
127  arg->val.f = value;
128 }
129 
130 static inline float get_float_arg(task_arg arg) {
131  assert(arg.type == a_float);
132  return arg.val.f;
133 }
134 
135 static inline void set_double_arg(task_arg *arg, double value) {
136  arg->type = a_double;
137  arg->val.d = value;
138 }
139 
140 static inline double get_double_arg(task_arg arg) {
141  assert(arg.type == a_double);
142  return arg.val.d;
143 }
144 
145 static inline void set_string_arg(task_arg *arg, char const *value) {
146  arg->type = a_string;
147  arg->val.s = value;
148 }
149 
150 static inline void set_void_arg(task_arg *arg, void *value) {
151  arg->type = a_void;
152  arg->val.v = value;
153 }
154 
155 static inline char const *get_string_arg(task_arg arg) {
156  assert(arg.type == a_string);
157  return (char const *)arg.val.v;
158 }
159 
160 static inline void *get_void_arg(task_arg arg) {
161  assert(arg.type == a_void);
162  return arg.val.v;
163 }
164 
165 static inline task_arg int_arg(int i) {
166  task_arg retval;
167  set_int_arg(&retval, i);
168  return retval;
169 }
170 
171 static inline task_arg uint_arg(unsigned int i) {
172  task_arg retval;
173  set_uint_arg(&retval, i);
174  return retval;
175 }
176 
177 static inline task_arg ulong_arg(unsigned long l) {
178  task_arg retval;
179  set_ulong_arg(&retval, l);
180  return retval;
181 }
182 
183 static 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 
189 static inline task_arg double_arg(double i) {
190  task_arg retval;
191  set_double_arg(&retval, i);
192  return retval;
193 }
194 
195 static inline task_arg string_arg(char const *v) {
196  task_arg retval;
197  set_string_arg(&retval, v);
198  return retval;
199 }
200 
201 static inline task_arg void_arg(void *v) {
202  task_arg retval;
203  set_void_arg(&retval, v);
204  return retval;
205 }
206 
207 static 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 */
214 struct task_ptr {
215  int state;
216  void *ptr;
217 };
218 
219 typedef struct task_ptr TaskAlign;
220 
221 struct task_env;
222 
223 /* All task functions have this signature */
224 typedef 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 
230 /* A complete task.
231  The buffer buf is used for a heap which grows upwards and a stack which grows
232  downwards.
233  The stack contains pointers to environment structs, which are allocated from
234  the heap.
235  */
236 struct task_env {
237  linkage l; /* Used for runnable tasks and wait queues */
238  linkage all; /* Links all tasks */
239  int heap_pos; /* Index in time priority queue, necessary for efficient removal
240  */
241  enum {
242  RUN = 0,
243  KILL = 1,
245  } terminate; /* Set this and activate task to make it terminate */
246  int refcnt; /* Number of references to task */
247  int taskret; /* Return value from task function */
248  task_func func; /* The task function */
249  task_arg arg; /* Argument passed to the task */
250  const char *name; /* The task name */
251  TaskAlign *where; /* High water mark in heap */
252  TaskAlign *stack_top; /* The stack top */
253  TaskAlign *sp; /* The current stack pointer */
254  double time; /* Time when the task should be activated */
255  TaskAlign buf[TASK_POOL_ELEMS]; /* Heap and stack */
256  int debug;
257  int waitfd;
258  int interrupt; /* Set if timeout while waiting */
259 };
260 
261 typedef struct task_env task_env;
262 
263 #define MAXTASKS 1000
264 
265 /* Priority queue of task_env */
266 struct task_queue {
267  int curn;
269 };
270 typedef struct task_queue task_queue;
271 
272 #define _ep ((struct env *)(stack->sp->ptr))
273 
274 #define TASK_ALLOC(pool, type) (task_allocate(pool, (unsigned int)sizeof(type)))
275 
276 #if 0
277 #define TASK_DEBUG(x) \
278  if (stack->debug) { \
279  DBGOUT(FN; STRLIT(x " task "); PTREXP((void *)stack); STRLIT(stack->name); \
280  NDBG(stack->sp->state, d)); \
281  }
282 #else
283 #define TASK_DEBUG(x)
284 #endif
285 
286 /* Place cleanup code after this label */
287 #define FINALLY \
288  task_cleanup:
289 
290 /* We have reached the top of the stack when sp == stack_top + 1 since the stack
291  * grows downwards */
292 #define ON_STACK_TOP (stack->sp == stack->stack_top + 1)
293 
294 /* If we have climbed the stack to the top, check the terminate flag.
295  Execute cleanup code and exit this stack frame if terminate is set.
296  */
297 #define TERM_CHECK \
298  if (ON_STACK_TOP && stack->terminate) goto task_cleanup
299 
300 #define TERMINATE goto task_cleanup
301 
302 #define TASK_STACK_DEBUG \
303  if (stack->debug) { \
304  char *fnpos = strrchr(__FILE__, DIR_SEP); \
305  if (fnpos) \
306  fnpos++; \
307  else \
308  fnpos = __FILE__; \
309  DBGOUT(FN; STRLIT("TASK_BEGIN "); STREXP(stack->name); STRLIT(fnpos); \
310  STRLIT(":"); NPUT(stack->sp->state, d); NDBG(stack->terminate, d)); \
311  }
312 
313 /* Switch on task state. The first time, allocate a new stack frame and check
314  * for termination */
315 #define TASK_BEGIN \
316  /* assert(ep); */ \
317  ADD_EVENTS(if (stack->sp->state) { \
318  add_event(string_arg("state")); \
319  add_event(int_arg(stack->sp->state)); \
320  } add_event(string_arg("TASK_BEGIN")); \
321  add_event(void_arg(stack)); add_event(string_arg(stack->name));); \
322  TASK_DEBUG("TASK_BEGIN"); \
323  switch (stack->sp->state) { \
324  case 0: \
325  pushp(stack, TASK_ALLOC(stack, struct env)); \
326  ep = _ep; \
327  assert(ep); \
328  TERM_CHECK;
329 
330 /* This stack frame is finished, deallocate it and return 0 to signal exit */
331 #define TASK_END \
332  ADD_EVENTS(if (stack->sp->state) { \
333  add_event(string_arg("state")); \
334  add_event(int_arg(stack->sp->state)); \
335  } add_event(string_arg("TASK_END")); \
336  add_event(void_arg(stack)); add_event(string_arg(stack->name));); \
337  TASK_DEBUG("TASK_END"); \
338  stack->sp->state = 0; \
339  stack->where = stack->sp->ptr; \
340  assert(stack->where); \
341  popp(stack); \
342  return 0; \
343  } \
344  return 0
345 
346 /* Assign a return value, execute cleanup code, and exit this stack frame */
347 #define TASK_RETURN(x) \
348  { \
349  *ret = (x); \
350  goto task_cleanup; \
351  }
352 
353 #define TASK_DUMP_ERR \
354  if (errno || SOCK_ERRNO || task_errno) { \
355  DBGOUT(FN; NDBG(errno, d); STREXP(strerror(errno)); NDBG(SOCK_ERRNO, d); \
356  STREXP(strerror(SOCK_ERRNO)); NDBG(task_errno, d); \
357  STREXP(strerror(task_errno))); \
358  }
359 
360 /* Assign -1 as exit code, execute cleanup code, and exit this stack frame */
361 #define TASK_FAIL \
362  { \
363  *ret = (-1); \
364  TASK_DUMP_ERR; \
365  DBGOUT(FN; STRLIT("TASK_FAIL")); \
366  ADD_EVENTS(add_event(string_arg("task failed"))); \
367  goto task_cleanup; \
368  }
369 
370 /* Capture the line number in the state variable, and return.
371  When called again (after the switch label), check for termination.
372 */
373 #define TASK_YIELD \
374  { \
375  TASK_DEBUG("TASK_YIELD"); \
376  stack->sp->state = __LINE__; \
377  return 1; \
378  case __LINE__: \
379  TASK_DEBUG("RETURN FROM YIELD"); \
380  ep = _ep; \
381  assert(ep); \
382  TERM_CHECK; \
383  }
384 
385 #define TASK_DEACTIVATE \
386  { \
387  TASK_DEBUG("TASK_DEACTIVATE"); \
388  task_deactivate(stack); \
389  TASK_YIELD; \
390  }
391 
392 /* Put the task in the queue of tasks waiting for timeout, then yield.
393  Wait until current time + t seconds.
394  */
395 #define TASK_DELAY(t) \
396  { \
397  TASK_DEBUG("TASK_DELAY"); \
398  task_delay_until(seconds() + t); \
399  TASK_YIELD; \
400  }
401 
402 /* Put the task in the queue of tasks waiting for timeout, then yield.
403  Wait until t.
404  */
405 #define TASK_DELAY_UNTIL(t) \
406  { \
407  TASK_DEBUG("TASK_DELAY_UNTIL"); \
408  task_delay_until(t); \
409  TASK_YIELD; \
410  }
411 
412 /* Put the task in a wait queue, then yield */
413 #define TASK_WAIT(queue) \
414  { \
415  TASK_DEBUG("TASK_WAIT"); \
416  task_wait(stack, queue); \
417  TASK_YIELD; \
418  }
419 
420 /* Put the task in a wait queue with timeout, then yield */
421 #define TIMED_TASK_WAIT(queue, t) \
422  { \
423  TASK_DEBUG("TIMED_TASK_WAIT"); \
424  task_delay_until(seconds() + (t)); \
425  task_wait(stack, queue); \
426  TASK_YIELD; \
427  }
428 
429 /* A channel has a queue of data elements and a queue of waiting tasks */
430 struct channel {
433 };
434 
435 typedef struct channel channel;
436 
437 /* Channel construction */
438 channel *channel_init(channel *c, unsigned int type);
440 
441 /* Put data in channel. No wait, since channels can never be full */
442 void channel_put(channel *c, linkage *data); /* Append to queue */
443 void channel_put_front(channel *c,
444  linkage *data); /* Insert in front of queue */
445 
446 /* Wait until there is data in the channel, then extract and cast to type */
447 #define CHANNEL_GET(channel, ptr, type) \
448  { \
449  while (link_empty(&(channel)->data)) { \
450  TASK_WAIT(&(channel)->queue); \
451  } \
452  *(ptr) = (type *)link_extract_first(&(channel)->data); \
453  DBGOUT(FN; STRLIT("CHANNEL_GET "); PTREXP(*(ptr)); \
454  PTREXP(&((channel)->data))); \
455  }
456 
457 #define CHANNEL_PEEK(channel, ptr, type) \
458  { \
459  while (link_empty(&(channel)->data)) { \
460  TASK_WAIT(&(channel)->queue); \
461  } \
462  *(ptr) = (type *)link_first(&(channel)->data); \
463  }
464 
465 #define CHANNEL_GET_REVERSE(channel, ptr, type) \
466  { \
467  while (link_empty(&(channel)->data)) { \
468  TASK_WAIT(&(channel)->queue); \
469  } \
470  *(ptr) = (type *)link_extract_last(&(channel)->data); \
471  }
472 
473 /*
474  The first time, reset the state of the stack frame of the called function.
475  Keep calling the function until it returns 0, which signals exit.
476  Yield after each call.
477  */
478 #define TASK_CALL(funcall) \
479  { \
480  reset_state(stack); \
481  TASK_DEBUG("BEFORE CALL"); \
482  do { \
483  stack->sp--; \
484  stack->taskret = funcall; \
485  stack->sp++; \
486  TERM_CHECK; \
487  if (stack->taskret) TASK_YIELD; \
488  } while (stack->taskret); \
489  TASK_DEBUG("AFTER CALL"); \
490  }
491 
492 /* Define the typeless struct which is the container for all variables in the
493  * stack frame */
494 #define DECL_ENV struct env {
495 /* Define a pointer to the environment struct */
496 #define END_ENV \
497  } \
498  ; \
499  struct env MY_ATTRIBUTE((unused)) * ep
500 
501 /* Try to lock a fd for read or write.
502  Yield and spin until it succeeds.
503 */
504 #define LOCK_FD(fd, op) \
505  { \
506  while (!lock_fd( \
507  fd, stack, \
508  op)) { /* Effectively a spin lock, but should not happen very often */ \
509  wait_io(stack, fd, op); \
510  TASK_YIELD; \
511  /* TASK_DELAY(1.0); */ \
512  } \
513  }
514 
515 /* Unlock a fd */
516 #define UNLOCK_FD(fd, op) unlock_fd(fd, stack, op)
517 
518 #define IF_CHANGED(DESIRED, CURRENT, TRUE_ACTION, FALSE_ACTION) \
519  { \
520  int _expr = DESIRED; \
521  if (_expr != (CURRENT)) { \
522  DBGOUT(FN; STRLIT("need change: "); NDBG(DESIRED, d); \
523  NDBG(CURRENT, d);); \
524  changed = 1; \
525  if (_expr) { \
526  DBGOUT(FN; STRLIT(#TRUE_ACTION " because: " #DESIRED " == TRUE");); \
527  TRUE_ACTION; \
528  } else { \
529  DBGOUT(FN; STRLIT(#FALSE_ACTION " because: " #DESIRED " == FALSE");); \
530  FALSE_ACTION; \
531  } \
532  } \
533  }
534 
535 #define IF_GUARD(DESIRED, GUARD, TRUE_ACTION, FALSE_ACTION) \
536  { \
537  int _expr = DESIRED; \
538  if (GUARD) { \
539  DBGOUT(FN; STRLIT("need change: "); NDBG(DESIRED, d); NDBG(GUARD, d);); \
540  changed = 1; \
541  if (_expr) { \
542  DBGOUT(FN; STRLIT(#TRUE_ACTION " because: " #DESIRED " == TRUE");); \
543  TRUE_ACTION; \
544  } else { \
545  DBGOUT(FN; STRLIT(#FALSE_ACTION " because: " #DESIRED " == FALSE");); \
546  FALSE_ACTION; \
547  } \
548  } \
549  }
550 
551 #ifndef mcm_close
552 #define mcm_close(x) close(x)
553 #endif
554 
555 #ifdef TASK_EVENT_TRACE
556 struct task_event {
557  task_arg arg;
558  int pad;
559 };
560 
561 typedef struct task_event task_event;
562 
563 #define MAX_TASK_EVENT 1000000
564 
565 void add_event(task_arg te);
566 void add_unpad_event(task_arg te);
567 void add_task_event(double when, char const *file, int state, char const *what);
568 void add_wait_event(double when, char const *file, int state, char const *what,
569  int milli);
570 void dump_task_events();
571 #endif
572 
573 /* The current task */
574 extern task_env *stack;
575 
576 extern void *task_allocate(task_env *p, unsigned int bytes);
577 extern void reset_state(task_env *p);
578 extern void pushp(task_env *p, void *ptr);
579 extern void popp(task_env *p);
580 
581 extern double seconds(); /* Return time as double */
582 extern double task_now(); /* Return result of last call to seconds() */
583 extern void task_delay_until(double time);
584 
585 extern int unblock_fd(int fd);
586 extern int block_fd(int fd);
587 extern int connect_tcp(char *server, xcom_port port, int *ret);
589 extern int accept_tcp(int fd, int *ret);
590 
591 extern int task_read(connection_descriptor const *con, void *buf, int n,
592  int64_t *ret);
593 extern int task_write(connection_descriptor const *con, void *buf, uint32_t n,
594  int64_t *ret);
595 extern int is_locked(int fd);
596 extern int lock_fd(int fd, task_env *t, int lock);
597 extern int unlock_fd(int fd, task_env *t, int lock);
598 
599 extern void task_sys_init();
600 extern task_env *task_new(task_func func, task_arg arg, const char *name,
601  int debug);
602 #define xstr(s) #s
603 /* #define task_new(func, arg) _task_new(func, arg, __FILE__":" xstr(__LINE__))
604  */
605 extern void task_loop();
606 extern void task_wait(task_env *t, linkage *queue);
607 extern void task_wakeup(linkage *queue);
608 extern task_env *task_terminate(task_env *t);
609 extern int is_running(task_env *t);
610 extern void set_task(task_env **p, task_env *t);
611 extern void task_terminate_all();
612 extern void remove_and_wakeup(int i);
613 extern int task_errno;
614 extern int is_only_task();
615 extern task_env *task_activate(task_env *t);
616 extern task_env *task_deactivate(task_env *t);
617 extern const char *task_name();
618 extern task_env *wait_io(task_env *t, int fd, int op);
619 
620 extern result con_read(connection_descriptor const *rfd, void *buf, int n);
621 extern result con_write(connection_descriptor const *wfd, void *buf, int n);
622 extern result set_nodelay(int fd);
623 
624 /* Use SSL ? */
625 void xcom_enable_ssl();
626 void xcom_disable_ssl();
627 
628 #ifdef __cplusplus
629 }
630 #endif
631 
632 #endif
task_activate
task_env * task_activate(task_env *t)
Definition: task.c:730
set_float_arg
static void set_float_arg(task_arg *arg, float value)
Definition: task.h:125
set_nodelay
result set_nodelay(int fd)
Definition: task.c:1334
task_env::heap_pos
int heap_pos
Definition: task.h:239
task_delay_until
void task_delay_until(double time)
Definition: task.c:562
queue
static QUEUE queue
Definition: myisampack.cc:206
channel_put
void channel_put(channel *c, linkage *data)
Definition: task.c:611
task_env::buf
TaskAlign buf[TASK_POOL_ELEMS]
Definition: task.h:255
announce_tcp
result announce_tcp(xcom_port port)
Definition: task.c:1458
task_read
int task_read(connection_descriptor const *con, void *buf, int n, int64_t *ret)
Definition: task.c:936
a_uint
@ a_uint
Definition: task_arg.h:34
a_float
@ a_float
Definition: task_arg.h:37
task_now
double task_now()
Definition: task.c:306
task_env::RUN
@ RUN
Definition: task.h:242
double_arg
static task_arg double_arg(double i)
Definition: task.h:189
task_arg::u_l
unsigned long u_l
Definition: task_arg.h:51
my_compiler.h
task_env::stack_top
TaskAlign * stack_top
Definition: task.h:252
task_env::name
const char * name
Definition: task.h:250
TASK_POOL_ELEMS
#define TASK_POOL_ELEMS
Definition: task.h:228
task_func
int(* task_func)(task_arg arg)
Definition: task.h:224
task_env::KILL
@ KILL
Definition: task.h:243
end_arg
static task_arg end_arg()
Definition: task.h:207
task_wait
void task_wait(task_env *t, linkage *queue)
Definition: task.c:570
task_queue::curn
int curn
Definition: task.h:267
task_allocate
void * task_allocate(task_env *p, unsigned int bytes)
Allocate bytes from pool, initialized to zero.
Definition: task.c:644
popp
void popp(task_env *p)
Definition: task.c:682
get_int_arg
static int get_int_arg(task_arg arg)
Definition: task.h:80
is_locked
int is_locked(int fd)
add_event
static char * add_event(const char *var, LEX_CSTRING event, const char *data, size_t data_length)
Definition: audit_null.cc:299
set_string_arg
static void set_string_arg(task_arg *arg, char const *value)
Definition: task.h:145
result
Definition: result.h:33
string_arg
static task_arg string_arg(char const *v)
Definition: task.h:195
task_arg.h
value
const string value("\"Value\"")
task_env::l
linkage l
Definition: task.h:237
task_arg::type
arg_type type
Definition: task_arg.h:46
task_env::terminate
enum task_env::@10 terminate
task_deactivate
task_env * task_deactivate(task_env *t)
Definition: task.c:732
a_ulong_long
@ a_ulong_long
Definition: task_arg.h:36
get_long_arg
static long get_long_arg(task_arg arg)
Definition: task.h:90
wait_io
task_env * wait_io(task_env *t, int fd, int op)
Definition: task.c:883
get_uint_arg
static unsigned int get_uint_arg(task_arg arg)
Definition: task.h:100
unblock_fd
int unblock_fd(int fd)
Definition: task.c:1053
task_env::TERMINATED
@ TERMINATED
Definition: task.h:244
a_void
@ a_void
Definition: task_arg.h:39
a_int
@ a_int
Definition: task_arg.h:32
xcom_port
unsigned short xcom_port
Definition: xcom_common.h:47
is_running
int is_running(task_env *t)
Definition: task.c:1633
xcom_disable_ssl
void xcom_disable_ssl()
set_void_arg
static void set_void_arg(task_arg *arg, void *value)
Definition: task.h:150
a_string
@ a_string
Definition: task_arg.h:40
reset_state
void reset_state(task_env *p)
Definition: task.c:662
task_arg::l
long l
Definition: task_arg.h:49
stack
task_env * stack
Definition: task.c:881
lock_fd
int lock_fd(int fd, task_env *t, int lock)
task_name
const char * task_name()
Definition: task.c:1642
a_end
@ a_end
Definition: task_arg.h:41
simset.h
result.h
set_double_arg
static void set_double_arg(task_arg *arg, double value)
Definition: task.h:135
uint_arg
static task_arg uint_arg(unsigned int i)
Definition: task.h:171
pushp
void pushp(task_env *p, void *ptr)
Definition: task.c:671
x_platform.h
linkage
Definition: simset.h:39
set_long_arg
static void set_long_arg(task_arg *arg, long value)
Definition: task.h:85
task_write
int task_write(connection_descriptor const *con, void *buf, uint32_t n, int64_t *ret)
Definition: task.c:1006
task_arg::s
const char * s
Definition: task_arg.h:55
xcom_profile.h
task_sys_init
void task_sys_init()
Definition: task.c:1614
task_env::waitfd
int waitfd
Definition: task.h:257
accept_tcp
int accept_tcp(int fd, int *ret)
Definition: task.c:1533
task_env::all
linkage all
Definition: task.h:238
port
static in_port_t port
Definition: testapp.c:33
get_ulong_long_arg
static unsigned long long get_ulong_long_arg(task_arg arg)
Definition: task.h:120
task_env::arg
task_arg arg
Definition: task.h:249
task_terminate_all
void task_terminate_all()
Definition: task.c:745
task_loop
void task_loop()
Definition: task.c:1110
task_env::time
double time
Definition: task.h:254
get_float_arg
static float get_float_arg(task_arg arg)
Definition: task.h:130
a_ulong
@ a_ulong
Definition: task_arg.h:35
task_ptr::ptr
void * ptr
Definition: task.h:216
ulong_long_arg
static task_arg ulong_long_arg(unsigned long long ll)
Definition: task.h:183
task_wakeup
void task_wakeup(linkage *queue)
Definition: task.c:578
task_arg::u_i
unsigned int u_i
Definition: task_arg.h:50
unlock_fd
int unlock_fd(int fd, task_env *t, int lock)
task_env::refcnt
int refcnt
Definition: task.h:246
task_env::debug
int debug
Definition: task.h:256
task_arg::u_ll
unsigned long long u_ll
Definition: task_arg.h:52
name
const string name("\"Name\"")
task_arg::d
double d
Definition: task_arg.h:54
task_env
Definition: task.h:236
set_ulong_arg
static void set_ulong_arg(task_arg *arg, unsigned long value)
Definition: task.h:105
remove_and_wakeup
void remove_and_wakeup(int i)
Definition: task.c:869
task_ptr
Definition: task.h:214
task_env::taskret
int taskret
Definition: task.h:247
task_arg::f
float f
Definition: task_arg.h:53
set_task
void set_task(task_env **p, task_env *t)
Definition: task.c:1636
get_ulong_arg
static unsigned long get_ulong_arg(task_arg arg)
Definition: task.h:115
MAXTASKS
#define MAXTASKS
Definition: task.h:263
xcom_common.h
a_double
@ a_double
Definition: task_arg.h:38
xcom_enable_ssl
void xcom_enable_ssl()
task_errno
int task_errno
Definition: task.c:122
channel::data
linkage data
Definition: task.h:431
task_env::interrupt
int interrupt
Definition: task.h:258
task_arg
Definition: task_arg.h:45
HttpMethod::type
int type
Definition: http_common.h:411
set_int_arg
static void set_int_arg(task_arg *arg, int value)
Definition: task.h:75
server
Definition: server_struct.h:42
get_void_arg
static void * get_void_arg(task_arg arg)
Definition: task.h:160
task_env::where
TaskAlign * where
Definition: task.h:251
channel_put_front
void channel_put_front(channel *c, linkage *data)
Definition: task.c:617
is_only_task
int is_only_task()
Definition: task.c:1090
a_long
@ a_long
Definition: task_arg.h:33
connect_tcp
int connect_tcp(char *server, xcom_port port, int *ret)
Definition: task.c:1215
channel_new
channel * channel_new()
Definition: task.c:604
con_write
result con_write(connection_descriptor const *wfd, void *buf, int n)
Definition: task.c:987
task_ptr::state
int state
Definition: task.h:215
block_fd
int block_fd(int fd)
Definition: task.c:1071
task_env::func
task_func func
Definition: task.h:248
channel::queue
linkage queue
Definition: task.h:432
get_string_arg
static const char * get_string_arg(task_arg arg)
Definition: task.h:155
task_new
task_env * task_new(task_func func, task_arg arg, const char *name, int debug)
Definition: task.c:623
seconds
double seconds()
Definition: task.c:298
n
int n
Definition: xcom_base.c:425
task_queue::x
task_env * x[MAXTASKS+1]
Definition: task.h:268
con_read
result con_read(connection_descriptor const *rfd, void *buf, int n)
Definition: task.c:918
task_env::sp
TaskAlign * sp
Definition: task.h:253
int_arg
static task_arg int_arg(int i)
Definition: task.h:165
channel_init
channel * channel_init(channel *c, unsigned int type)
Definition: task.c:597
node_connection.h
connection_descriptor
Definition: node_connection.h:48
channel
Definition: task.h:430
void_arg
static task_arg void_arg(void *v)
Definition: task.h:201
p
const char * p
Definition: ctype-mb.cc:1233
set_uint_arg
static void set_uint_arg(task_arg *arg, unsigned int value)
Definition: task.h:95
get_double_arg
static double get_double_arg(task_arg arg)
Definition: task.h:140
task_arg::i
int i
Definition: task_arg.h:48
set_ulong_long_arg
static void set_ulong_long_arg(task_arg *arg, unsigned long long value)
Definition: task.h:110
task_queue
Definition: task.h:266
task_terminate
task_env * task_terminate(task_env *t)
Definition: task.c:735
task_arg::v
void * v
Definition: task_arg.h:56
task_arg::val
union task_arg::@11 val
ulong_arg
static task_arg ulong_arg(unsigned long l)
Definition: task.h:177