lliopipe.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:9k
源码类别:

游戏引擎

开发平台:

C++ Builder

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