protected bool Poll(int microSeconds, SelectMode mode) { fd_set readFDs = null; fd_set writeFDs = null; if (mode == SelectMode.SelectRead) { readFDs = new fd_set(); readFDs.FD_ZERO(); readFDs.FD_SET(mSocket); } if (mode == SelectMode.SelectWrite) { writeFDs = new fd_set(); writeFDs.FD_ZERO(); writeFDs.FD_SET(mSocket); } Int32 ret = select(0, readFDs, null, null, null); //Console.WriteLine("select returned: {0}", ret); if (readFDs.FD_ISSET(mSocket)) { return true; } return false; }
private static extern Int32 __WSAFDIsSet(Int32 fd, fd_set set);
private static extern Int32 select(Int32 nfds, fd_set readFDs, fd_set writeFDs, fd_set exceptFDs, timeval timeout);
internal static void FD_ZERO(fd_set fds) { for (var i = 0; i < fd_set.FD_SETSIZE; i++) { //fds.fd_array[i] = (IntPtr) 0; fds.fd_array[i] = 0; } fds.fd_count = 0; }
public static extern int select(Int32 nfds, ref fd_set readfds, IntPtr writefds, IntPtr exceptfds, ref timeval timeout);
public static extern unsafe int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout);
public override object Call(Class last_class, object recv, Frame caller, Proc block, object p1, Array rest) { object read, write = null, except = null, timeout = null; Array res, list; fd_set rset = new fd_set(), wset = new fd_set(), eset = new fd_set(), pset = new fd_set(); object rp, wp, ep; System.TimeSpan tp; IO fptr; int i; int max = 0; int interrupt_flag = 0; int pending = 0; Class.rb_scan_args(caller, rest, 1, 3, false); read = (Array)p1; if (rest.Count > 0) write = rest[0]; if (rest.Count > 1) except = rest[1]; if (rest.Count > 2) timeout = rest[2]; if (timeout == null) tp = System.TimeSpan.Zero; else tp = Time.rb_time_interval(timeout, caller); rset.fd_array = new int[64]; FD_ZERO(pset); if (read != null) { Object.CheckType<Array>(caller, read); rp = rset; FD_ZERO((fd_set)rp); for (i = 0; i < ((Array)read).Count; i++) { fptr = IO.GetOpenFile(caller, IO.rb_io_get_io(((Array)read)[i], caller)); FD_SET(IO.fileno(fptr.f), (fd_set)rp); if (IO.READ_DATA_PENDING(fptr.f)) { /* check for buffered data */ pending++; FD_SET(IO.fileno(fptr.f), pset); } if (max < IO.fileno(fptr.f)) max = IO.fileno(fptr.f); } if (pending > 0) { /* no blocking if there's buffered data */ tp = System.TimeSpan.Zero; } } else rp = null; if (write != null) { Object.CheckType<Array>(caller, write); wp = wset; FD_ZERO((fd_set)wp); for (i = 0; i < ((Array)write).Count; i++) { fptr = IO.GetOpenFile(caller, IO.rb_io_get_io(((Array)write)[i], caller)); FD_SET(IO.fileno(fptr.f), (fd_set)wp); if (max < IO.fileno(fptr.f)) max = IO.fileno(fptr.f); if (fptr.f2 != null) { FD_SET(IO.fileno(fptr.f2), (fd_set)wp); if (max < IO.fileno(fptr.f2)) max = IO.fileno(fptr.f2); } } } else wp = null; if (except != null) { Object.CheckType<Array>(caller, except); ep = eset; FD_ZERO((fd_set)ep); for (i = 0; i < ((Array)except).Count; i++) { fptr = IO.GetOpenFile(caller, IO.rb_io_get_io(((Array)except)[i], caller)); FD_SET(IO.fileno(fptr.f), (fd_set)ep); if (max < IO.fileno(fptr.f)) max = IO.fileno(fptr.f); if (fptr.f2 != null) { FD_SET(IO.fileno(fptr.f2), (fd_set)ep); if (max < IO.fileno(fptr.f2)) max = IO.fileno(fptr.f2); } } } else ep = null; max++; //n = rb_thread_select(max, rp, wp, ep, tp); //if (n < 0) //{ // rb_sys_fail(0); //} if (pending == 0) //&& n == 0) return null; /* returns nil on timeout */ res = new Array(); res.Tainted = true; Array rparr = new Array(), wparr = new Array(), eparr = new Array(); if (rp == null) rparr.Tainted = true; if (wp == null) wparr.Tainted = true; if (ep == null) eparr.Tainted = true; res.Add(rparr); res.Add(wparr); res.Add(eparr); if (interrupt_flag == 0) { if (rp != null) { list = rparr; for (i = 0; i < ((Array)read).Count; i++) { fptr = IO.GetOpenFile(caller, IO.rb_io_get_io(((Array)read)[i], caller)); if (FD_ISSET(IO.fileno(fptr.f), (fd_set)rp) || FD_ISSET(IO.fileno(fptr.f), pset)) { list.Add(((Array)read)[i]); } } } if (wp != null) { list = wparr; for (i = 0; i < ((Array)write).Count; i++) { fptr = IO.GetOpenFile(caller, IO.rb_io_get_io(((Array)write)[i], caller)); if (FD_ISSET(IO.fileno(fptr.f), (fd_set)wp)) { list.Add(((Array)write)[i]); } else if (fptr.f2 != null && FD_ISSET(IO.fileno(fptr.f2), (fd_set)wp)) { list.Add(((Array)write)[i]); } } } if (ep != null) { list = eparr; for (i = 0; i < ((Array)except).Count; i++) { fptr = IO.GetOpenFile(caller, IO.rb_io_get_io(((Array)except)[i], caller)); if (FD_ISSET(IO.fileno(fptr.f), (fd_set)ep)) { list.Add(((Array)except)[i]); } else if (fptr.f2 != null && FD_ISSET(IO.fileno(fptr.f2), (fd_set)ep)) { list.Add(((Array)except)[i]); } } } } return res; /* returns an empty array on interrupt */ }
private bool FD_ISSET(int fd, fd_set set) { for (int i = 0; i < set.fd_count; i++) if (set.fd_array[i] == fd) return true; return false; }
private void FD_ZERO(fd_set set) { set.fd_count = 0; set.fd_array = new int[FD_SETSIZE]; }
private void FD_SET(int fd, fd_set set) { set.fd_array[set.fd_count] = fd; set.fd_count++; }
private void FD_CLR(int fd, fd_set set) { for (int i = 0; i < set.fd_count; i++) if (set.fd_array[i] == fd) { for (; i < set.fd_count - 1; i++) set.fd_array[i] = set.fd_array[i + 1]; set.fd_array[set.fd_count - 1] = 0; set.fd_count = 0; return; } }