123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- /**
- * @file lliopipe.h
- * @author Phoenix
- * @date 2004-11-18
- * @brief Declaration of base IO class
- *
- * $LicenseInfo:firstyear=2004&license=viewergpl$
- *
- * Copyright (c) 2004-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #ifndef LL_LLIOPIPE_H
- #define LL_LLIOPIPE_H
- #include "llwin32headerslean.h"
- #include <memory>
- #include "boost/intrusive_ptr.hpp"
- #include "apr_poll.h"
- #include "llpreprocessor.h"
- #include "llsd.h"
- class LLIOPipe;
- class LLPumpIO;
- class LLBufferArray;
- class LLChannelDescriptors;
- // Debugging schmutz for deadlocks
- //#define LL_DEBUG_PUMPS
- #ifdef LL_DEBUG_PUMPS
- void pump_debug(const char *file, S32 line);
- #define PUMP_DEBUG pump_debug(__FILE__, __LINE__);
- #define END_PUMP_DEBUG pump_debug("none", 0);
- #else /* LL_DEBUG_PUMPS */
- #define PUMP_DEBUG
- #define END_PUMP_DEBUG
- #endif
- /**
- * intrusive pointer support
- */
- void intrusive_ptr_add_ref(LLIOPipe* p);
- void intrusive_ptr_release(LLIOPipe* p);
- /**
- * @class LLIOPipe
- * @brief This class is an abstract base class for data processing units
- * @see LLPumpIO
- *
- * The LLIOPipe is a base class for implementing the basic non-blocking
- * processing of data subsystem in our system.
- *
- * Implementations of this class should behave like a stateful or
- * stateless signal processor. Each call to <code>process()</code>
- * hands the pipe implementation a buffer and a set of channels in the
- * buffer to process, and the pipe returns the status of the
- * operation. This is an abstract base class and developer created
- * concrete implementations provide block or stream based processing
- * of data to implement a particular protocol.
- */
- class LLIOPipe
- {
- public:
- /**
- * @brief I have decided that IO objects should have a reference
- * count. In general, you can pass bald LLIOPipe pointers around
- * as you need, but if you need to maintain a reference to one,
- * you need to hold a ptr_t.
- */
- typedef boost::intrusive_ptr<LLIOPipe> ptr_t;
- /**
- * @brief Scattered memory container.
- */
- typedef std::shared_ptr<LLBufferArray> buffer_ptr_t;
- /**
- * @brief Enumeration for IO return codes
- *
- * A status code a positive integer value is considered a success,
- * but may indicate special handling for future calls, for
- * example, issuing a STATUS_STOP to an LLIOSocketReader instance
- * will tell the instance to stop reading the socket. A status
- * code with a negative value means that a problem has been
- * encountered which will require further action on the caller or
- * a developer to correct. Some mechanisms, such as the LLPumpIO
- * may depend on this definition of success and failure.
- */
- enum EStatus
- {
- // Processing occurred normally, future calls will be accepted.
- STATUS_OK = 0,
- // Processing occured normally, but stop unsolicited calls to
- // process.
- STATUS_STOP = 1,
- // This pipe is done with the processing. Future calls to
- // process will be accepted as long as new data is available.
- STATUS_DONE = 2,
- // This pipe is requesting that it become the head in a process.
- STATUS_BREAK = 3,
- // This pipe is requesting that it become the head in a process.
- STATUS_NEED_PROCESS = 4,
- // Keep track of the highest number of success codes here.
- STATUS_SUCCESS_COUNT = 5,
- // A generic error code.
- STATUS_ERROR = -1,
- // This method has not yet been implemented. This usually
- // indicates the programmer working on the pipe is not yet
- // done.
- STATUS_NOT_IMPLEMENTED = -2,
- // This indicates that a pipe precondition was not met. For
- // example, many pipes require an element to appear after them
- // in a chain (ie, mNext is not null) and will return this in
- // response to method calls. To recover from this, it will
- // require the caller to adjust the pipe state or may require
- // a dev to adjust the code to satisfy the preconditions.
- STATUS_PRECONDITION_NOT_MET = -3,
- // This means we could not connect to a remote host.
- STATUS_NO_CONNECTION = -4,
- // The connection was lost.
- STATUS_LOST_CONNECTION = -5,
- // The totoal process time has exceeded the timeout.
- STATUS_EXPIRED = -6,
- // Keep track of the count of codes here.
- STATUS_ERROR_COUNT = 6,
- };
- /**
- * @brief Helper function to check status.
- *
- * When writing code to check status codes, if you do not
- * specifically check a particular value, use this method for
- * checking an error condition.
- * @param status The status to check.
- * @return Returns true if the code indicates an error occurred.
- */
- LL_INLINE static bool isError(EStatus status)
- {
- return (S32)status < 0;
- }
- /**
- * @brief Helper function to check status.
- *
- * When writing code to check status codes, if you do not
- * specifically check a particular value, use this method for
- * checking an error condition.
- * @param status The status to check.
- * @return Returns true if the code indicates no error was generated.
- */
- LL_INLINE static bool isSuccess(EStatus status)
- {
- return (S32)status >= 0;
- }
- /**
- * @brief Helper function to turn status into a string.
- *
- * @param status The status to check.
- * @return Returns the name of the status code or empty string on failure.
- */
- static std::string lookupStatusString(EStatus status);
- /**
- * @brief Process the data in buffer.
- *
- * @param data The data processed
- * @param eos True if this function call is the last because end of stream.
- * @param pump The pump which is calling process. May be NULL.
- * @param context Shared meta-data for the process.
- * @return Returns a status code from the operation.
- */
- EStatus process(const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer, bool& eos,
- LLSD& context, LLPumpIO* pump);
- /**
- * @brief Give this pipe a chance to handle a generated error
- *
- * If this pipe is in a chain being processed by a pump, and one
- * of the pipes generates an error, the pump will rewind through
- * the chain to see if any of the links can handle the error. For
- * example, if a connection is refused in a socket connection, the
- * socket client can try to find a new destination host. Return an
- * error code if this pipe does not handle the error passed in.
- * @param status The status code for the error
- * @param pump The pump which was calling process before the error
- * was generated.
- * @return Returns a status code from the operation. Returns an
- * error code if the error passed in was not handled. Returns
- * STATUS_OK to indicate the error has been handled.
- */
- virtual EStatus handleError(EStatus status, LLPumpIO* pump);
- /**
- * @brief Base Destructor - do not call <code>delete</code> directly.
- */
- virtual ~LLIOPipe();
- virtual bool isValid();
- protected:
- /**
- * @brief Base Constructor.
- */
- LLIOPipe();
- /**
- * @brief Process the data in buffer
- */
- virtual EStatus process_impl(const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer, bool& eos,
- LLSD& context, LLPumpIO* pump) = 0;
- private:
- friend void intrusive_ptr_add_ref(LLIOPipe* p);
- friend void intrusive_ptr_release(LLIOPipe* p);
- U32 mReferenceCount;
- };
- LL_INLINE void intrusive_ptr_add_ref(LLIOPipe* p)
- {
- ++p->mReferenceCount;
- }
- LL_INLINE void intrusive_ptr_release(LLIOPipe* p)
- {
- if (p && 0 == --p->mReferenceCount)
- {
- delete p;
- }
- }
- #if 0
- /**
- * @class LLIOBoiler
- * @brief This class helps construct new LLIOPipe specializations
- * @see LLIOPipe
- *
- * THOROUGH_DESCRIPTION
- */
- class LLIOBoiler : public LLIOPipe
- {
- public:
- LLIOBoiler();
- virtual ~LLIOBoiler();
- protected:
- /* @name LLIOPipe virtual implementations
- */
- //@{
- /**
- * @brief Process the data in buffer
- */
- virtual EStatus process_impl(const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer, bool& eos,
- LLSD& context, LLPumpIO* pump);
- //@}
- };
- // virtual
- LLIOPipe::EStatus process_impl(const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer, bool& eos,
- LLSD& context, LLPumpIO* pump)
- {
- return STATUS_NOT_IMPLEMENTED;
- }
- #endif // #if 0 - use this block as a boilerplate
- #endif // LL_LLIOPIPE_H
|