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()); }
void CallMeOnEvent(Oars.Events events, Action act) { _host.Sync(() => { lock (this) { var ev = new Oars.Event(_host._eventBase, _socket, events); _activeEvents.Add(ev); ev.Activated += () => { lock (this) { ev.Delete(); ev.Dispose(); act(); _activeEvents.Remove(ev); } }; ev.Add(new TimeSpan(7, 1, 1, 1)); } }); }