PageRenderTime 43ms CodeModel.GetById 12ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llmessage/lltransfermanager.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 499 lines | 325 code | 112 blank | 62 comment | 0 complexity | 4dccf85ddbc014fbbc86791f85b5363f MD5 | raw file
  1/** 
  2 * @file lltransfermanager.h
  3 * @brief Improved transfer mechanism for moving data through the
  4 * message system.
  5 *
  6 * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  7 * Second Life Viewer Source Code
  8 * Copyright (C) 2010, Linden Research, Inc.
  9 * 
 10 * This library is free software; you can redistribute it and/or
 11 * modify it under the terms of the GNU Lesser General Public
 12 * License as published by the Free Software Foundation;
 13 * version 2.1 of the License only.
 14 * 
 15 * This library is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18 * Lesser General Public License for more details.
 19 * 
 20 * You should have received a copy of the GNU Lesser General Public
 21 * License along with this library; if not, write to the Free Software
 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 23 * 
 24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 25 * $/LicenseInfo$
 26 */
 27
 28#ifndef LL_LLTRANSFERMANAGER_H
 29#define LL_LLTRANSFERMANAGER_H
 30
 31#include <map>
 32#include <list>
 33
 34#include "llhost.h"
 35#include "lluuid.h"
 36#include "llthrottle.h"
 37#include "llpriqueuemap.h"
 38#include "llassettype.h"
 39
 40//
 41// Definition of the manager class for the new LLXfer replacement.
 42// Provides prioritized, bandwidth-throttled transport of arbitrary
 43// binary data between host/circuit combos
 44//
 45
 46
 47typedef enum e_transfer_channel_type
 48{
 49	LLTCT_UNKNOWN = 0,
 50	LLTCT_MISC,
 51	LLTCT_ASSET,
 52	LLTCT_NUM_TYPES
 53} LLTransferChannelType;
 54
 55
 56typedef enum e_transfer_source_type
 57{
 58	LLTST_UNKNOWN = 0,
 59	LLTST_FILE,
 60	LLTST_ASSET,
 61	LLTST_SIM_INV_ITEM,	// Simulator specific, may not be handled
 62	LLTST_SIM_ESTATE,	// Simulator specific, may not be handled
 63	LLTST_NUM_TYPES
 64} LLTransferSourceType;
 65
 66
 67typedef enum e_transfer_target_type
 68{
 69	LLTTT_UNKNOWN = 0,
 70	LLTTT_FILE,
 71	LLTTT_VFILE,
 72	LLTTT_NUM_TYPES
 73} LLTransferTargetType;
 74
 75
 76// Errors are negative, expected values are positive.
 77typedef enum e_status_codes
 78{
 79	LLTS_OK = 0,
 80	LLTS_DONE = 1,
 81	LLTS_SKIP = 2,
 82	LLTS_ABORT = 3,
 83	LLTS_ERROR = -1,
 84	LLTS_UNKNOWN_SOURCE = -2, // Equivalent of a 404
 85	LLTS_INSUFFICIENT_PERMISSIONS = -3	// Not enough permissions
 86} LLTSCode;
 87
 88// Types of requests for estate wide information
 89typedef enum e_estate_type
 90{
 91	ET_Covenant = 0,
 92	ET_NONE = -1
 93} EstateAssetType;
 94
 95class LLMessageSystem;
 96class LLDataPacker;
 97
 98class LLTransferConnection;
 99class LLTransferSourceChannel;
