123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677 |
- /**
- * @file lltransfermanager.h
- * @brief Improved transfer mechanism for moving data through the
- * message system.
- *
- * $LicenseInfo:firstyear=2006&license=viewergpl$
- *
- * Copyright (c) 2006-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_LLTRANSFERMANAGER_H
- #define LL_LLTRANSFERMANAGER_H
- #include <list>
- #include <map>
- #include "llassettype.h"
- #include "llhost.h"
- #include "lluuid.h"
- class LLDataPacker;
- class LLMessageSystem;
- class LLTransferConnection;
- class LLTransferSourceChannel;
- class LLTransferSourceParams;
- class LLTransferTargetChannel;
- class LLTransferTargetParams;
- class LLTransferSource;
- class LLTransferTarget;
- ///////////////////////////////////////////////////////////////////////////////
- // Priority queue map. This used to be in llcommon/llpriqueuemap.h, but was
- // only included from this header and is only used by LLTransferManager, so I
- // moved it here, where it belongs. HB
- ///////////////////////////////////////////////////////////////////////////////
- // Priority queue, implemented under the hood as a map. Needs to be done this
- // way because none of the standard STL containers provide a representation
- // where it is easy to reprioritize.
- template <class DATA>
- class LLPQMKey
- {
- public:
- LL_INLINE LLPQMKey(F32 priority, DATA data)
- : mPriority(priority),
- mData(data)
- {
- }
- LL_INLINE bool operator<(const LLPQMKey& b) const
- {
- if (mPriority > b.mPriority)
- {
- return true;
- }
- if (mPriority < b.mPriority)
- {
- return false;
- }
- if (mData > b.mData)
- {
- return true;
- }
- return false;
- }
- public:
- DATA mData;
- F32 mPriority;
- };
- template <class DATA_TYPE>
- class LLPriQueueMap
- {
- protected:
- LOG_CLASS(LLPriQueueMap);
- public:
- typedef typename std::map<LLPQMKey<DATA_TYPE>, DATA_TYPE>::iterator pqm_iter;
- typedef void (*set_pri_fn)(DATA_TYPE& data, F32 priority);
- typedef F32 (*get_pri_fn)(DATA_TYPE& data);
- LLPriQueueMap(set_pri_fn set_pri, get_pri_fn get_pri)
- : mSetPriority(set_pri),
- mGetPriority(get_pri)
- {
- }
- void push(F32 priority, DATA_TYPE data)
- {
- #if LL_DEBUG
- pqm_iter iter = mMap.find(LLPQMKey<DATA_TYPE>(priority, data));
- if (iter != mMap.end())
- {
- llerrs << "Pushing already existing data onto queue !" << llendl;
- }
- #endif
- mMap.emplace(LLPQMKey<DATA_TYPE>(priority, data), data);
- }
- bool pop(DATA_TYPE* datap)
- {
- pqm_iter iter;
- iter = mMap.begin();
- if (iter == mMap.end())
- {
- return false;
- }
- *datap = iter->second;
- mMap.erase(iter);
- return true;
- }
- void reprioritize(F32 new_priority, DATA_TYPE data)
- {
- pqm_iter iter;
- F32 cur_priority = mGetPriority(data);
- LLPQMKey<DATA_TYPE> cur_key(cur_priority, data);
- iter = mMap.find(cur_key);
- if (iter == mMap.end())
- {
- llwarns << "Data not on priority queue !" << llendl;
- // OK, try iterating through all of the data and seeing if we just
- // screwed up the priority somehow.
- for (iter = mMap.begin(); iter != mMap.end(); ++iter)
- {
- if (iter->second == data)
- {
- llerrs << "Data on priority queue but priority not matched !"
- << llendl;
- }
- }
- return;
- }
- mMap.erase(iter);
- mSetPriority(data, new_priority);
- push(new_priority, data);
- }
- LL_INLINE S32 getLength() const { return (S32)mMap.size(); }
- public:
- // *HACK: public for use by the transfer manager, ugh.
- std::map<LLPQMKey<DATA_TYPE>, DATA_TYPE> mMap;
- protected:
- void (*mSetPriority)(DATA_TYPE &data, F32 priority);
- F32 (*mGetPriority)(DATA_TYPE &data);
- };
- ///////////////////////////////////////////////////////////////////////////////
- // LLTransferManager
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Definition of the manager class for the new LLXfer replacement.
- // Provides prioritized, bandwidth-throttled transport of arbitrary
- // binary data between host/circuit combos
- //
- typedef enum e_transfer_channel_type
- {
- LLTCT_UNKNOWN = 0,
- LLTCT_MISC,
- LLTCT_ASSET,
- LLTCT_NUM_TYPES
- } LLTransferChannelType;
- typedef enum e_transfer_source_type
- {
- LLTST_UNKNOWN = 0,
- LLTST_FILE,
- LLTST_ASSET,
- LLTST_SIM_INV_ITEM, // Simulator specific, may not be handled
- LLTST_SIM_ESTATE, // Simulator specific, may not be handled
- LLTST_NUM_TYPES
- } LLTransferSourceType;
- typedef enum e_transfer_target_type
- {
- LLTTT_UNKNOWN = 0,
- LLTTT_FILE,
- LLTTT_VFILE,
- LLTTT_NUM_TYPES
- } LLTransferTargetType;
- // Errors are negative, expected values are positive.
- typedef enum e_status_codes
- {
- LLTS_OK = 0,
- LLTS_DONE = 1,
- LLTS_SKIP = 2,
- LLTS_ABORT = 3,
- LLTS_ERROR = -1,
- LLTS_UNKNOWN_SOURCE = -2, // Equivalent of a 404
- LLTS_INSUFFICIENT_PERMISSIONS = -3 // Not enough permissions
- } LLTSCode;
- // Types of requests for estate wide information
- typedef enum e_estate_type
- {
- ET_Covenant = 0,
- ET_NONE = -1
- } EstateAssetType;
- class LLTransferManager
- {
- protected:
- LOG_CLASS(LLTransferManager);
- public:
- LLTransferManager();
- virtual ~LLTransferManager();
- void init();
- void cleanup();
- // Called per frame to push packets out on the various different channels.
- void updateTransfers();
- void cleanupConnection(const LLHost& host);
- LLTransferSourceChannel* getSourceChannel(const LLHost& host,
- LLTransferChannelType stype);
- LLTransferTargetChannel* getTargetChannel(const LLHost& host,
- LLTransferChannelType stype);
- LLTransferSource* findTransferSource(const LLUUID& transfer_id);
- LL_INLINE bool isValid() const { return mValid; }
- static void processTransferRequest(LLMessageSystem* mesgsys, void**);
- static void processTransferInfo(LLMessageSystem* mesgsys, void**);
- static void processTransferPacket(LLMessageSystem* mesgsys, void**);
- static void processTransferAbort(LLMessageSystem* mesgsys, void**);
- static void reliablePacketCallback(void**, S32 result);
- LL_INLINE S32 getTransferBitsIn(LLTransferChannelType tctype) const
- {
- return mTransferBitsIn[tctype];
- }
- LL_INLINE S32 getTransferBitsOut(LLTransferChannelType tctype) const
- {
- return mTransferBitsOut[tctype];
- }
- LL_INLINE void resetTransferBitsIn(LLTransferChannelType tctype)
- {
- mTransferBitsIn[tctype] = 0;
- }
- LL_INLINE void resetTransferBitsOut(LLTransferChannelType tctype)
- {
- mTransferBitsOut[tctype] = 0;
- }
- LL_INLINE void addTransferBitsIn(LLTransferChannelType tctype, S32 bits)
- {
- mTransferBitsIn[tctype] += bits;
- }
- LL_INLINE void addTransferBitsOut(LLTransferChannelType tctype, S32 bits)
- {
- mTransferBitsOut[tctype] += bits;
- }
- protected:
- LLTransferConnection* getTransferConnection(const LLHost& host);
- protected:
- // Convenient typedefs
- typedef std::map<LLHost, LLTransferConnection*> host_tc_map;
- // We keep a map between each host and LLTransferConnection.
- host_tc_map mTransferConnections;
- LLHost mHost;
- S32 mTransferBitsIn[LLTTT_NUM_TYPES];
- S32 mTransferBitsOut[LLTTT_NUM_TYPES];
- bool mValid;
- };
- //
- // Keeps tracks of all channels to/from a particular host.
- //
- class LLTransferConnection
- {
- friend class LLTransferManager;
- protected:
- LOG_CLASS(LLTransferConnection);
- public:
- LLTransferConnection(const LLHost& host);
- virtual ~LLTransferConnection();
- void updateTransfers();
- LLTransferSourceChannel* getSourceChannel(LLTransferChannelType type);
- LLTransferTargetChannel* getTargetChannel(LLTransferChannelType type);
- // Convenient typedefs
- typedef std::list<LLTransferSourceChannel*>::iterator tsc_iter;
- typedef std::list<LLTransferTargetChannel*>::iterator ttc_iter;
- protected:
- std::list<LLTransferSourceChannel*> mTransferSourceChannels;
- std::list<LLTransferTargetChannel*> mTransferTargetChannels;
- LLHost mHost;
- };
- //
- // A channel which is pushing data out.
- //
- class LLTransferSourceChannel
- {
- protected:
- LOG_CLASS(LLTransferSourceChannel);
- typedef std::list<LLTransferSource*>::iterator ts_iter;
- public:
- LLTransferSourceChannel(LLTransferChannelType type, const LLHost& host);
- virtual ~LLTransferSourceChannel();
- void updateTransfers();
- void updatePriority(LLTransferSource* tsp, F32 priority);
- void addTransferSource(LLTransferSource* sourcep);
- LLTransferSource* findTransferSource(const LLUUID& transfer_id);
- void deleteTransfer(LLTransferSource* tsp);
- LL_INLINE void setThrottleID(S32 throttle_id) { mThrottleID = throttle_id; }
- LL_INLINE LLTransferChannelType getChannelType() const { return mChannelType; }
- LL_INLINE LLHost getHost() const { return mHost; }
- protected:
- LLPriQueueMap<LLTransferSource*> mTransferSources;
- LLHost mHost;
- LLTransferChannelType mChannelType;
- // The throttle that this source channel should use
- S32 mThrottleID;
- };
- //
- // A channel receiving data from a source.
- //
- class LLTransferTargetChannel
- {
- friend class LLTransferTarget;
- friend class LLTransferManager;
- protected:
- LOG_CLASS(LLTransferTargetChannel);
- public:
- LLTransferTargetChannel(LLTransferChannelType type, const LLHost& host);
- virtual ~LLTransferTargetChannel();
- void requestTransfer(const LLTransferSourceParams& source_params,
- const LLTransferTargetParams& target_params,
- F32 priority);
- LLTransferTarget* findTransferTarget(const LLUUID& transfer_id);
- void deleteTransfer(LLTransferTarget* ttp);
- LL_INLINE LLTransferChannelType getChannelType() const { return mChannelType; }
- LL_INLINE LLHost getHost() const { return mHost; }
- protected:
- void sendTransferRequest(LLTransferTarget* targetp,
- const LLTransferSourceParams& params,
- F32 priority);
- void addTransferTarget(LLTransferTarget* targetp);
- protected:
- typedef std::list<LLTransferTarget*>::iterator tt_iter;
- std::list<LLTransferTarget*> mTransferTargets;
- LLHost mHost;
- LLTransferChannelType mChannelType;
- };
- class LLTransferSourceParams
- {
- protected:
- LOG_CLASS(LLTransferSourceParams);
- public:
- LLTransferSourceParams(LLTransferSourceType type)
- : mType(type)
- {
- }
- virtual ~LLTransferSourceParams() = default;
- virtual void packParams(LLDataPacker& dp) const = 0;
- virtual bool unpackParams(LLDataPacker& dp) = 0;
- LL_INLINE LLTransferSourceType getType() const { return mType; }
-
- protected:
- LLTransferSourceType mType;
- };
- //
- // LLTransferSource is an interface, all transfer sources should be derived
- // from it.
- //
- typedef LLTransferSource* (*LLTransferSourceCreateFunc)(const LLUUID& id,
- F32 priority);
- class LLTransferSource
- {
- protected:
- LOG_CLASS(LLTransferSource);
- public:
- LL_INLINE LLUUID getID() { return mID; }
- friend class LLTransferManager;
- friend class LLTransferSourceChannel;
- protected:
- LLTransferSource(LLTransferSourceType source_type,
- const LLUUID& request_id, F32 priority);
- virtual ~LLTransferSource() = default;
- // When you have figured out your transfer status, do this
- void sendTransferStatus(LLTSCode status);
- virtual void initTransfer() = 0;
- virtual F32 updatePriority() = 0;
- virtual LLTSCode dataCallback(S32 packet_id, S32 max_bytes,
- U8** datap, S32& returned_bytes,
- bool& delete_returned) = 0;
- // The completionCallback is GUARANTEED to be called before the destructor.
- virtual void completionCallback(LLTSCode status) = 0;
- virtual void packParams(LLDataPacker& dp) const = 0;
- virtual bool unpackParams(LLDataPacker& dp) = 0;
- LL_INLINE virtual S32 getNextPacketID() { return mLastPacketID + 1; }
- LL_INLINE virtual void setLastPacketID(S32 id) { mLastPacketID = id; }
- // For now, no self-induced priority changes
- LL_INLINE F32 getPriority() { return mPriority; }
- LL_INLINE void setPriority(F32 pri) { mPriority = pri; }
- // DON'T USE THIS ONE, used internally by LLTransferManager
- virtual void abortTransfer();
- static LLTransferSource* createSource(LLTransferSourceType stype,
- const LLUUID& request_id,
- F32 priority);
- static void registerSourceType(LLTransferSourceType stype,
- LLTransferSourceCreateFunc);
- static void sSetPriority(LLTransferSource*& tsp, F32 priority);
- static F32 sGetPriority(LLTransferSource*& tsp);
- protected:
- LLUUID mID;
- LLTransferSourceChannel* mChannelp;
- LLTransferSourceType mType;
- F32 mPriority;
- S32 mSize;
- S32 mLastPacketID;
- typedef std::map<LLTransferSourceType,
- LLTransferSourceCreateFunc> stype_scfunc_map;
- static stype_scfunc_map sSourceCreateMap;
- };
- class LLTransferTargetParams
- {
- protected:
- LOG_CLASS(LLTransferTargetParams);
- public:
- LLTransferTargetParams(LLTransferTargetType type)
- : mType(type)
- {
- }
- LL_INLINE LLTransferTargetType getType() const { return mType; }
- protected:
- LLTransferTargetType mType;
- };
- class LLTransferPacket
- {
- // Used for storing a packet that's being delivered later because it's out
- // of order. ONLY should be accessed by the following two classes, for now.
- friend class LLTransferTarget;
- friend class LLTransferManager;
- protected:
- LLTransferPacket(S32 packet_id, LLTSCode status, const U8* data, S32 size);
- virtual ~LLTransferPacket();
- protected:
- U8* mDatap;
- S32 mSize;
- S32 mPacketID;
- LLTSCode mStatus;
- };
- class LLTransferTarget
- {
- friend class LLTransferManager;
- friend class LLTransferTargetChannel;
- protected:
- LOG_CLASS(LLTransferTarget);
- public:
- LLTransferTarget(LLTransferTargetType target_type,
- const LLUUID& transfer_id,
- LLTransferSourceType source_type);
- virtual ~LLTransferTarget();
- // Accessors
- LL_INLINE LLUUID getID() const { return mID; }
- LL_INLINE LLTransferTargetType getType() const { return mType; }
- LL_INLINE LLTransferTargetChannel* getChannel() const { return mChannelp; }
- LL_INLINE LLTransferSourceType getSourceType() const { return mSourceType; }
- // Static functionality
- static LLTransferTarget* createTarget(LLTransferTargetType target_type,
- const LLUUID& request_id,
- LLTransferSourceType source_type);
- protected:
- // Implementation
- virtual bool unpackParams(LLDataPacker& dp) = 0;
- virtual void applyParams(const LLTransferTargetParams& params) = 0;
- virtual LLTSCode dataCallback(S32 packet_id, U8* in_datap,
- S32 in_size) = 0;
- // The completionCallback is GUARANTEED to be called before the destructor,
- // so all handling of errors/aborts should be done here.
- virtual void completionCallback(LLTSCode status) = 0;
- void abortTransfer();
- LL_INLINE virtual S32 getNextPacketID() { return mLastPacketID + 1; }
- LL_INLINE virtual void setLastPacketID(S32 id) { mLastPacketID =id; }
- LL_INLINE void setSize(S32 size) { mSize = size; }
- LL_INLINE void setGotInfo(bool got_info) { mGotInfo = got_info; }
- LL_INLINE bool gotInfo() const { return mGotInfo; }
- bool addDelayedPacket(S32 packet_id, LLTSCode status, U8* datap, S32 size);
- protected:
- typedef std::map<S32, LLTransferPacket*> transfer_packet_map;
- typedef std::map<S32, LLTransferPacket*>::iterator tpm_iter;
- LLTransferTargetType mType;
- LLTransferSourceType mSourceType;
- LLUUID mID;
- LLTransferTargetChannel* mChannelp;
- S32 mSize;
- S32 mLastPacketID;
- bool mGotInfo;
- // Packets that are waiting because of missing/out of order issues
- transfer_packet_map mDelayedPacketMap;
- };
- // Hack, here so it's publicly available even though LLTransferSourceInvItem is
- // only available on the simulator
- class LLTransferSourceParamsInvItem: public LLTransferSourceParams
- {
- protected:
- LOG_CLASS(LLTransferSourceParamsInvItem);
- public:
- LLTransferSourceParamsInvItem();
- void packParams(LLDataPacker& dp) const override;
- bool unpackParams(LLDataPacker& dp) override;
- void setAgentSession(const LLUUID& agent_id, const LLUUID& session_id);
- void setInvItem(const LLUUID& owner_id, const LLUUID& task_id,
- const LLUUID& item_id);
- void setAsset(const LLUUID& asset_id, LLAssetType::EType at);
- LL_INLINE LLUUID getAgentID() const { return mAgentID; }
- LL_INLINE LLUUID getSessionID() const { return mSessionID; }
- LL_INLINE LLUUID getOwnerID() const { return mOwnerID; }
- LL_INLINE LLUUID getTaskID() const { return mTaskID; }
- LL_INLINE LLUUID getItemID() const { return mItemID; }
- LL_INLINE LLUUID getAssetID() const { return mAssetID; }
- LL_INLINE LLAssetType::EType getAssetType() const { return mAssetType; }
- protected:
- LLUUID mAgentID;
- LLUUID mSessionID;
- LLUUID mOwnerID;
- LLUUID mTaskID;
- LLUUID mItemID;
- LLUUID mAssetID;
- LLAssetType::EType mAssetType;
- };
- // Hack, here so it is publicly available even though LLTransferSourceEstate is
- // only available on the simulator
- class LLTransferSourceParamsEstate: public LLTransferSourceParams
- {
- protected:
- LOG_CLASS(LLTransferSourceParamsEstate);
- public:
- LLTransferSourceParamsEstate();
- void packParams(LLDataPacker& dp) const override;
- bool unpackParams(LLDataPacker& dp) override;
- void setAgentSession(const LLUUID& agent_id, const LLUUID& session_id);
- void setEstateAssetType(EstateAssetType etype);
- void setAsset(const LLUUID& asset_id, LLAssetType::EType at);
- LL_INLINE LLUUID getAgentID() const { return mAgentID; }
- LL_INLINE LLUUID getSessionID() const { return mSessionID; }
- LL_INLINE EstateAssetType getEstateAssetType() const { return mEstateAssetType; }
- LL_INLINE LLUUID getAssetID() const { return mAssetID; }
- LL_INLINE LLAssetType::EType getAssetType() const { return mAssetType; }
- protected:
- LLUUID mAgentID;
- LLUUID mSessionID;
- // these are set on the sim based on estateinfotype
- LLUUID mAssetID;
- LLAssetType::EType mAssetType;
- EstateAssetType mEstateAssetType;
- };
- extern LLTransferManager gTransferManager;
- #endif//LL_LLTRANSFERMANAGER_H
|