OLD | NEW |
| (Empty) |
1 /***************************************************************************** | |
2 Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. | |
3 All rights reserved. | |
4 | |
5 Redistribution and use in source and binary forms, with or without | |
6 modification, are permitted provided that the following conditions are | |
7 met: | |
8 | |
9 * Redistributions of source code must retain the above | |
10 copyright notice, this list of conditions and the | |
11 following disclaimer. | |
12 | |
13 * Redistributions in binary form must reproduce the | |
14 above copyright notice, this list of conditions | |
15 and the following disclaimer in the documentation | |
16 and/or other materials provided with the distribution. | |
17 | |
18 * Neither the name of the University of Illinois | |
19 nor the names of its contributors may be used to | |
20 endorse or promote products derived from this | |
21 software without specific prior written permission. | |
22 | |
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
24 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
25 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
26 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
34 *****************************************************************************/ | |
35 | |
36 /***************************************************************************** | |
37 written by | |
38 Yunhong Gu, last updated 01/12/2011 | |
39 *****************************************************************************/ | |
40 | |
41 | |
42 #ifndef __UDT_QUEUE_H__ | |
43 #define __UDT_QUEUE_H__ | |
44 | |
45 #include "common.h" | |
46 #include "packet.h" | |
47 #include "channel.h" | |
48 #include <vector> | |
49 #include <map> | |
50 #include <queue> | |
51 | |
52 class CUDT; | |
53 | |
54 struct CUnit | |
55 { | |
56 CPacket m_Packet; // packet | |
57 int m_iFlag; // 0: free, 1: occupied, 2: msg read but not fre
ed (out-of-order), 3: msg dropped | |
58 }; | |
59 | |
60 class CUnitQueue | |
61 { | |
62 friend class CRcvQueue; | |
63 friend class CRcvBuffer; | |
64 | |
65 public: | |
66 CUnitQueue(); | |
67 ~CUnitQueue(); | |
68 | |
69 public: | |
70 | |
71 // Functionality: | |
72 // Initialize the unit queue. | |
73 // Parameters: | |
74 // 1) [in] size: queue size | |
75 // 2) [in] mss: maximum segament size | |
76 // 3) [in] version: IP version | |
77 // Returned value: | |
78 // 0: success, -1: failure. | |
79 | |
80 int init(const int& size, const int& mss, const int& version); | |
81 | |
82 // Functionality: | |
83 // Increase (double) the unit queue size. | |
84 // Parameters: | |
85 // None. | |
86 // Returned value: | |
87 // 0: success, -1: failure. | |
88 | |
89 int increase(); | |
90 | |
91 // Functionality: | |
92 // Decrease (halve) the unit queue size. | |
93 // Parameters: | |
94 // None. | |
95 // Returned value: | |
96 // 0: success, -1: failure. | |
97 | |
98 int shrink(); | |
99 | |
100 // Functionality: | |
101 // find an available unit for incoming packet. | |
102 // Parameters: | |
103 // None. | |
104 // Returned value: | |
105 // Pointer to the available unit, NULL if not found. | |
106 | |
107 CUnit* getNextAvailUnit(); | |
108 | |
109 private: | |
110 struct CQEntry | |
111 { | |
112 CUnit* m_pUnit; // unit queue | |
113 char* m_pBuffer; // data buffer | |
114 int m_iSize; // size of each queue | |
115 | |
116 CQEntry* m_pNext; | |
117 } | |
118 *m_pQEntry, // pointer to the first unit queue | |
119 *m_pCurrQueue, // pointer to the current available queue | |
120 *m_pLastQueue; // pointer to the last unit queue | |
121 | |
122 CUnit* m_pAvailUnit; // recent available unit | |
123 | |
124 int m_iSize; // total size of the unit queue, in number of pa
ckets | |
125 int m_iCount; // total number of valid packets in the queue | |
126 | |
127 int m_iMSS; // unit buffer size | |
128 int m_iIPversion; // IP version | |
129 | |
130 private: | |
131 CUnitQueue(const CUnitQueue&); | |
132 CUnitQueue& operator=(const CUnitQueue&); | |
133 }; | |
134 | |
135 struct CSNode | |
136 { | |
137 CUDT* m_pUDT; // Pointer to the instance of CUDT socket | |
138 uint64_t m_llTimeStamp; // Time Stamp | |
139 | |
140 int m_iHeapLoc; // location on the heap, -1 means not on the hea
p | |
141 }; | |
142 | |
143 class CSndUList | |
144 { | |
145 friend class CSndQueue; | |
146 | |
147 public: | |
148 CSndUList(); | |
149 ~CSndUList(); | |
150 | |
151 public: | |
152 | |
153 // Functionality: | |
154 // Insert a new UDT instance into the list. | |
155 // Parameters: | |
156 // 1) [in] ts: time stamp: next processing time | |
157 // 2) [in] u: pointer to the UDT instance | |
158 // Returned value: | |
159 // None. | |
160 | |
161 void insert(const int64_t& ts, const CUDT* u); | |
162 | |
163 // Functionality: | |
164 // Update the timestamp of the UDT instance on the list. | |
165 // Parameters: | |
166 // 1) [in] u: pointer to the UDT instance | |
167 // 2) [in] resechedule: if the timestampe shoudl be rescheduled | |
168 // Returned value: | |
169 // None. | |
170 | |
171 void update(const CUDT* u, const bool& reschedule = true); | |
172 | |
173 // Functionality: | |
174 // Retrieve the next packet and peer address from the first entry, and
reschedule it in the queue. | |
175 // Parameters: | |
176 // 0) [out] addr: destination address of the next packet | |
177 // 1) [out] pkt: the next packet to be sent | |
178 // Returned value: | |
179 // 1 if successfully retrieved, -1 if no packet found. | |
180 | |
181 int pop(sockaddr*& addr, CPacket& pkt); | |
182 | |
183 // Functionality: | |
184 // Remove UDT instance from the list. | |
185 // Parameters: | |
186 // 1) [in] u: pointer to the UDT instance | |
187 // Returned value: | |
188 // None. | |
189 | |
190 void remove(const CUDT* u); | |
191 | |
192 // Functionality: | |
193 // Retrieve the next scheduled processing time. | |
194 // Parameters: | |
195 // None. | |
196 // Returned value: | |
197 // Scheduled processing time of the first UDT socket in the list. | |
198 | |
199 uint64_t getNextProcTime(); | |
200 | |
201 private: | |
202 void insert_(const int64_t& ts, const CUDT* u); | |
203 void remove_(const CUDT* u); | |
204 | |
205 private: | |
206 CSNode** m_pHeap; // The heap array | |
207 int m_iArrayLength; // physical length of the array | |
208 int m_iLastEntry; // position of last entry on the heap ar
ray | |
209 | |
210 pthread_mutex_t m_ListLock; | |
211 | |
212 pthread_mutex_t* m_pWindowLock; | |
213 pthread_cond_t* m_pWindowCond; | |
214 | |
215 CTimer* m_pTimer; | |
216 | |
217 private: | |
218 CSndUList(const CSndUList&); | |
219 CSndUList& operator=(const CSndUList&); | |
220 }; | |
221 | |
222 struct CRNode | |
223 { | |
224 CUDT* m_pUDT; // Pointer to the instance of CUDT socket | |
225 uint64_t m_llTimeStamp; // Time Stamp | |
226 | |
227 CRNode* m_pPrev; // previous link | |
228 CRNode* m_pNext; // next link | |
229 | |
230 bool m_bOnList; // if the node is already on the list | |
231 }; | |
232 | |
233 class CRcvUList | |
234 { | |
235 public: | |
236 CRcvUList(); | |
237 ~CRcvUList(); | |
238 | |
239 public: | |
240 | |
241 // Functionality: | |
242 // Insert a new UDT instance to the list. | |
243 // Parameters: | |
244 // 1) [in] u: pointer to the UDT instance | |
245 // Returned value: | |
246 // None. | |
247 | |
248 void insert(const CUDT* u); | |
249 | |
250 // Functionality: | |
251 // Remove the UDT instance from the list. | |
252 // Parameters: | |
253 // 1) [in] u: pointer to the UDT instance | |
254 // Returned value: | |
255 // None. | |
256 | |
257 void remove(const CUDT* u); | |
258 | |
259 // Functionality: | |
260 // Move the UDT instance to the end of the list, if it already exists;
otherwise, do nothing. | |
261 // Parameters: | |
262 // 1) [in] u: pointer to the UDT instance | |
263 // Returned value: | |
264 // None. | |
265 | |
266 void update(const CUDT* u); | |
267 | |
268 public: | |
269 CRNode* m_pUList; // the head node | |
270 | |
271 private: | |
272 CRNode* m_pLast; // the last node | |
273 | |
274 private: | |
275 CRcvUList(const CRcvUList&); | |
276 CRcvUList& operator=(const CRcvUList&); | |
277 }; | |
278 | |
279 class CHash | |
280 { | |
281 public: | |
282 CHash(); | |
283 ~CHash(); | |
284 | |
285 public: | |
286 | |
287 // Functionality: | |
288 // Initialize the hash table. | |
289 // Parameters: | |
290 // 1) [in] size: hash table size | |
291 // Returned value: | |
292 // None. | |
293 | |
294 void init(const int& size); | |
295 | |
296 // Functionality: | |
297 // Look for a UDT instance from the hash table. | |
298 // Parameters: | |
299 // 1) [in] id: socket ID | |
300 // Returned value: | |
301 // Pointer to a UDT instance, or NULL if not found. | |
302 | |
303 CUDT* lookup(const int32_t& id); | |
304 | |
305 // Functionality: | |
306 // Insert an entry to the hash table. | |
307 // Parameters: | |
308 // 1) [in] id: socket ID | |
309 // 2) [in] u: pointer to the UDT instance | |
310 // Returned value: | |
311 // None. | |
312 | |
313 void insert(const int32_t& id, const CUDT* u); | |
314 | |
315 // Functionality: | |
316 // Remove an entry from the hash table. | |
317 // Parameters: | |
318 // 1) [in] id: socket ID | |
319 // Returned value: | |
320 // None. | |
321 | |
322 void remove(const int32_t& id); | |
323 | |
324 private: | |
325 struct CBucket | |
326 { | |
327 int32_t m_iID; // Socket ID | |
328 CUDT* m_pUDT; // Socket instance | |
329 | |
330 CBucket* m_pNext; // next bucket | |
331 } **m_pBucket; // list of buckets (the hash table) | |
332 | |
333 int m_iHashSize; // size of hash table | |
334 | |
335 private: | |
336 CHash(const CHash&); | |
337 CHash& operator=(const CHash&); | |
338 }; | |
339 | |
340 class CRendezvousQueue | |
341 { | |
342 public: | |
343 CRendezvousQueue(); | |
344 ~CRendezvousQueue(); | |
345 | |
346 public: | |
347 void insert(const UDTSOCKET& id, const int& ipv, const sockaddr* addr); | |
348 void remove(const UDTSOCKET& id); | |
349 bool retrieve(const sockaddr* addr, UDTSOCKET& id); | |
350 | |
351 private: | |
352 struct CRL | |
353 { | |
354 UDTSOCKET m_iID; | |
355 int m_iIPversion; | |
356 sockaddr* m_pPeerAddr; | |
357 }; | |
358 std::vector<CRL> m_vRendezvousID; // The sockets currently in rendezv
ous mode | |
359 | |
360 pthread_mutex_t m_RIDVectorLock; | |
361 }; | |
362 | |
363 class CSndQueue | |
364 { | |
365 friend class CUDT; | |
366 friend class CUDTUnited; | |
367 | |
368 public: | |
369 CSndQueue(); | |
370 ~CSndQueue(); | |
371 | |
372 public: | |
373 | |
374 // Functionality: | |
375 // Initialize the sending queue. | |
376 // Parameters: | |
377 // 1) [in] c: UDP channel to be associated to the queue | |
378 // 2) [in] t: Timer | |
379 // Returned value: | |
380 // None. | |
381 | |
382 void init(const CChannel* c, const CTimer* t); | |
383 | |
384 // Functionality: | |
385 // Send out a packet to a given address. | |
386 // Parameters: | |
387 // 1) [in] addr: destination address | |
388 // 2) [in] packet: packet to be sent out | |
389 // Returned value: | |
390 // Size of data sent out. | |
391 | |
392 int sendto(const sockaddr* addr, CPacket& packet); | |
393 | |
394 private: | |
395 #ifndef WIN32 | |
396 static void* worker(void* param); | |
397 #else | |
398 static DWORD WINAPI worker(LPVOID param); | |
399 #endif | |
400 | |
401 pthread_t m_WorkerThread; | |
402 | |
403 private: | |
404 CSndUList* m_pSndUList; // List of UDT instances for data sendin
g | |
405 CChannel* m_pChannel; // The UDP channel for data sending | |
406 CTimer* m_pTimer; // Timing facility | |
407 | |
408 pthread_mutex_t m_WindowLock; | |
409 pthread_cond_t m_WindowCond; | |
410 | |
411 volatile bool m_bClosing; // closing the worker | |
412 pthread_cond_t m_ExitCond; | |
413 | |
414 private: | |
415 CSndQueue(const CSndQueue&); | |
416 CSndQueue& operator=(const CSndQueue&); | |
417 }; | |
418 | |
419 class CRcvQueue | |
420 { | |
421 friend class CUDT; | |
422 friend class CUDTUnited; | |
423 | |
424 public: | |
425 CRcvQueue(); | |
426 ~CRcvQueue(); | |
427 | |
428 public: | |
429 | |
430 // Functionality: | |
431 // Initialize the receiving queue. | |
432 // Parameters: | |
433 // 1) [in] size: queue size | |
434 // 2) [in] mss: maximum packet size | |
435 // 3) [in] version: IP version | |
436 // 4) [in] hsize: hash table size | |
437 // 5) [in] c: UDP channel to be associated to the queue | |
438 // 6) [in] t: timer | |
439 // Returned value: | |
440 // None. | |
441 | |
442 void init(const int& size, const int& payload, const int& version, const int&
hsize, const CChannel* c, const CTimer* t); | |
443 | |
444 // Functionality: | |
445 // Read a packet for a specific UDT socket id. | |
446 // Parameters: | |
447 // 1) [in] id: Socket ID | |
448 // 2) [out] packet: received packet | |
449 // Returned value: | |
450 // Data size of the packet | |
451 | |
452 int recvfrom(const int32_t& id, CPacket& packet); | |
453 | |
454 private: | |
455 #ifndef WIN32 | |
456 static void* worker(void* param); | |
457 #else | |
458 static DWORD WINAPI worker(LPVOID param); | |
459 #endif | |
460 | |
461 pthread_t m_WorkerThread; | |
462 | |
463 private: | |
464 CUnitQueue m_UnitQueue; // The received packet queue | |
465 | |
466 CRcvUList* m_pRcvUList; // List of UDT instances that will read
packets from the queue | |
467 CHash* m_pHash; // Hash table for UDT socket looking up | |
468 CChannel* m_pChannel; // UDP channel for receving packets | |
469 CTimer* m_pTimer; // shared timer with the snd queue | |
470 | |
471 int m_iPayloadSize; // packet payload size | |
472 | |
473 volatile bool m_bClosing; // closing the workder | |
474 pthread_cond_t m_ExitCond; | |
475 | |
476 private: | |
477 int setListener(const CUDT* u); | |
478 void removeListener(const CUDT* u); | |
479 | |
480 void setNewEntry(CUDT* u); | |
481 bool ifNewEntry(); | |
482 CUDT* getNewEntry(); | |
483 | |
484 void storePkt(const int32_t& id, CPacket* pkt); | |
485 | |
486 private: | |
487 pthread_mutex_t m_LSLock; | |
488 volatile CUDT* m_pListener; // pointer to the (uniqu
e, if any) listening UDT entity | |
489 CRendezvousQueue* m_pRendezvousQueue; // The list of sockets i
n rendezvous mode | |
490 | |
491 std::vector<CUDT*> m_vNewEntry; // newly added entries,
to be inserted | |
492 pthread_mutex_t m_IDLock; | |
493 | |
494 std::map<int32_t, std::queue<CPacket*> > m_mBuffer; // temporary buffer for
rendezvous connection request | |
495 pthread_mutex_t m_PassLock; | |
496 pthread_cond_t m_PassCond; | |
497 | |
498 private: | |
499 CRcvQueue(const CRcvQueue&); | |
500 CRcvQueue& operator=(const CRcvQueue&); | |
501 }; | |
502 | |
503 struct CMultiplexer | |
504 { | |
505 CSndQueue* m_pSndQueue; // The sending queue | |
506 CRcvQueue* m_pRcvQueue; // The receiving queue | |
507 CChannel* m_pChannel; // The UDP channel for sending and receiving | |
508 CTimer* m_pTimer; // The timer | |
509 | |
510 int m_iPort; // The UDP port number of this multiplexer | |
511 int m_iIPversion; // IP version | |
512 int m_iMSS; // Maximum Segment Size | |
513 int m_iRefCount; // number of UDT instances that are associated w
ith this multiplexer | |
514 bool m_bReusable; // if this one can be shared with others | |
515 | |
516 int m_iID; // multiplexer ID | |
517 }; | |
518 | |
519 #endif | |
OLD | NEW |