public const int SYS_SENDMMSG = 20; /* sys_sendmmsg(2) */ public static int Poll(Thread current, ref Arch.ExceptionRegisters regs, UserPtr fds, int nfds, int timeout) { if (nfds < 0) { return(-ErrorCode.EINVAL); } var pollfd_size = pollfd.Size * nfds; var buf = Globals.AllocateAlignedCompletionBuffer(pollfd_size); if (!buf.isValid) { return(-ErrorCode.ENOMEM); } var poll_entry = new PollCompletion(current, fds, nfds, buf); if (fds.Read(current, buf, pollfd_size) != 0) { poll_entry.Dispose(); return(-ErrorCode.EFAULT); } Contract.Assert(buf.Length >= pollfd_size); if (!TranslateToLinuxFd(current, poll_entry, buf)) { poll_entry.Dispose(); return(-ErrorCode.EBADF); } var ret = Arch.IPCStubs.PollAsync(current.Parent.helperPid, current.impl._value.thread._value, new Pointer(buf.Location), nfds, timeout); if (ret < 0) { poll_entry.Dispose(); return(ret); } Globals.CompletionQueue.Enqueue(poll_entry); current.SaveState(ref regs); current.AsyncReturn = true; return(0); }
public static void HandlePollAsync(PollCompletion entry, int ret) { var current = entry.thr; var proc = current.Parent; if (ret <= 0) { entry.Dispose(); current.ReturnFromCompletion(ret); return; } var b = entry.buf; if (b.Length < ret * pollfd.Size) { ret = -ErrorCode.ENOMEM; entry.Dispose(); current.ReturnFromCompletion(ret); Utils.Panic(); return; } // Translate fds back into fd in ExpressOS for (var i = 0; i < ret; ++i) { Contract.Assert(i < ret && ret * pollfd.Size <= b.Length); Contract.Assert(i + 1 <= ret && (i + 1) * pollfd.Size <= ret * pollfd.Size); Contract.Assert((i + 1) * pollfd.Size <= ret * pollfd.Size && ret * pollfd.Size <= b.Length); var poll_struct = pollfd.Deserialize(b, i * pollfd.Size); var expressos_fd = -1; for (var j = 0; j < entry.fdMaps.Length; ++j) { var file = proc.LookupFile(entry.fdMaps[j]); if (file == null) continue; if (file.inode.LinuxFd == poll_struct.fd) { expressos_fd = entry.fdMaps[j]; break; } } if (expressos_fd == -1) { // DEBUG Arch.Console.Write("poll_async: cannot find ExpressOS fd for fd "); Arch.Console.Write(poll_struct.fd); Arch.Console.Write(" i="); Arch.Console.Write(i); Arch.Console.Write(" poll_ret="); Arch.Console.Write(ret); Arch.Console.Write(" nfds="); Arch.Console.Write(entry.fdMaps.Length); Arch.Console.WriteLine(); ret = -ErrorCode.EBADF; break; } // Write result back var p_user_entry = entry.userFdBuf + i * pollfd.Size; p_user_entry.Write(current, expressos_fd); (p_user_entry + pollfd.OFFSET_OF_REVENTS).Write(current, poll_struct.revents); } entry.Dispose(); current.ReturnFromCompletion(ret); }
public static void HandlePollAsync(PollCompletion entry, int ret) { var current = entry.thr; var proc = current.Parent; if (ret <= 0) { entry.Dispose(); current.ReturnFromCompletion(ret); return; } var b = entry.buf; if (b.Length < ret * pollfd.Size) { ret = -ErrorCode.ENOMEM; entry.Dispose(); current.ReturnFromCompletion(ret); Utils.Panic(); return; } // Translate fds back into fd in ExpressOS for (var i = 0; i < ret; ++i) { Contract.Assert(i < ret && ret * pollfd.Size <= b.Length); Contract.Assert(i + 1 <= ret && (i + 1) * pollfd.Size <= ret * pollfd.Size); Contract.Assert((i + 1) * pollfd.Size <= ret * pollfd.Size && ret * pollfd.Size <= b.Length); var poll_struct = pollfd.Deserialize(b, i * pollfd.Size); var expressos_fd = -1; for (var j = 0; j < entry.fdMaps.Length; ++j) { var file = proc.LookupFile(entry.fdMaps[j]); if (file == null) { continue; } if (file.inode.LinuxFd == poll_struct.fd) { expressos_fd = entry.fdMaps[j]; break; } } if (expressos_fd == -1) { // DEBUG Arch.Console.Write("poll_async: cannot find ExpressOS fd for fd "); Arch.Console.Write(poll_struct.fd); Arch.Console.Write(" i="); Arch.Console.Write(i); Arch.Console.Write(" poll_ret="); Arch.Console.Write(ret); Arch.Console.Write(" nfds="); Arch.Console.Write(entry.fdMaps.Length); Arch.Console.WriteLine(); ret = -ErrorCode.EBADF; break; } // Write result back var p_user_entry = entry.userFdBuf + i * pollfd.Size; p_user_entry.Write(current, expressos_fd); (p_user_entry + pollfd.OFFSET_OF_REVENTS).Write(current, poll_struct.revents); } entry.Dispose(); current.ReturnFromCompletion(ret); }
public static int Poll(Thread current, ref Arch.ExceptionRegisters regs, UserPtr fds, int nfds, int timeout) { if (nfds < 0) return -ErrorCode.EINVAL; var pollfd_size = pollfd.Size * nfds; var buf = Globals.AllocateAlignedCompletionBuffer(pollfd_size); if (!buf.isValid) return -ErrorCode.ENOMEM; var poll_entry = new PollCompletion(current, fds, nfds, buf); if (fds.Read(current, buf, pollfd_size) != 0) { poll_entry.Dispose(); return -ErrorCode.EFAULT; } Contract.Assert(buf.Length >= pollfd_size); if (!TranslateToLinuxFd(current, poll_entry, buf)) { poll_entry.Dispose(); return -ErrorCode.EBADF; } var ret = Arch.IPCStubs.PollAsync(current.Parent.helperPid, current.impl._value.thread._value, new Pointer(buf.Location), nfds, timeout); if (ret < 0) { poll_entry.Dispose(); return ret; } Globals.CompletionQueue.Enqueue(poll_entry); current.SaveState(ref regs); current.AsyncReturn = true; return 0; }