public SelectCompletion(Thread current, int maxfds, UserPtr inp, UserPtr outp, UserPtr exp, SelectHelper helper, ByteBufferRef buf) : base(current, Kind.SelectCompletionKind, buf) { this.fds = maxfds; this.inp = inp; this.outp = outp; this.exp = exp; this.helper = helper; }
public static int Select(Thread current, ref Arch.ExceptionRegisters regs, int maxfds, UserPtr inp, UserPtr outp, UserPtr exp, UserPtr tvp) { var helper = new SelectHelper(); int ret = 0; ret = helper.AddUserFdList(current, inp, maxfds, POLLIN); if (ret < 0) return ret; ret = helper.AddUserFdList(current, outp, maxfds, POLLOUT); if (ret < 0) return ret; ret = helper.AddUserFdList(current, exp, maxfds, POLLERR); if (ret < 0) return ret; int timeout = 0; timeval tv; if (tvp == UserPtr.Zero) { timeout = -1; } else if (tvp.Read(current, out tv) != 0) { return -ErrorCode.EFAULT; } else { timeout = (int)(tv.tv_sec * 1000 + tv.tv_usec / 1000); } var nfds = helper.TotalFds; var pollfd_size = pollfd.Size * nfds; var buf = Globals.AllocateAlignedCompletionBuffer(pollfd_size); if (!buf.isValid) return -ErrorCode.ENOMEM; helper.WritePollFds(buf); var select_entry = new SelectCompletion(current, maxfds, inp, outp, exp, helper, buf); ret = Arch.IPCStubs.PollAsync(current.Parent.helperPid, current.impl._value.thread._value, new Pointer(buf.Location), nfds, timeout); if (ret < 0) { select_entry.Dispose(); return ret; } Globals.CompletionQueue.Enqueue(select_entry); current.SaveState(ref regs); current.AsyncReturn = true; return 0; }