io_plan.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /* Licensed under LGPLv2.1+ - see LICENSE file for details */
  2. #ifndef CCAN_IO_PLAN_H
  3. #define CCAN_IO_PLAN_H
  4. struct io_conn;
  5. /**
  6. * struct io_plan - a plan of what I/O to do.
  7. * @pollflag: POLLIN or POLLOUT.
  8. * @io: function to call when fd is available for @pollflag.
  9. * @next: function to call after @io returns true.
  10. * @next_arg: argument to @next.
  11. * @u1: scratch area for I/O.
  12. * @u2: scratch area for I/O.
  13. *
  14. * When the fd is POLLIN or POLLOUT (according to @pollflag), @io is
  15. * called. If it returns -1, io_close() becomed the new plan (and errno
  16. * is saved). If it returns 1, @next is called, otherwise @io is
  17. * called again when @pollflag is available.
  18. *
  19. * You can use this to write your own io_plan functions.
  20. */
  21. struct io_plan {
  22. int pollflag;
  23. /* Only NULL if idle. */
  24. int (*io)(int fd, struct io_plan *plan);
  25. /* Only NULL if closing. */
  26. struct io_plan (*next)(struct io_conn *, void *arg);
  27. void *next_arg;
  28. union {
  29. char *cp;
  30. void *vp;
  31. const void *const_vp;
  32. size_t s;
  33. char c[sizeof(size_t)];
  34. } u1;
  35. union {
  36. char *p;
  37. void *vp;
  38. const void *const_vp;
  39. size_t s;
  40. char c[sizeof(size_t)];
  41. } u2;
  42. };
  43. #ifdef DEBUG
  44. /**
  45. * io_debug_conn - routine to select connection(s) to debug.
  46. *
  47. * If this is set, the routine should return true if the connection is a
  48. * debugging candidate. If so, the callchain for I/O operations on this
  49. * connection will be linear, for easier use of a debugger.
  50. *
  51. * You will also see calls to any callbacks which wake the connection
  52. * which is being debugged.
  53. *
  54. * Example:
  55. * static bool debug_all(struct io_conn *conn)
  56. * {
  57. * return true();
  58. * }
  59. * ...
  60. * io_debug_conn = debug_all;
  61. */
  62. extern bool (*io_debug_conn)(struct io_conn *conn);
  63. /**
  64. * io_debug - if we're debugging the current connection, call immediately.
  65. *
  66. * This determines if we are debugging the current connection: if so,
  67. * it immediately applies the plan and calls back into io_loop() to
  68. * create a linear call chain.
  69. *
  70. * Example:
  71. * #define io_idle() io_debug(io_idle_())
  72. * struct io_plan io_idle_(void);
  73. */
  74. struct io_plan io_debug(struct io_plan plan);
  75. /**
  76. * io_debug_io - return from function which actually does I/O.
  77. *
  78. * This determines if we are debugging the current connection: if so,
  79. * it immediately sets the next function and calls into io_loop() to
  80. * create a linear call chain.
  81. *
  82. * Example:
  83. *
  84. * static int do_write(int fd, struct io_plan *plan)
  85. * {
  86. * ssize_t ret = write(fd, plan->u.write.buf, plan->u.write.len);
  87. * if (ret < 0)
  88. * return io_debug_io(-1);
  89. *
  90. * plan->u.write.buf += ret;
  91. * plan->u.write.len -= ret;
  92. * return io_debug_io(plan->u.write.len == 0);
  93. * }
  94. */
  95. int io_debug_io(int ret);
  96. /**
  97. * io_plan_no_debug - mark the next plan not to be called immediately.
  98. *
  99. * Most routines which take a plan are about to apply it to the current
  100. * connection. We (ab)use this pattern for debugging: as soon as such a
  101. * plan is created it is called, to create a linear call chain.
  102. *
  103. * Some routines, like io_break(), io_duplex() and io_wake() take an
  104. * io_plan, but they must not be applied immediately to the current
  105. * connection, so we call this first.
  106. *
  107. * Example:
  108. * #define io_break(ret, plan) (io_plan_no_debug(), io_break_((ret), (plan)))
  109. * struct io_plan io_break_(void *ret, struct io_plan plan);
  110. */
  111. #define io_plan_no_debug() ((io_plan_nodebug = true))
  112. extern bool io_plan_nodebug;
  113. #else
  114. static inline struct io_plan io_debug(struct io_plan plan)
  115. {
  116. return plan;
  117. }
  118. static inline int io_debug_io(int ret)
  119. {
  120. return ret;
  121. }
  122. #define io_plan_no_debug() (void)0
  123. #endif
  124. #endif /* CCAN_IO_PLAN_H */