public int select(ref UDTSOCKET[] readfds, ref UDTSOCKET[] writefds, ref UDTSOCKET[] exceptfds, timeval timeout) { Int64 entertime = CClock.getTime(); Int64 to; if (null == timeout) to = 0xFFFFFFFFFFFFFFFF; else to = timeout.tv_sec * 1000000 + timeout.tv_usec; // initialize results int count = 0; HashSet<UDTSOCKET> rs = new HashSet<int>(); HashSet<UDTSOCKET> ws = new HashSet<int>(); HashSet<UDTSOCKET> es = new HashSet<int>(); // retrieve related UDT sockets List<UdtSocket> ru = new List<UdtSocket>(); List<UdtSocket> wu = new List<UdtSocket>(); List<UdtSocket> eu = new List<UdtSocket>(); UdtSocket s; if (null != readfds) { foreach (UDTSOCKET sockid in readfds) { if (UDTSTATUS.BROKEN == getStatus(sockid)) { rs.Add(sockid); ++count; } else if (null == (s = locate(sockid))) throw new CUDTException(5, 4, 0); else ru.Add(s); } } if (null != writefds) { foreach (UDTSOCKET i2 in writefds) { if (UDTSTATUS.BROKEN == getStatus(i2)) { ws.Add(i2); ++count; } else if (null == (s = locate(i2))) throw new CUDTException(5, 4, 0); else wu.Add(s); } } if (null != exceptfds) { //for (set<UDTSOCKET>::iterator i3 = exceptfds.begin(); i3 != exceptfds.end(); ++ i3) foreach (UDTSOCKET i3 in exceptfds) { if (UDTSTATUS.BROKEN == getStatus(i3)) { es.Add(i3); ++count; } else if (null == (s = locate(i3))) throw new CUDTException(5, 4, 0); else eu.Add(s); } } do { // query read sockets //for (vector<UdtSocket*>::iterator j1 = ru.begin(); j1 != ru.end(); ++ j1) foreach (UdtSocket j1 in ru) { s = j1; if ((s.m_pUDT.m_bConnected && (s.m_pUDT.m_pRcvBuffer.getRcvDataSize() > 0) && ((s.m_pUDT.m_iSockType == UDTSockType.UDT_STREAM) || (s.m_pUDT.m_pRcvBuffer.getRcvMsgNum() > 0))) || (!s.m_pUDT.m_bListening && (s.m_pUDT.m_bBroken || !s.m_pUDT.m_bConnected)) || (s.m_pUDT.m_bListening && (s.m_pQueuedSockets.size() > 0)) || (s.m_Status == UDTSTATUS.CLOSED)) { rs.insert(s.m_SocketID); ++count; } } // query write sockets //for (vector<UdtSocket*>::iterator j2 = wu.begin(); j2 != wu.end(); ++ j2) foreach (UdtSocket j2 in wu) { s = j2; if ((s.m_pUDT.m_bConnected && (s.m_pUDT.m_pSndBuffer.getCurrBufSize() < s.m_pUDT.m_iSndBufSize)) || s.m_pUDT.m_bBroken || !s.m_pUDT.m_bConnected || (s.m_Status == UDTSTATUS.CLOSED)) { ws.insert(s.m_SocketID); ++count; } } // query exceptions on sockets //for (vector<UdtSocket*>::iterator j3 = eu.begin(); j3 != eu.end(); ++ j3) foreach (UdtSocket j3 in eu) { // check connection request status, not supported now } if (0 < count) break; CClock.waitForEvent(); } while (to > CClock.getTime() - entertime); if (null != readfds) readfds = rs.ToArray(); if (null != writefds) writefds = ws.ToArray(); if (null != exceptfds) exceptfds = es.ToArray(); return count; }
public static int select(int nfds, fd_set readfds, fd_set writefds, fd_set exceptfds, timeval timeout) { if ((null == readfds) && (null == writefds) && (null == exceptfds)) { s_UDTUnited.setError(new CUDTException(5, 3, 0)); return ERROR; } try { return s_UDTUnited.select(readfds, writefds, exceptfds, timeout); } catch (CUDTException e) { s_UDTUnited.setError(new CUDTException(e)); return ERROR; } catch (bad_alloc) { s_UDTUnited.setError(new CUDTException(3, 2, 0)); return ERROR; } catch (Exception e) { s_UDTUnited.setError(new CUDTException(-1, 0, 0)); return ERROR; } }