Index: net/third_party/udt/src/epoll.cpp |
=================================================================== |
--- net/third_party/udt/src/epoll.cpp (revision 78992) |
+++ net/third_party/udt/src/epoll.cpp (working copy) |
@@ -1,437 +0,0 @@ |
-/***************************************************************************** |
-Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. |
-All rights reserved. |
- |
-Redistribution and use in source and binary forms, with or without |
-modification, are permitted provided that the following conditions are |
-met: |
- |
-* Redistributions of source code must retain the above |
- copyright notice, this list of conditions and the |
- following disclaimer. |
- |
-* Redistributions in binary form must reproduce the |
- above copyright notice, this list of conditions |
- and the following disclaimer in the documentation |
- and/or other materials provided with the distribution. |
- |
-* Neither the name of the University of Illinois |
- nor the names of its contributors may be used to |
- endorse or promote products derived from this |
- software without specific prior written permission. |
- |
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-*****************************************************************************/ |
- |
-/***************************************************************************** |
-written by |
- Yunhong Gu, last updated 01/01/2011 |
-*****************************************************************************/ |
- |
-#include "udt.h" |
-#include "common.h" |
-#include "epoll.h" |
-#include <errno.h> |
-#include <algorithm> |
-#include <iterator> |
-#ifdef LINUX |
- #include <sys/epoll.h> |
- #include <unistd.h> |
-#endif |
- |
-using namespace std; |
- |
-CEPoll::CEPoll(): |
-m_iIDSeed(0) |
-{ |
- CGuard::createMutex(m_EPollLock); |
-} |
- |
-CEPoll::~CEPoll() |
-{ |
- CGuard::releaseMutex(m_EPollLock); |
-} |
- |
-int CEPoll::create() |
-{ |
- CGuard pg(m_EPollLock); |
- |
- int localid = 0; |
- |
- #ifdef LINUX |
- localid = epoll_create(1024); |
- if (localid < 0) |
- throw CUDTException(-1, 0, errno); |
- #else |
- // on BSD, use kqueue |
- // on Solaris, use /dev/poll |
- // on Windows, select |
- #endif |
- |
- if (++ m_iIDSeed >= 0x7FFFFFFF) |
- m_iIDSeed = 0; |
- |
- CEPollDesc desc; |
- desc.m_iID = m_iIDSeed; |
- desc.m_iLocalID = localid; |
- m_mPolls[desc.m_iID] = desc; |
- |
- return desc.m_iID; |
-} |
- |
-int CEPoll::add_usock(const int eid, const UDTSOCKET& u, const int* /*events*/) |
-{ |
- CGuard pg(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator p = m_mPolls.find(eid); |
- if (p == m_mPolls.end()) |
- throw CUDTException(5, 13); |
- |
- p->second.m_sUDTSocks.insert(u); |
- |
- return 0; |
-} |
- |
-int CEPoll::add_ssock(const int eid, const SYSSOCKET& s, const int* events) |
-{ |
- CGuard pg(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator p = m_mPolls.find(eid); |
- if (p == m_mPolls.end()) |
- throw CUDTException(5, 13); |
- |
-#ifdef LINUX |
- epoll_event ev; |
- |
- if (NULL == events) |
- ev.events = EPOLLIN | EPOLLOUT | EPOLLERR; |
- else |
- { |
- if (*events & UDT_EPOLL_IN) |
- ev.events |= EPOLLIN; |
- if (*events & UDT_EPOLL_OUT) |
- ev.events |= EPOLLOUT; |
- if (*events & UDT_EPOLL_ERR) |
- ev.events |= EPOLLERR; |
- } |
- |
- ev.data.fd = s; |
- if (epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_ADD, s, &ev) < 0) |
- throw CUDTException(); |
-#endif |
- |
- p->second.m_sLocals.insert(s); |
- |
- return 0; |
-} |
- |
-int CEPoll::remove_usock(const int eid, const UDTSOCKET& u, const int* /*events*/) |
-{ |
- CGuard pg(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator p = m_mPolls.find(eid); |
- if (p == m_mPolls.end()) |
- throw CUDTException(5, 13); |
- |
- p->second.m_sUDTSocks.erase(u); |
- |
- // when the socket is removed from a monitoring, it is not available anymore for any IO notification |
- p->second.m_sUDTReads.erase(u); |
- p->second.m_sUDTWrites.erase(u); |
- |
- return 0; |
-} |
- |
-int CEPoll::remove_ssock(const int eid, const SYSSOCKET& s, const int* events) |
-{ |
- CGuard pg(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator p = m_mPolls.find(eid); |
- if (p == m_mPolls.end()) |
- throw CUDTException(5, 13); |
- |
-#ifdef LINUX |
- epoll_event ev; |
- |
- if (NULL == events) |
- ev.events = EPOLLIN | EPOLLOUT | EPOLLERR; |
- else |
- { |
- if (*events & UDT_EPOLL_IN) |
- ev.events |= EPOLLIN; |
- if (*events & UDT_EPOLL_OUT) |
- ev.events |= EPOLLOUT; |
- if (*events & UDT_EPOLL_ERR) |
- ev.events |= EPOLLERR; |
- } |
- |
- ev.data.fd = s; |
- if (epoll_ctl(p->second.m_iLocalID, EPOLL_CTL_DEL, s, &ev) < 0) |
- throw CUDTException(); |
-#endif |
- |
- p->second.m_sLocals.erase(s); |
- |
- return 0; |
-} |
- |
-int CEPoll::wait(const int eid, set<UDTSOCKET>* readfds, set<UDTSOCKET>* writefds, int64_t msTimeOut, set<SYSSOCKET>* lrfds, set<SYSSOCKET>* lwfds) |
-{ |
- // if all fields is NULL and waiting time is infinite, then this would be a deadlock |
- if (!readfds && !writefds && !lrfds && lwfds && (msTimeOut < 0)) |
- throw CUDTException(5, 3, 0); |
- |
- int total = 0; |
- |
- int64_t entertime = CTimer::getTime(); |
- while (true) |
- { |
- CGuard::enterCS(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator p = m_mPolls.find(eid); |
- if (p == m_mPolls.end()) |
- { |
- CGuard::leaveCS(m_EPollLock); |
- throw CUDTException(5, 13); |
- } |
- |
- if (((readfds || writefds) && p->second.m_sUDTSocks.empty()) && ((lrfds || lwfds) && p->second.m_sLocals.empty())) |
- { |
- // no socket is being monitored, this may be a deadlock |
- CGuard::leaveCS(m_EPollLock); |
- throw CUDTException(5, 3); |
- } |
- |
- if ((NULL != readfds) && !p->second.m_sUDTReads.empty()) |
- { |
- *readfds = p->second.m_sUDTReads; |
- total += p->second.m_sUDTReads.size(); |
- } |
- |
- if ((NULL != writefds) && !p->second.m_sUDTWrites.empty()) |
- { |
- *writefds = p->second.m_sUDTWrites; |
- total += p->second.m_sUDTWrites.size(); |
- } |
- |
- if (lrfds || lwfds) |
- { |
- if (lrfds) |
- lrfds->clear(); |
- |
- if (lwfds) |
- lwfds->clear(); |
- |
- #ifdef LINUX |
- const int max_events = p->second.m_sLocals.size(); |
- epoll_event ev[max_events]; |
- int nfds = epoll_wait(p->second.m_iLocalID, ev, max_events, 0); |
- |
- for (int i = 0; i < nfds; ++ i) |
- { |
- if ((NULL != lrfds) && (ev[i].events & EPOLLIN)) |
- { |
- lrfds->insert(ev[i].data.fd); |
- ++ total; |
- } |
- if ((NULL != lwfds) && (ev[i].events & EPOLLOUT)) |
- { |
- lwfds->insert(ev[i].data.fd); |
- ++ total; |
- } |
- } |
- #else |
- //currently "select" is used for all non-Linux platforms. |
- //faster approaches can be applied for specific systems in the future. |
- |
- //"select" has a limitation on the number of sockets |
- |
- fd_set readfds; |
- fd_set writefds; |
- FD_ZERO(&readfds); |
- FD_ZERO(&writefds); |
- |
- for (set<SYSSOCKET>::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i) |
- { |
- if (lrfds) |
- FD_SET(*i, &readfds); |
- if (lwfds) |
- FD_SET(*i, &writefds); |
- } |
- |
- timeval tv; |
- tv.tv_sec = 0; |
- tv.tv_usec = 0; |
- int r = select(0, &readfds, &writefds, NULL, &tv); |
- |
- if (r > 0) |
- { |
- for (set<SYSSOCKET>::const_iterator i = p->second.m_sLocals.begin(); i != p->second.m_sLocals.end(); ++ i) |
- { |
- if (lrfds) |
- { |
- if (FD_ISSET(*i, &readfds)) |
- { |
- lrfds->insert(*i); |
- ++ total; |
- } |
- } |
- |
- if (lwfds) |
- { |
- if (FD_ISSET(*i, &writefds)) |
- { |
- lwfds->insert(*i); |
- ++ total; |
- } |
- } |
- } |
- } |
- #endif |
- } |
- |
- CGuard::leaveCS(m_EPollLock); |
- |
- if (total > 0) |
- return total; |
- |
- if ((msTimeOut >= 0) && (int64_t(CTimer::getTime() - entertime) >= msTimeOut * 1000LL)) |
- break; |
- |
- CTimer::waitForEvent(); |
- } |
- |
- return 0; |
-} |
- |
-int CEPoll::release(const int eid) |
-{ |
- CGuard pg(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator i = m_mPolls.find(eid); |
- if (i == m_mPolls.end()) |
- throw CUDTException(5, 13); |
- |
- #ifdef LINUX |
- // release local/system epoll descriptor |
- ::close(i->second.m_iLocalID); |
- #endif |
- |
- m_mPolls.erase(i); |
- |
- return 0; |
-} |
- |
-int CEPoll::enable_write(const UDTSOCKET& uid, set<int>& eids) |
-{ |
- CGuard pg(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator p; |
- |
- vector<int> lost; |
- for (set<int>::iterator i = eids.begin(); i != eids.end(); ++ i) |
- { |
- p = m_mPolls.find(*i); |
- if (p == m_mPolls.end()) |
- { |
- lost.push_back(*i); |
- } |
- else |
- { |
- p->second.m_sUDTWrites.insert(uid); |
- } |
- } |
- |
- for (vector<int>::iterator i = lost.begin(); i != lost.end(); ++ i) |
- eids.erase(*i); |
- |
- return 0; |
-} |
- |
-int CEPoll::enable_read(const UDTSOCKET& uid, set<int>& eids) |
-{ |
- CGuard pg(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator p; |
- |
- vector<int> lost; |
- for (set<int>::iterator i = eids.begin(); i != eids.end(); ++ i) |
- { |
- p = m_mPolls.find(*i); |
- if (p == m_mPolls.end()) |
- { |
- lost.push_back(*i); |
- } |
- else |
- { |
- p->second.m_sUDTReads.insert(uid); |
- } |
- } |
- |
- for (vector<int>::iterator i = lost.begin(); i != lost.end(); ++ i) |
- eids.erase(*i); |
- |
- return 0; |
-} |
- |
-int CEPoll::disable_write(const UDTSOCKET& uid, set<int>& eids) |
-{ |
- CGuard pg(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator p; |
- |
- vector<int> lost; |
- for (set<int>::iterator i = eids.begin(); i != eids.end(); ++ i) |
- { |
- p = m_mPolls.find(*i); |
- if (p == m_mPolls.end()) |
- { |
- lost.push_back(*i); |
- } |
- else |
- { |
- p->second.m_sUDTWrites.erase(uid); |
- } |
- } |
- |
- for (vector<int>::iterator i = lost.begin(); i != lost.end(); ++ i) |
- eids.erase(*i); |
- |
- return 0; |
-} |
- |
-int CEPoll::disable_read(const UDTSOCKET& uid, set<int>& eids) |
-{ |
- CGuard pg(m_EPollLock); |
- |
- map<int, CEPollDesc>::iterator p; |
- |
- vector<int> lost; |
- for (set<int>::iterator i = eids.begin(); i != eids.end(); ++ i) |
- { |
- p = m_mPolls.find(*i); |
- if (p == m_mPolls.end()) |
- { |
- lost.push_back(*i); |
- } |
- else |
- { |
- p->second.m_sUDTReads.erase(uid); |
- } |
- } |
- |
- for (vector<int>::iterator i = lost.begin(); i != lost.end(); ++ i) |
- eids.erase(*i); |
- |
- return 0; |
-} |