100class LLTransferTargetChannel;
101class LLTransferSourceParams;
102class LLTransferTargetParams;
103class LLTransferSource;
104class LLTransferTarget;
105
106class LLTransferManager
107{
108public:
109	LLTransferManager();
110	virtual ~LLTransferManager();
111
112	void init();
113	void cleanup();
114
115	void updateTransfers();	// Called per frame to push packets out on the various different channels.
116	void cleanupConnection(const LLHost &host);
117
118
119	LLTransferSourceChannel *getSourceChannel(const LLHost &host, const LLTransferChannelType stype);
120	LLTransferTargetChannel *getTargetChannel(const LLHost &host, const LLTransferChannelType stype);
121
122	LLTransferSource *findTransferSource(const LLUUID &transfer_id);
123
124	BOOL						isValid() const			{ return mValid; }
125
126	static void processTransferRequest(LLMessageSystem *mesgsys, void **);
127	static void processTransferInfo(LLMessageSystem *mesgsys, void **);
128	static void processTransferPacket(LLMessageSystem *mesgsys, void **);
129	static void processTransferAbort(LLMessageSystem *mesgsys, void **);
130
131	static void reliablePacketCallback(void **, S32 result);
132
133	S32	getTransferBitsIn(const LLTransferChannelType tctype) const		{ return mTransferBitsIn[tctype]; }
134	S32 getTransferBitsOut(const LLTransferChannelType tctype) const	{ return mTransferBitsOut[tctype]; }
135	void resetTransferBitsIn(const LLTransferChannelType tctype)		{ mTransferBitsIn[tctype] = 0; }
136	void resetTransferBitsOut(const LLTransferChannelType tctype)		{ mTransferBitsOut[tctype] = 0; }
137	void addTransferBitsIn(const LLTransferChannelType tctype, const S32 bits)	{ mTransferBitsIn[tctype] += bits; }
138	void addTransferBitsOut(const LLTransferChannelType tctype, const S32 bits)	{ mTransferBitsOut[tctype] += bits; }
139protected:
140	LLTransferConnection		*getTransferConnection(const LLHost &host);
141	BOOL						removeTransferConnection(const LLHost &host);
142
143protected:
144	// Convenient typedefs
145	typedef std::map<LLHost, LLTransferConnection *> host_tc_map;
146
147	BOOL	mValid;
148	LLHost	mHost;
149
150	S32		mTransferBitsIn[LLTTT_NUM_TYPES];
151	S32		mTransferBitsOut[LLTTT_NUM_TYPES];
152
153	// We keep a map between each host and LLTransferConnection.
154	host_tc_map mTransferConnections;
155};
156
157
158//
159// Keeps tracks of all channels to/from a particular host.
160//
161class LLTransferConnection
162{
163public:
164	LLTransferConnection(const LLHost &host);
165	virtual ~LLTransferConnection();
166
167	void updateTransfers();
168
169	LLTransferSourceChannel *getSourceChannel(const LLTransferChannelType type);
170	LLTransferTargetChannel *getTargetChannel(const LLTransferChannelType type);
171
172	// Convenient typedefs
173	typedef std::list<LLTransferSourceChannel *>::iterator tsc_iter;
174	typedef std::list<LLTransferTargetChannel *>::iterator ttc_iter;
175	friend class LLTransferManager;
176protected:
177
178	LLHost									mHost;
179	std::list<LLTransferSourceChannel *>	mTransferSourceChannels;
180	std::list<LLTransferTargetChannel *>	mTransferTargetChannels;
181
182};
183
184
185//
186// A channel which is pushing data out.
187//
188
189class LLTransferSourceChannel
190{
191public:
192	LLTransferSourceChannel(const LLTransferChannelType channel_type,
193							const LLHost &host);
194	virtual ~LLTransferSourceChannel();
195
196	void updateTransfers();
197
198	void updatePriority(LLTransferSource *tsp, const F32 priority);
199
200	void				addTransferSource(LLTransferSource *sourcep);
201	LLTransferSource	*findTransferSource(const LLUUID &transfer_id);
202	BOOL				deleteTransfer(LLTransferSource *tsp);
203
204	void					setThrottleID(const S32 throttle_id)	{ mThrottleID = throttle_id; }
205
206	LLTransferChannelType	getChannelType() const		{ return mChannelType; }
207	LLHost					getHost() const				{ return mHost; }
208
209protected:
210	typedef std::list<LLTransferSource *>::iterator ts_iter;
211
212	LLTransferChannelType				mChannelType;
213	LLHost								mHost;
214	LLPriQueueMap<LLTransferSource*>	mTransferSources;
215
216	// The throttle that this source channel should use
217	S32									mThrottleID;
218};
219
220
221//
222// A channel receiving data from a source.
223//
224class LLTransferTargetChannel
225{
226public:
227	LLTransferTargetChannel(const LLTransferChannelType channel_type, const LLHost &host);
228	virtual ~LLTransferTargetChannel();
229
230	void requestTransfer(const LLTransferSourceParams &source_params,
231						 const LLTransferTargetParams &target_params,
232						 const F32 priority);
233
234	LLTransferTarget		*findTransferTarget(const LLUUID &transfer_id);
235	BOOL					deleteTransfer(LLTransferTarget *ttp);
236
237
238	LLTransferChannelType	getChannelType() const		{ return mChannelType; }
239	LLHost					getHost() const				{ return mHost; }
240
241protected:
242	void sendTransferRequest(LLTransferTarget *targetp,
243							 const LLTransferSourceParams &params,
244							 const F32 priority);
245
246	void					addTransferTarget(LLTransferTarget *targetp);
247
248	friend class LLTransferTarget;
249	friend class LLTransferManager;
250protected:
251	typedef std::list<LLTransferTarget *>::iterator tt_iter;
252
253	LLTransferChannelType			mChannelType;
254	LLHost							mHost;
255	std::list<LLTransferTarget *>	mTransferTargets;
256};
257
258
259class LLTransferSourceParams
260{
261public:
262	LLTransferSourceParams(const LLTransferSourceType type) : mType(type) { }
263	virtual ~LLTransferSourceParams();
264
265	virtual void packParams(LLDataPacker &dp) const	= 0;
266	virtual BOOL unpackParams(LLDataPacker &dp) = 0;
267
268	LLTransferSourceType getType() const			{ return mType; }
269	
270protected:
271	LLTransferSourceType mType;
272};
273
274
275//
276// LLTransferSource is an interface, all transfer sources should be derived from it.
277//
278typedef LLTransferSource *(*LLTransferSourceCreateFunc)(const LLUUID &id, const F32 priority);
279
280class LLTransferSource
281{
282public:
283
284	LLUUID getID()				{ return mID; }
285
286	friend class LLTransferManager;
287	friend class LLTransferSourceChannel;
288
289protected:
290	LLTransferSource(const LLTransferSourceType source_type,
291					 const LLUUID &request_id,
292					 const F32 priority);
293	virtual ~LLTransferSource();
294
295	void					sendTransferStatus(LLTSCode status);	// When you've figured out your transfer status, do this
296
297	virtual void			initTransfer() = 0;
298	virtual F32				updatePriority() = 0;
299	virtual LLTSCode		dataCallback(const S32 packet_id,
300										 const S32 max_bytes,
301										 U8 **datap,
302										 S32 &returned_bytes,
303										 BOOL &delete_returned) = 0;
304
305	// The completionCallback is GUARANTEED to be called before the destructor.
306	virtual void			completionCallback(const LLTSCode status) = 0;
307
308	virtual void packParams(LLDataPacker& dp) const = 0;
309	virtual BOOL unpackParams(LLDataPacker& dp) = 0;
310
311	virtual S32				getNextPacketID()						{ return mLastPacketID + 1; }
312	virtual void			setLastPacketID(const S32 packet_id)	{ mLastPacketID = packet_id; }
313
314
315	// For now, no self-induced priority changes
316	F32						getPriority()							{ return mPriority; }
317	void					setPriority(const F32 pri)				{ mPriority = pri; }
318
319	virtual void			abortTransfer(); // DON'T USE THIS ONE, used internally by LLTransferManager
320
321	static LLTransferSource *createSource(const LLTransferSourceType stype,
322										  const LLUUID &request_id,
323										  const F32 priority);
324	static void registerSourceType(const LLTransferSourceType stype, LLTransferSourceCreateFunc);
325
326	static void sSetPriority(LLTransferSource *&tsp, const F32 priority);
327	static F32	sGetPriority(LLTransferSource *&tsp);
328protected:
329	typedef std::map<LLTransferSourceType, LLTransferSourceCreateFunc> stype_scfunc_map;
330	static stype_scfunc_map sSourceCreateMap;
331
332	LLTransferSourceType mType;
333	LLUUID mID;
334	LLTransferSourceChannel *mChannelp;
335	F32		mPriority;
336	S32		mSize;
337	S32		mLastPacketID;
338};
339
340
341class LLTransferTargetParams
342{
343public:
344	LLTransferTargetParams(const LLTransferTargetType type) : mType(type) {}
345	LLTransferTargetType getType() const		{ return mType; }
346protected:
347	LLTransferTargetType mType;
348};
349
350
351class LLTransferPacket
352{
353	// Used for storing a packet that's being delivered later because it's out of order.
354	// ONLY should be accessed by the following two classes, for now.
355	friend class LLTransferTarget;
356	friend class LLTransferManager;
357
358protected:
359
360	LLTransferPacket(const S32 packet_id, const LLTSCode status, const U8 *datap, const S32 size);
361	virtual ~LLTransferPacket();
362
363protected:
364	S32			mPacketID;
365	LLTSCode	mStatus;
366	U8			*mDatap;
367	S32			mSize;
368};
369
370
371class LLTransferTarget
372{
373public:
374	LLTransferTarget(
375		LLTransferTargetType target_type,
376		const LLUUID& transfer_id,
377		LLTransferSourceType source_type);
378	virtual ~LLTransferTarget();
379
380	// Accessors
381	LLUUID					getID() const			{ return mID; }
382	LLTransferTargetType	getType() const			{ return mType; }
383	LLTransferTargetChannel *getChannel() const		{ return mChannelp; }
384	LLTransferSourceType getSourceType() const { return mSourceType; }
385
386	// Static functionality
387	static LLTransferTarget* createTarget(
388		LLTransferTargetType target_type,
389		const LLUUID& request_id,
390		LLTransferSourceType source_type);
391
392	// friends
393	friend class LLTransferManager;
394	friend class LLTransferTargetChannel;
395
396protected:
397	// Implementation
398	virtual bool unpackParams(LLDataPacker& dp) = 0;
399	virtual void applyParams(const LLTransferTargetParams &params) = 0;
400	virtual LLTSCode		dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size) = 0;
401
402	// The completionCallback is GUARANTEED to be called before the destructor, so all handling
403	// of errors/aborts should be done here.
404	virtual void			completionCallback(const LLTSCode status) = 0;
405
406	void					abortTransfer();
407
408	virtual S32				getNextPacketID()						{ return mLastPacketID + 1; }
409	virtual void			setLastPacketID(const S32 packet_id)	{ mLastPacketID = packet_id; }
410	void					setSize(const S32 size)					{ mSize = size; }
411	void					setGotInfo(const BOOL got_info)			{ mGotInfo = got_info; }
412	BOOL					gotInfo() const							{ return mGotInfo; }
413
414	bool addDelayedPacket(
415		const S32 packet_id,
416		const LLTSCode status,
417		U8* datap,
418		const S32 size);
419
420protected:
421	typedef std::map<S32, LLTransferPacket *> transfer_packet_map;
422	typedef std::map<S32, LLTransferPacket *>::iterator tpm_iter;
423
424	LLTransferTargetType	mType;
425	LLTransferSourceType mSourceType;
426	LLUUID					mID;
427	LLTransferTargetChannel *mChannelp;
428	BOOL					mGotInfo;
429	S32						mSize;
430	S32						mLastPacketID;
431
432	transfer_packet_map		mDelayedPacketMap; // Packets that are waiting because of missing/out of order issues
433};
434
435
436// Hack, here so it's publicly available even though LLTransferSourceInvItem is only available on the simulator
437class LLTransferSourceParamsInvItem: public LLTransferSourceParams
438{
439public:
440	LLTransferSourceParamsInvItem();
441	virtual ~LLTransferSourceParamsInvItem() {}
442	/*virtual*/ void packParams(LLDataPacker &dp) const;
443	/*virtual*/ BOOL unpackParams(LLDataPacker &dp);
444
445	void setAgentSession(const LLUUID &agent_id, const LLUUID &session_id);
446	void setInvItem(const LLUUID &owner_id, const LLUUID &task_id, const LLUUID &item_id);
447	void setAsset(const LLUUID &asset_id, const LLAssetType::EType at);
448
449	LLUUID getAgentID() const						{ return mAgentID; }
450	LLUUID getSessionID() const						{ return mSessionID; }
451	LLUUID getOwnerID() const						{ return mOwnerID; }
452	LLUUID getTaskID() const						{ return mTaskID; }
453	LLUUID getItemID() const						{ return mItemID; }
454	LLUUID getAssetID() const						{ return mAssetID; }
455	LLAssetType::EType getAssetType() const			{ return mAssetType; }
456
457protected:
458	LLUUID				mAgentID;
459	LLUUID				mSessionID;
460	LLUUID				mOwnerID;
461	LLUUID				mTaskID;
462	LLUUID				mItemID;
463	LLUUID				mAssetID;
464	LLAssetType::EType	mAssetType;
465};
466
467
468// Hack, here so it's publicly available even though LLTransferSourceEstate is only available on the simulator
469class LLTransferSourceParamsEstate: public LLTransferSourceParams
470{
471public:
472	LLTransferSourceParamsEstate();
473	virtual ~LLTransferSourceParamsEstate() {}
474	/*virtual*/ void packParams(LLDataPacker &dp) const;
475	/*virtual*/ BOOL unpackParams(LLDataPacker &dp);
476
477	void setAgentSession(const LLUUID &agent_id, const LLUUID &session_id);
478	void setEstateAssetType(const EstateAssetType etype);
479	void setAsset(const LLUUID &asset_id, const LLAssetType::EType at);
480
481	LLUUID getAgentID() const						{ return mAgentID; }
482	LLUUID getSessionID() const						{ return mSessionID; }
483	EstateAssetType getEstateAssetType() const		{ return mEstateAssetType; }
484	LLUUID getAssetID() const					{ return mAssetID; }
485	LLAssetType::EType getAssetType() const		{ return mAssetType; }
486
487protected:
488	LLUUID				mAgentID;
489	LLUUID				mSessionID;
490	EstateAssetType		mEstateAssetType;
491	// these are set on the sim based on estateinfotype
492	LLUUID				mAssetID;
493	LLAssetType::EType	mAssetType;
494};
495
496
497extern LLTransferManager gTransferManager;
498
499#endif//LL_LLTRANSFERMANAGER_H