private static int Recv(Thread current, ref Arch.ExceptionRegisters regs, UserPtr ptr_label, UserPtr userBuf, uint size) { Contract.Requires(current.VBinderState.Owner == current); if (!current.Parent.Space.VerifyWrite(userBuf, size) || !current.Parent.Space.VerifyWrite(ptr_label, sizeof(int))) { return(-ErrorCode.EFAULT); } var b = current.VBinderState.NoPendingMessages(); if (b) { var entry = new VBinderCompletion(current, ptr_label, userBuf, size); current.VBinderState.Completion = entry; current.SaveState(ref regs); current.AsyncReturn = true; return(0); } else { var msg = current.VBinderState.TakeMessage(); Contract.Assert(msg.GhostTarget == current); var length = msg.Length; ptr_label.Write(current.Parent, msg.label); userBuf.Write(current, new Pointer(msg.payload.Location), length); msg.Recycle(); return(length); } }
private static int Recv(Thread current, ref Arch.ExceptionRegisters regs, UserPtr ptr_label, UserPtr userBuf, uint size) { Contract.Requires(current.VBinderState.Owner == current); if (!current.Parent.Space.VerifyWrite(userBuf, size) || !current.Parent.Space.VerifyWrite(ptr_label, sizeof(int))) return -ErrorCode.EFAULT; var b = current.VBinderState.NoPendingMessages(); if (b) { var entry = new VBinderCompletion(current, ptr_label, userBuf, size); current.VBinderState.Completion = entry; current.SaveState(ref regs); current.AsyncReturn = true; return 0; } else { var msg = current.VBinderState.TakeMessage(); Contract.Assert(msg.GhostTarget == current); var length = msg.Length; ptr_label.Write(current.Parent, msg.label); userBuf.Write(current, new Pointer(msg.payload.Location), length); msg.Recycle(); return length; } }