Task <int> DoSocketOpAsync(SocketIO.SocketOp op, Oars.Events events, byte[] buffer, int offset, int size) { lock (this) { if (_socket == IntPtr.Zero) { throw new InvalidOperationException("Socket is closed or disposed"); } var segment = new ArraySegment <byte> (buffer, offset, size); var read = op(_socket, segment, SocketIO.MSG_DONTWAIT); if (read == -1) { var errno = Marshal.GetLastWin32Error(); if (errno != Errno.EAGAIN) { if (errno == Errno.EPIPE && events == Oars.Events.EV_READ) { return(TaskFromResult(0)); } throw new IOException("Error #" + errno + " on socket"); } var tcs = new TaskCompletionSource <int> (); CallMeOnEvent(events, () => { read = op(_socket, segment, SocketIO.MSG_DONTWAIT); if (read != -1) { tcs.SetResult(read); return; } errno = Marshal.GetLastWin32Error(); if (errno == Errno.EPIPE && events == Oars.Events.EV_READ) { tcs.SetResult(0); } else { tcs.SetException(new IOException("Error #" + errno + " on socket")); } }); return(tcs.Task); } else { return(TaskFromResult(read)); } } }
Task <int> DoSocketOpAsyncWithCheck(SocketIO.SocketOp op, Oars.Events events, byte[] buffer, int offset, int size) { lock (this) { if (_busy) { throw new InvalidOperationException("Busy"); } _busy = true; } return(DoSocketOpAsync(op, events, buffer, offset, size).ContinueWith(t => { lock (this) { _busy = false; } return TaskFromResult(t.Result); }).Unwrap()); }