Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(771)

Side by Side Diff: net/third_party/udt/src/epoll.cpp

Issue 6708091: Remove UDT. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/third_party/udt/src/epoll.h ('k') | net/third_party/udt/src/list.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/01/2011
39 *****************************************************************************/
40
41 #include "udt.h"
42 #include "common.h"
43 #include "epoll.h"
44 #include <errno.h>
45 #include <algorithm>
46 #include <iterator>
47 #ifdef LINUX
48 #include <sys/epoll.h>
49 #include <unistd.h>
50 #endif
51
52 using namespace std;
53
54 CEPoll::CEPoll():
55 m_iIDSeed(0)
56 {
57 CGuard::createMutex(m_EPollLock);
58 }
59
60 CEPoll::~CEPoll()
61 {
62 CGuard::releaseMutex(m_EPollLock);
63 }
64
65 int CEPoll::create()
66 {
67 CGuard pg(m_EPollLock);
68
69 int localid = 0;
70
71 #ifdef LINUX
72 localid = epoll_create(1024);
73 if (localid < 0)
74 throw CUDTException(-1, 0, errno);
75 #else
76 // on BSD, use kqueue
77 // on Solaris, use /dev/poll
78 // on Windows, select
79 #endif
80
81 if (++ m_iIDSeed >= 0x7FFFFFFF)
82 m_iIDSeed = 0;
83
84 CEPollDesc desc;
85 desc.m_iID = m_iIDSeed;
86 desc.m_iLocalID = localid;
87 m_mPolls[desc.m_iID] = desc;
88
89 return desc.m_iID;
90 }
91
92 int CEPoll::add_usock(const int eid, const UDTSOCKET& u, const int* /*events*/)
93 {
94 CGuard pg(m_EPollLock);
95
96 map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
97 if (p == m_mPolls.end())
98 throw CUDTException(5, 13);
99
100 p->second.m_sUDTSocks.insert(u);
101
102 return 0;
103 }
104
105 int CEPoll::add_ssock(const int eid, const SYSSOCKET& s, const int* events)
106 {
107 CGuard pg(m_EPollLock);
108
109 map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
110 if (p == m_mPolls.end())
111 throw CUDTException(5, 13);
112
113 #ifdef LINUX
114 epoll_event ev;
115
116 if (NULL == events)
117 ev.events = EPOLLIN | EPOLLOUT | EPOLLERR;
118 else
119 {
120 if (*events & UDT_EPOLL_IN)
121 ev.events |= EPOLLIN;
122 if (*events & UDT_EPOLL_OUT)
123 ev.events |= EPOLLOUT;
124 if (*events & UDT_EPOLL_ERR)
125 ev.events |= EPOLLERR;
126 }
127
128 ev.data.fd = s;
129 if (epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_ADD, s, &ev) < 0)
130 throw CUDTException();
131 #endif
132
133 p->second.m_sLocals.insert(s);
134
135 return 0;
136 }
137
138 int CEPoll::remove_usock(const int eid, const UDTSOCKET& u, const int* /*events* /)
139 {
140 CGuard pg(m_EPollLock);
141
142 map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
143 if (p == m_mPolls.end())
144 throw CUDTException(5, 13);
145
146 p->second.m_sUDTSocks.erase(u);
147
148 // when the socket is removed from a monitoring, it is not available anymore for any IO notification
149 p->second.m_sUDTReads.erase(u);
150 p->second.m_sUDTWrites.erase(u);
151
152 return 0;
153 }
154
155 int CEPoll::remove_ssock(const int eid, const SYSSOCKET& s, const int* events)
156 {
157 CGuard pg(m_EPollLock);
158
159 map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
160 if (p == m_mPolls.end())
161 throw CUDTException(5, 13);
162
163 #ifdef LINUX
164 epoll_event ev;
165
166 if (NULL == events)
167 ev.events = EPOLLIN | EPOLLOUT | EPOLLERR;
168 else
169 {
170 if (*events & UDT_EPOLL_IN)
171 ev.events |= EPOLLIN;
172 if (*events & UDT_EPOLL_OUT)
173 ev.events |= EPOLLOUT;
174 if (*events & UDT_EPOLL_ERR)
175 ev.events |= EPOLLERR;
176 }
177
178 ev.data.fd = s;
179 if (epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_DEL, s, &ev) < 0)
180 throw CUDTException();
181 #endif
182
183 p->second.m_sLocals.erase(s);
184
185 return 0;
186 }
187
188 int CEPoll::wait(const int eid, set<UDTSOCKET>* readfds, set<UDTSOCKET>* writefd s, int64_t msTimeOut, set<SYSSOCKET>* lrfds, set<SYSSOCKET>* lwfds)
189 {
190 // if all fields is NULL and waiting time is infinite, then this would be a d eadlock
191 if (!readfds && !writefds && !lrfds && lwfds && (msTimeOut < 0))
192 throw CUDTException(5, 3, 0);
193
194 int total = 0;
195
196 int64_t entertime = CTimer::getTime();
197 while (true)
198 {
199 CGuard::enterCS(m_EPollLock);
200
201 map<int, CEPollDesc>::iterator p = m_mPolls.find(eid);
202 if (p == m_mPolls.end())
203 {
204 CGuard::leaveCS(m_EPollLock);
205 throw CUDTException(5, 13);
206 }
207
208 if (((readfds || writefds) && p->second.m_sUDTSocks.empty()) && ((lrfds || lwfds) && p->second.m_sLocals.empty()))
209 {
210 // no socket is being monitored, this may be a deadlock
211 CGuard::leaveCS(m_EPollLock);
212 throw CUDTException(5, 3);
213 }
214
215 if ((NULL != readfds) && !p->second.m_sUDTReads.empty())
216 {
217 *readfds = p->second.m_sUDTReads;
218 total += p->second.m_sUDTReads.size();
219 }
220
221 if ((NULL != writefds) && !p->second.m_sUDTWrites.empty())
222 {
223 *writefds = p->second.m_sUDTWrites;
224 total += p->second.m_sUDTWrites.size();
225 }
226
227 if (lrfds || lwfds)
228 {
229 if (lrfds)
230 lrfds->clear();
231
232 if (lwfds)
233 lwfds->clear();
234
235 #ifdef LINUX
236 const int max_events = p->second.m_sLocals.size();
237 epoll_event ev[max_events];
238 int nfds = epoll_wait(p->second.m_iLocalID, ev, max_events, 0);
239
240 for (int i = 0; i < nfds; ++ i)
241 {
242 if ((NULL != lrfds) && (ev[i].events & EPOLLIN))
243 {
244 lrfds->insert(ev[i].data.fd);
245 ++ total;
246 }
247 if ((NULL != lwfds) && (ev[i].events & EPOLLOUT))
248 {
249 lwfds->insert(ev[i].data.fd);
250 ++ total;
251 }
252 }
253 #else
254 //currently "select" is used for all non-Linux platforms.
255 //faster approaches can be applied for specific systems in the future.
256
257 //"select" has a limitation on the number of sockets
258
259 fd_set readfds;
260 fd_set writefds;
261 FD_ZERO(&readfds);
262 FD_ZERO(&writefds);
263
264 for (set<SYSSOCKET>::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i)
265 {
266 if (lrfds)
267 FD_SET(*i, &readfds);
268 if (lwfds)
269 FD_SET(*i, &writefds);
270 }
271
272 timeval tv;
273 tv.tv_sec = 0;
274 tv.tv_usec = 0;
275 int r = select(0, &readfds, &writefds, NULL, &tv);
276
277 if (r > 0)
278 {
279 for (set<SYSSOCKET>::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i)
280 {
281 if (lrfds)
282 {
283 if (FD_ISSET(*i, &readfds))
284 {
285 lrfds->insert(*i);
286 ++ total;
287 }
288 }
289
290 if (lwfds)
291 {
292 if (FD_ISSET(*i, &writefds))
293 {
294 lwfds->insert(*i);
295 ++ total;
296 }
297 }
298 }
299 }
300 #endif
301 }
302
303 CGuard::leaveCS(m_EPollLock);
304
305 if (total > 0)
306 return total;
307
308 if ((msTimeOut >= 0) && (int64_t(CTimer::getTime() - entertime) >= msTimeO ut * 1000LL))
309 break;
310
311 CTimer::waitForEvent();
312 }
313
314 return 0;
315 }
316
317 int CEPoll::release(const int eid)
318 {
319 CGuard pg(m_EPollLock);
320
321 map<int, CEPollDesc>::iterator i = m_mPolls.find(eid);
322 if (i == m_mPolls.end())
323 throw CUDTException(5, 13);
324
325 #ifdef LINUX
326 // release local/system epoll descriptor
327 ::close(i->second.m_iLocalID);
328 #endif
329
330 m_mPolls.erase(i);
331
332 return 0;
333 }
334
335 int CEPoll::enable_write(const UDTSOCKET& uid, set<int>& eids)
336 {
337 CGuard pg(m_EPollLock);
338
339 map<int, CEPollDesc>::iterator p;
340
341 vector<int> lost;
342 for (set<int>::iterator i = eids.begin(); i != eids.end(); ++ i)
343 {
344 p = m_mPolls.find(*i);
345 if (p == m_mPolls.end())
346 {
347 lost.push_back(*i);
348 }
349 else
350 {
351 p->second.m_sUDTWrites.insert(uid);
352 }
353 }
354
355 for (vector<int>::iterator i = lost.begin(); i != lost.end(); ++ i)
356 eids.erase(*i);
357
358 return 0;
359 }
360
361 int CEPoll::enable_read(const UDTSOCKET& uid, set<int>& eids)
362 {
363 CGuard pg(m_EPollLock);
364
365 map<int, CEPollDesc>::iterator p;
366
367 vector<int> lost;
368 for (set<int>::iterator i = eids.begin(); i != eids.end(); ++ i)
369 {
370 p = m_mPolls.find(*i);
371 if (p == m_mPolls.end())
372 {
373 lost.push_back(*i);
374 }
375 else
376 {
377 p->second.m_sUDTReads.insert(uid);
378 }
379 }
380
381 for (vector<int>::iterator i = lost.begin(); i != lost.end(); ++ i)
382 eids.erase(*i);
383
384 return 0;
385 }
386
387 int CEPoll::disable_write(const UDTSOCKET& uid, set<int>& eids)
388 {
389 CGuard pg(m_EPollLock);
390
391 map<int, CEPollDesc>::iterator p;
392
393 vector<int> lost;
394 for (set<int>::iterator i = eids.begin(); i != eids.end(); ++ i)
395 {
396 p = m_mPolls.find(*i);
397 if (p == m_mPolls.end())
398 {
399 lost.push_back(*i);
400 }
401 else
402 {
403 p->second.m_sUDTWrites.erase(uid);
404 }
405 }
406
407 for (vector<int>::iterator i = lost.begin(); i != lost.end(); ++ i)
408 eids.erase(*i);
409
410 return 0;
411 }
412
413 int CEPoll::disable_read(const UDTSOCKET& uid, set<int>& eids)
414 {
415 CGuard pg(m_EPollLock);
416
417 map<int, CEPollDesc>::iterator p;
418
419 vector<int> lost;
420 for (set<int>::iterator i = eids.begin(); i != eids.end(); ++ i)
421 {
422 p = m_mPolls.find(*i);
423 if (p == m_mPolls.end())
424 {
425 lost.push_back(*i);
426 }
427 else
428 {
429 p->second.m_sUDTReads.erase(uid);
430 }
431 }
432
433 for (vector<int>::iterator i = lost.begin(); i != lost.end(); ++ i)
434 eids.erase(*i);
435
436 return 0;
437 }
OLDNEW
« no previous file with comments | « net/third_party/udt/src/epoll.h ('k') | net/third_party/udt/src/list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698