void WriteContinuation(int messageSize) { // First, allocate a new buffer: string newName = Name + "." + ++m_BufferCount; int newLength = Math.Max(messageSize * 10, MinimumBufferSize); var newFile = new SafeMemoryMappedFile(MemoryMappedFile.CreateNew(newName, newLength, MemoryMappedFileAccess.ReadWrite)); Trace.WriteLine($"Allocated new buffer of {newLength} bytes"); // Write a message to the old buffer indicating the address of the new buffer: WriteMessage(new byte[0]); // Keep the old buffer alive until the reader has indicated that it's seen it: m_OldBuffers.Add(Buffer); // Make the new buffer current: Buffer = newFile; Length = newFile.Length; Offset = StartingOffset; // Release old buffers that have been read: foreach (var buffer in m_OldBuffers.Take(m_OldBuffers.Count - 1).ToArray()) { lock (buffer.NoDisposeWhileLocked) { if (!buffer.Disposed && buffer.Accessor.ReadBoolean(4)) { m_OldBuffers.Remove(buffer); buffer.Dispose(); Trace.WriteLine("Cleaned file"); } } } }
protected MutexFreePipe(string name, bool createBuffer) { Name = name; var mmFile = createBuffer ? MemoryMappedFile.CreateNew(String.Concat(name, INITIAL_FILE_EXT), MinimumBufferSize, MemoryMappedFileAccess.ReadWrite) : MemoryMappedFile.OpenExisting(String.Concat(name, INITIAL_FILE_EXT)); Buffer = new SafeMemoryMappedFile(mmFile); NewMessageSignal = new EventWaitHandle(false, EventResetMode.AutoReset, String.Concat(name, ".signal")); Length = Buffer.Length; Offset = StartingOffset; }
unsafe byte[] GetNextMessage() { m_LastMessageProcessed++; lock (NoDisposeWhileLocked) { if (Disposed) { return(null); } lock (Buffer.NoDisposeWhileLocked) { if (Buffer.Disposed) { return(null); } byte *offsetPointer = Buffer.Pointer + Offset; var msgPointer = (int *)offsetPointer; int msgLength = *msgPointer; Offset += MessageHeaderLength; offsetPointer += MessageHeaderLength; if (msgLength == 0) { Buffer.Accessor.Write(4, true); // Signal that we no longer need file Buffer.Dispose(); string newName = Name + "." + ++m_BufferCount; Buffer = new SafeMemoryMappedFile(MemoryMappedFile.OpenExisting(newName)); Offset = StartingOffset; return(new byte[0]); } Offset += msgLength; //MMF.Accessor.ReadArray (Offset, msg, 0, msg.Length); // too slow var msg = new byte[msgLength]; Marshal.Copy(new IntPtr(offsetPointer), msg, 0, msg.Length); return(msg); } } }