示例#1
0
 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;
 }
示例#2
0
        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;
        }