PageRenderTime 118ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmessage/lliopipe.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 317 lines | 114 code | 39 blank | 164 comment | 3 complexity | 6334325d40f151079ae1eb65d8ec4bdf MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lliopipe.h
  3. * @author Phoenix
  4. * @date 2004-11-18
  5. * @brief Declaration of base IO class
  6. *
  7. * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. #ifndef LL_LLIOPIPE_H
  29. #define LL_LLIOPIPE_H
  30. #include <boost/intrusive_ptr.hpp>
  31. #include <boost/shared_ptr.hpp>
  32. #include "apr_poll.h"
  33. #include "llsd.h"
  34. class LLIOPipe;
  35. class LLPumpIO;
  36. class LLBufferArray;
  37. class LLChannelDescriptors;
  38. // Debugging schmutz for deadlocks
  39. //#define LL_DEBUG_PUMPS
  40. #ifdef LL_DEBUG_PUMPS
  41. void pump_debug(const char *file, S32 line);
  42. #define PUMP_DEBUG pump_debug(__FILE__, __LINE__);
  43. #define END_PUMP_DEBUG pump_debug("none", 0);
  44. #else /* LL_DEBUG_PUMPS */
  45. #define PUMP_DEBUG
  46. #define END_PUMP_DEBUG
  47. #endif
  48. /**
  49. * intrusive pointer support
  50. */
  51. namespace boost
  52. {
  53. void intrusive_ptr_add_ref(LLIOPipe* p);
  54. void intrusive_ptr_release(LLIOPipe* p);
  55. };
  56. /**
  57. * @class LLIOPipe
  58. * @brief This class is an abstract base class for data processing units
  59. * @see LLPumpIO
  60. *
  61. * The LLIOPipe is a base class for implementing the basic non-blocking
  62. * processing of data subsystem in our system.
  63. *
  64. * Implementations of this class should behave like a stateful or
  65. * stateless signal processor. Each call to <code>process()</code>
  66. * hands the pipe implementation a buffer and a set of channels in the
  67. * buffer to process, and the pipe returns the status of the
  68. * operation. This is an abstract base class and developer created
  69. * concrete implementations provide block or stream based processing
  70. * of data to implement a particular protocol.
  71. */
  72. class LLIOPipe
  73. {
  74. public:
  75. /**
  76. * @brief I have decided that IO objects should have a reference
  77. * count. In general, you can pass bald LLIOPipe pointers around
  78. * as you need, but if you need to maintain a reference to one,
  79. * you need to hold a ptr_t.
  80. */
  81. typedef boost::intrusive_ptr<LLIOPipe> ptr_t;
  82. /**
  83. * @brief Scattered memory container.
  84. */
  85. typedef boost::shared_ptr<LLBufferArray> buffer_ptr_t;
  86. /**
  87. * @brief Enumeration for IO return codes
  88. *
  89. * A status code a positive integer value is considered a success,
  90. * but may indicate special handling for future calls, for
  91. * example, issuing a STATUS_STOP to an LLIOSocketReader instance
  92. * will tell the instance to stop reading the socket. A status
  93. * code with a negative value means that a problem has been
  94. * encountered which will require further action on the caller or
  95. * a developer to correct. Some mechanisms, such as the LLPumpIO
  96. * may depend on this definition of success and failure.
  97. */
  98. enum EStatus
  99. {
  100. // Processing occurred normally, future calls will be accepted.
  101. STATUS_OK = 0,
  102. // Processing occured normally, but stop unsolicited calls to
  103. // process.
  104. STATUS_STOP = 1,
  105. // This pipe is done with the processing. Future calls to
  106. // process will be accepted as long as new data is available.
  107. STATUS_DONE = 2,
  108. // This pipe is requesting that it become the head in a process.
  109. STATUS_BREAK = 3,
  110. // This pipe is requesting that it become the head in a process.
  111. STATUS_NEED_PROCESS = 4,
  112. // Keep track of the highest number of success codes here.
  113. STATUS_SUCCESS_COUNT = 5,
  114. // A generic error code.
  115. STATUS_ERROR = -1,
  116. // This method has not yet been implemented. This usually
  117. // indicates the programmer working on the pipe is not yet
  118. // done.
  119. STATUS_NOT_IMPLEMENTED = -2,
  120. // This indicates that a pipe precondition was not met. For
  121. // example, many pipes require an element to appear after them
  122. // in a chain (ie, mNext is not null) and will return this in
  123. // response to method calls. To recover from this, it will
  124. // require the caller to adjust the pipe state or may require
  125. // a dev to adjust the code to satisfy the preconditions.
  126. STATUS_PRECONDITION_NOT_MET = -3,
  127. // This means we could not connect to a remote host.
  128. STATUS_NO_CONNECTION = -4,
  129. // The connection was lost.
  130. STATUS_LOST_CONNECTION = -5,
  131. // The totoal process time has exceeded the timeout.
  132. STATUS_EXPIRED = -6,
  133. // Keep track of the count of codes here.
  134. STATUS_ERROR_COUNT = 6,
  135. };
  136. /**
  137. * @brief Helper function to check status.
  138. *
  139. * When writing code to check status codes, if you do not
  140. * specifically check a particular value, use this method for
  141. * checking an error condition.
  142. * @param status The status to check.
  143. * @return Returns true if the code indicates an error occurred.
  144. */
  145. inline static bool isError(EStatus status)
  146. {
  147. return ((S32)status < 0);
  148. }
  149. /**
  150. * @brief Helper function to check status.
  151. *
  152. * When writing code to check status codes, if you do not
  153. * specifically check a particular value, use this method for
  154. * checking an error condition.
  155. * @param status The status to check.
  156. * @return Returns true if the code indicates no error was generated.
  157. */
  158. inline static bool isSuccess(EStatus status)
  159. {
  160. return ((S32)status >= 0);
  161. }
  162. /**
  163. * @brief Helper function to turn status into a string.
  164. *
  165. * @param status The status to check.
  166. * @return Returns the name of the status code or empty string on failure.
  167. */
  168. static std::string lookupStatusString(EStatus status);
  169. /**
  170. * @brief Process the data in buffer.
  171. *
  172. * @param data The data processed
  173. * @param eos True if this function call is the last because end of stream.
  174. * @param pump The pump which is calling process. May be NULL.
  175. * @param context Shared meta-data for the process.
  176. * @return Returns a status code from the operation.
  177. */
  178. EStatus process(
  179. const LLChannelDescriptors& channels,
  180. buffer_ptr_t& buffer,
  181. bool& eos,
  182. LLSD& context,
  183. LLPumpIO* pump);
  184. /**
  185. * @brief Give this pipe a chance to handle a generated error
  186. *
  187. * If this pipe is in a chain being processed by a pump, and one
  188. * of the pipes generates an error, the pump will rewind through
  189. * the chain to see if any of the links can handle the error. For
  190. * example, if a connection is refused in a socket connection, the
  191. * socket client can try to find a new destination host. Return an
  192. * error code if this pipe does not handle the error passed in.
  193. * @param status The status code for the error
  194. * @param pump The pump which was calling process before the error
  195. * was generated.
  196. * @return Returns a status code from the operation. Returns an
  197. * error code if the error passed in was not handled. Returns
  198. * STATUS_OK to indicate the error has been handled.
  199. */
  200. virtual EStatus handleError(EStatus status, LLPumpIO* pump);
  201. /**
  202. * @brief Base Destructor - do not call <code>delete</code> directly.
  203. */
  204. virtual ~LLIOPipe();
  205. virtual bool isValid() ;
  206. protected:
  207. /**
  208. * @brief Base Constructor.
  209. */
  210. LLIOPipe();
  211. /**
  212. * @brief Process the data in buffer
  213. */
  214. virtual EStatus process_impl(
  215. const LLChannelDescriptors& channels,
  216. buffer_ptr_t& buffer,
  217. bool& eos,
  218. LLSD& context,
  219. LLPumpIO* pump) = 0;
  220. private:
  221. friend void boost::intrusive_ptr_add_ref(LLIOPipe* p);
  222. friend void boost::intrusive_ptr_release(LLIOPipe* p);
  223. U32 mReferenceCount;
  224. };
  225. namespace boost
  226. {
  227. inline void intrusive_ptr_add_ref(LLIOPipe* p)
  228. {
  229. ++p->mReferenceCount;
  230. }
  231. inline void intrusive_ptr_release(LLIOPipe* p)
  232. {
  233. if(p && 0 == --p->mReferenceCount)
  234. {
  235. delete p;
  236. }
  237. }
  238. };
  239. #if 0
  240. /**
  241. * @class LLIOBoiler
  242. * @brief This class helps construct new LLIOPipe specializations
  243. * @see LLIOPipe
  244. *
  245. * THOROUGH_DESCRIPTION
  246. */
  247. class LLIOBoiler : public LLIOPipe
  248. {
  249. public:
  250. LLIOBoiler();
  251. virtual ~LLIOBoiler();
  252. protected:
  253. /* @name LLIOPipe virtual implementations
  254. */
  255. //@{
  256. /**
  257. * @brief Process the data in buffer
  258. */
  259. virtual EStatus process_impl(
  260. const LLChannelDescriptors& channels,
  261. buffer_ptr_t& buffer,
  262. bool& eos,
  263. LLSD& context,
  264. LLPumpIO* pump);
  265. //@}
  266. };
  267. // virtual
  268. LLIOPipe::EStatus process_impl(
  269. const LLChannelDescriptors& channels,
  270. buffer_ptr_t& buffer,
  271. bool& eos,
  272. LLSD& context,
  273. LLPumpIO* pump)
  274. {
  275. return STATUS_NOT_IMPLEMENTED;
  276. }
  277. #endif // #if 0 - use this block as a boilerplate
  278. #endif // LL_LLIOPIPE_H