void WriteContinuation(int messageSize)
        {
            // First, allocate a new buffer:
            string newName   = Name + "." + ++_bufferCount;
            int    newLength = Math.Max(messageSize * 10, MinimumBufferSize);
            var    newFile   = new SafeMemoryMappedFile(MemoryMappedFile.CreateNew(newName, newLength, MemoryMappedFileAccess.ReadWrite));

            Console.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:
            _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 _oldBuffers.Take(_oldBuffers.Count - 1).ToArray())
            {
                lock (buffer.DisposeLock)
                    if (!buffer.IsDisposed && buffer.Accessor.ReadBoolean(4))
                    {
                        _oldBuffers.Remove(buffer);
                        buffer.Dispose();
                        Console.WriteLine("Cleaned file");
                    }
            }
        }
        protected MutexFreePipe(string name, bool createBuffer)
        {
            Name = name;

            var mmFile = createBuffer
                ? MemoryMappedFile.CreateNew(name + ".0", MinimumBufferSize, MemoryMappedFileAccess.ReadWrite)
                : MemoryMappedFile.OpenExisting(name + ".0");

            Buffer           = new SafeMemoryMappedFile(mmFile);
            NewMessageSignal = new EventWaitHandle(false, EventResetMode.AutoReset, name + ".signal");

            Length = Buffer.Length;
            Offset = StartingOffset;
        }
        unsafe byte[] GetNextMessage()
        {
            _lastMessageProcessed++;

            lock (DisposeLock)
            {
                if (IsDisposed)
                {
                    return(null);
                }

                lock (Buffer.DisposeLock)
                {
                    if (Buffer.IsDisposed)
                    {
                        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 + "." + ++_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);
                }
            }
        }