private unsafe void WriteArraySegmentInternal( UvStreamHandle handle, ArraySegment <ArraySegment <byte> > bufs, UvStreamHandle sendHandle, Action <UvWriteReq, int, UvException, object> callback, object state) { try { var pBuffers = (Uv.uv_buf_t *)_bufs; var nBuffers = bufs.Count; if (nBuffers > BUFFER_COUNT) { // create and pin buffer array when it's larger than the pre-allocated one var bufArray = new Uv.uv_buf_t[nBuffers]; var gcHandle = GCHandle.Alloc(bufArray, GCHandleType.Pinned); _pins.Add(gcHandle); pBuffers = (Uv.uv_buf_t *)gcHandle.AddrOfPinnedObject(); } for (var index = 0; index < nBuffers; index++) { // create and pin each segment being written var buf = bufs.Array[bufs.Offset + index]; var gcHandle = GCHandle.Alloc(buf.Array, GCHandleType.Pinned); _pins.Add(gcHandle); pBuffers[index] = Libuv.buf_init( gcHandle.AddrOfPinnedObject() + buf.Offset, buf.Count); } _callback = callback; _state = state; if (sendHandle == null) { _uv.write(this, handle, pBuffers, nBuffers, _uv_write_cb); } else { _uv.write2(this, handle, pBuffers, nBuffers, sendHandle, _uv_write_cb); } } catch { _callback = null; _state = null; UnpinGcHandles(); throw; } }
private static void UvReadCb(IntPtr handle, int status, ref Uv.uv_buf_t buf) { var stream = FromIntPtr <UvStreamHandle>(handle); try { stream._readCallback(stream, status, stream._readState); } catch (Exception ex) { stream._log.LogError(0, ex, "UbReadCb"); throw; } }
public Task StartAsync( string pipeName, byte[] pipeMessage) { _pipeName = pipeName; _pipeMessage = pipeMessage; _buf = _thread.Loop.Libuv.buf_init(_ptr, 4); DispatchPipe = new UvPipeHandle(Log); var tcs = new TaskCompletionSource <int>(this, TaskCreationOptions.RunContinuationsAsynchronously); _thread.Post(StartCallback, tcs); return(tcs.Task); }
private static void UvAllocCb(IntPtr handle, int suggested_size, out Uv.uv_buf_t buf) { var stream = FromIntPtr <UvStreamHandle>(handle); try { buf = stream._allocCallback(stream, suggested_size, stream._readState); } catch (Exception ex) { stream._log.LogError(0, ex, "UvAllocCb"); buf = stream.Libuv.buf_init(IntPtr.Zero, 0); throw; } }
private unsafe void Write( UvStreamHandle handle, ReadOnlySequence <byte> buffer, Action <UvWriteReq, int, UvException, object> callback, object state) { try { var nBuffers = 0; if (buffer.IsSingleSegment) { nBuffers = 1; } else { foreach (var _ in buffer) { nBuffers++; } } var pBuffers = (Uv.uv_buf_t *)_bufs; if (nBuffers > BUFFER_COUNT) { // create and pin buffer array when it's larger than the pre-allocated one var bufArray = new Uv.uv_buf_t[nBuffers]; var gcHandle = GCHandle.Alloc(bufArray, GCHandleType.Pinned); _pins.Add(gcHandle); pBuffers = (Uv.uv_buf_t *)gcHandle.AddrOfPinnedObject(); } if (nBuffers == 1) { var memory = buffer.First; var memoryHandle = memory.Pin(); _handles.Add(memoryHandle); // Fast path for single buffer pBuffers[0] = Libuv.buf_init( (IntPtr)memoryHandle.Pointer, memory.Length); } else { var index = 0; foreach (var memory in buffer) { // This won't actually pin the buffer since we're already using pinned memory var memoryHandle = memory.Pin(); _handles.Add(memoryHandle); // create and pin each segment being written pBuffers[index] = Libuv.buf_init( (IntPtr)memoryHandle.Pointer, memory.Length); index++; } } _callback = callback; _state = state; _uv.write(this, handle, pBuffers, nBuffers, _uv_write_cb); } catch { _callback = null; _state = null; UnpinGcHandles(); throw; } }
public int TryWrite(Uv.uv_buf_t buf) { return(_uv.try_write(this, new[] { buf }, 1)); }