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