ctkEAChannel_p.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*=============================================================================
  2. Library: CTK
  3. Copyright (c) German Cancer Research Center,
  4. Division of Medical and Biological Informatics
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. =============================================================================*/
  15. #ifndef CTKEACHANNEL_P_H
  16. #define CTKEACHANNEL_P_H
  17. class ctkEARunnable;
  18. /**
  19. * Main interface for buffers, queues, pipes, conduits, etc.
  20. * <p>
  21. * A ctkEAChannel represents anything that you can put items
  22. * into and take them out of. Both blocking (put(x), take),
  23. * and timeouts (offer(x, msecs), poll(msecs)) policies
  24. * are provided. Using a zero timeout for offer and poll
  25. * results in a pure balking policy.
  26. *
  27. * <p>
  28. * A given channel implementation might or might not have bounded
  29. * capacity or other insertion constraints, so in general,
  30. * you cannot tell if a given put will block.
  31. *
  32. * <p>
  33. * By design, the ctkEAChannel interface does not support any methods
  34. * to determine the current number of elements being held in the channel.
  35. * This decision reflects the fact that in concurrent programming,
  36. * such methods are so rarely useful that including them invites misuse;
  37. * at best they could provide a snapshot of current
  38. * state, that could change immediately after being reported.
  39. * It is better practice to instead use poll and offer to try
  40. * to take and put elements without blocking. For example,
  41. * to empty out the current contents of a channel, you could write:
  42. * \code
  43. * try
  44. * {
  45. * forever
  46. * {
  47. * ctkEARunnable* item = channel->poll(0);
  48. * if (item)
  49. * process(item);
  50. * else
  51. * break;
  52. * }
  53. * }
  54. * catch(const ctkEAInterruptedException& ex) { ... }
  55. * \endcode
  56. *
  57. * <p>
  58. * However, it is possible to determine whether an item
  59. * exists in a ctkEAChannel via <code>peek</code>, which returns
  60. * but does NOT remove the next item that can be taken (or null
  61. * if there is no such item). The peek operation has a limited
  62. * range of applicability, and must be used with care. Unless it
  63. * is known that a given thread is the only possible consumer
  64. * of a channel, and that no time-out-based <code>offer</code> operations
  65. * are ever invoked, there is no guarantee that the item returned
  66. * by peek will be available for a subsequent take.
  67. *
  68. * <p>
  69. * When appropriate, you can define an isEmpty method to
  70. * return whether <code>peek</code> returns null.
  71. *
  72. * <p>
  73. * Also, as a compromise, even though it does not appear in the interface,
  74. * implementation classes that can readily compute the number
  75. * of elements support a <code>size()</code> method. This allows careful
  76. * use, for example in queue length monitors, appropriate to the
  77. * particular implementation constraints and properties.
  78. *
  79. * <p>
  80. * All channels allow multiple producers and/or consumers.
  81. * They do not support any kind of <em>close</em> method
  82. * to shut down operation or indicate completion of particular
  83. * producer or consumer threads.
  84. * If you need to signal completion, one way to do it is to
  85. * create a class such as
  86. * \code
  87. * class EndOfStream : public ctkEARunnable
  88. * {
  89. * // Application-dependent field/methods
  90. * };
  91. * \endcode
  92. * And to have producers put an instance of this class into
  93. * the channel when they are done. The consumer side can then
  94. * check this via
  95. * \code
  96. * ctkEARunnable* x = aChannel->take();
  97. * if (dynamic_cast<EndOfStream*>(x))
  98. * // special actions; perhaps terminate
  99. * else
  100. * // process normally
  101. * \endcode
  102. *
  103. * <p>
  104. * In time-out based methods (poll(msecs) and offer(x, msecs),
  105. * time bounds are interpreted in
  106. * a coarse-grained, best-effort fashion. Since there is no
  107. * way to escape out of a wait for a mutex, time bounds
  108. * can sometimes be exceeded when there is a lot contention
  109. * for the channel. Additionally, some Channel semantics entail
  110. * a ``point of no return'' where, once some parts of the operation
  111. * have completed, others must follow, regardless of time bound.
  112. *
  113. * <p>
  114. * Interruptions are in general handled as early as possible
  115. * in all methods. Normally, ctkEAInterruptionExceptions are thrown
  116. * in put/take and offer(msec)/poll(msec) if interruption
  117. * is detected upon entry to the method, as well as in any
  118. * later context surrounding waits.
  119. *
  120. * <p>
  121. * If a put returns normally, an offer
  122. * returns true, or a put or poll returns non-null, the operation
  123. * completed successfully.
  124. * In all other cases, the operation fails cleanly -- the
  125. * element is not put or taken.
  126. *
  127. * The design of this class was inspired from:
  128. * http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html
  129. */
  130. struct ctkEAChannel
  131. {
  132. virtual ~ctkEAChannel() {}
  133. /**
  134. * Place item in the channel, possibly waiting indefinitely until
  135. * it can be accepted.
  136. *
  137. * @param item the element to be inserted. Should be non-null.
  138. * @throws ctkEAInterruptedException if the current thread has
  139. * been interrupted at a point at which interruption
  140. * is detected, in which case the element is guaranteed not
  141. * to be inserted. Otherwise, on normal return, the element is guaranteed
  142. * to have been inserted.
  143. */
  144. virtual void put(ctkEARunnable* item) = 0;
  145. /**
  146. * Place item in channel only if it can be accepted within
  147. * msecs milliseconds. The time bound is interpreted in
  148. * a coarse-grained, best-effort fashion.
  149. *
  150. * @param item the element to be inserted. Should be non-null.
  151. * @param msecs the number of milliseconds to wait. If less than
  152. * or equal to zero, the method does not perform any
  153. * timed waits, but might still require access to a
  154. * synchronization lock, which can impose unbounded
  155. * delay if there is a lot of contention for the channel.
  156. * @return true if accepted, else false
  157. * @throws ctkEAInterruptedException if the current thread has
  158. * been interrupted at a point at which interruption
  159. * is detected, in which case the element is guaranteed not
  160. * to be inserted (i.e., is equivalent to a false return).
  161. */
  162. virtual bool offer(ctkEARunnable* item, long msecs) = 0;
  163. /**
  164. * Return and remove an item from channel, possibly waiting
  165. * indefinitely until such an item exists.
  166. *
  167. * @return some item from the channel. Different implementations
  168. * may guarantee various properties (such as FIFO) about that item
  169. * @throws ctkEAInterruptedException if the current thread has
  170. * been interrupted at a point at which interruption
  171. * is detected, in which case state of the channel is unchanged.
  172. */
  173. virtual ctkEARunnable* take() = 0;
  174. /**
  175. * Return and remove an item from channel only if one is available within
  176. * msecs milliseconds. The time bound is interpreted in a coarse
  177. * grained, best-effort fashion.
  178. * @param msecs the number of milliseconds to wait. If less than
  179. * or equal to zero, the operation does not perform any timed waits,
  180. * but might still require access to a synchronization lock,
  181. * which can impose unbounded delay if there is a lot of contention
  182. * for the channel.
  183. * @return some item, or null if the channel is empty.
  184. * @throws ctkEAInterruptedException if the current thread has
  185. * been interrupted at a point at which interruption
  186. * is detected, in which case state of the channel is unchanged
  187. * (i.e., equivalent to a null return).
  188. */
  189. virtual ctkEARunnable* poll(long msecs) = 0;
  190. /**
  191. * Return, but do not remove object at head of Channel,
  192. * or null if it is empty.
  193. */
  194. virtual ctkEARunnable* peek() const = 0;
  195. };
  196. #endif // CTKEACHANNEL_P_H