/// <summary> /// Instanciate a new Interprocess Mailbox. /// </summary> /// <param name="name">The name for the Win32 semaphores and the shared memory file.</param> /// <param name="size">The size of the shared memory in terms of bytes.</param> public ProcessMailBox(string name, int size) { empty = new ProcessSemaphore(name + ".EmptySemaphore.MailBox", 1, 1); full = new ProcessSemaphore(name + ".FullSemaphore.MailBox", 0, 1); file = MemoryMappedFile.CreateFile(name + ".MemoryMappedFile.MailBox", MemoryMappedFile.FileAccess.ReadWrite, size); view = file.CreateView(0, size, MemoryMappedFileView.ViewAccess.ReadWrite); }
/// <summary> /// Instanciate a new Interprocess Mailbox. /// </summary> /// <param name="name">The name for the Win32 semaphores and the shared memory file.</param> /// <param name="size">The size of the shared memory in terms of bytes.</param> public ProcessMailBox(string name,int size) { empty = new ProcessSemaphore(name+".EmptySemaphore.MailBox",1,1); full = new ProcessSemaphore(name+".FullSemaphore.MailBox",0,1); file = MemoryMappedFile.CreateFile(name+".MemoryMappedFile.MailBox",MemoryMappedFile.FileAccess.ReadWrite,size); view = file.CreateView(0,size,MemoryMappedFileView.ViewAccess.ReadWrite); }
/// <summary> /// Instanciates an Inter-Process message channel. /// </summary> /// <param name="size">The count of messages the channel can queue before it blocks.</param> /// <param name="name">The channel's name. Must be the same for all instances using this channel.</param> /// <param name="maxBytesPerEntry">The maximum serialized message size in terms of bytes. Must be the same for all instances using this channel.</param> public ProcessChannel( int size, string name, int maxBytesPerEntry) { int fileSize = 64+size*maxBytesPerEntry; empty = new ProcessSemaphore(name+".EmptySemaphore.Channel",size,size); full = new ProcessSemaphore(name+".FullSemaphore.Channel",0,size); mutex = new ProcessSemaphore(name+".MutexSemaphore.Channel",1,1); file = MemoryMappedFile.CreateFile(name+".MemoryMappedFile.Channel",MemoryMappedFile.FileAccess.ReadWrite,fileSize); view = file.CreateView(0,fileSize,MemoryMappedFileView.ViewAccess.ReadWrite); queue = new MemoryMappedQueue(view,size,maxBytesPerEntry,true,0); if(queue.Length < size || queue.BytesPerEntry < maxBytesPerEntry) throw new MemoryMappedArrayFailedException(); }
/// <summary> /// Instanciate a new memory mapped array for inter-process access. /// </summary> /// <param name="view">The memory mapped file view.</param> /// <param name="length">The count of entries of the array.</param> /// <param name="bytesPerEntry">The (maximal) count of bytes per entry.</param> /// <param name="cooperative"> /// If true, it accepts other length and bytesPerEntry if the array already exists. /// If falls it throws an exception if the array already exists but with other length or bytesPerEntry. /// </param> /// <param name="offset">An optional initial positive offset before the array starts.</param> public MemoryMappedQueue(MemoryMappedFileView view, int length, int bytesPerEntry, bool cooperative, int offset) { this.headerOffset = offset; this.view = view; this.array = new MemoryMappedArray(view,length,bytesPerEntry,cooperative,offset+16); this.length = array.Length; if(StatusOnline != QueueStatus.Initialized) { InOnline = 0; OutOnline = 0; CountOnline = 0; StatusOnline = QueueStatus.Initialized; } }
/// <summary> /// Instanciates an Inter-Process message channel. /// </summary> /// <param name="size">The count of messages the channel can queue before it blocks.</param> /// <param name="name">The channel's name. Must be the same for all instances using this channel.</param> /// <param name="maxBytesPerEntry">The maximum serialized message size in terms of bytes. Must be the same for all instances using this channel.</param> public ProcessChannel(int size, string name, int maxBytesPerEntry) { int fileSize = 64 + size * maxBytesPerEntry; empty = new ProcessSemaphore(name + ".EmptySemaphore.Channel", size, size); full = new ProcessSemaphore(name + ".FullSemaphore.Channel", 0, size); mutex = new ProcessSemaphore(name + ".MutexSemaphore.Channel", 1, 1); file = MemoryMappedFile.CreateFile(name + ".MemoryMappedFile.Channel", MemoryMappedFile.FileAccess.ReadWrite, fileSize); view = file.CreateView(0, fileSize, MemoryMappedFileView.ViewAccess.ReadWrite); queue = new MemoryMappedQueue(view, size, maxBytesPerEntry, true, 0); if (queue.Length < size || queue.BytesPerEntry < maxBytesPerEntry) { throw new MemoryMappedArrayFailedException(); } }
/// <summary> /// Instanciate a new memory mapped array for inter-process access. /// </summary> /// <param name="view">The memory mapped file view.</param> /// <param name="length">The count of entries of the array.</param> /// <param name="bytesPerEntry">The (maximal) count of bytes per entry.</param> /// <param name="cooperative"> /// If true, it accepts other length and bytesPerEntry if the array already exists. /// If falls it throws an exception if the array already exists but with other length or bytesPerEntry. /// </param> /// <param name="offset">An optional initial positive offset before the array starts.</param> public MemoryMappedQueue(MemoryMappedFileView view, int length, int bytesPerEntry, bool cooperative, int offset) { this.headerOffset = offset; this.view = view; this.array = new MemoryMappedArray(view, length, bytesPerEntry, cooperative, offset + 16); this.length = array.Length; if (StatusOnline != QueueStatus.Initialized) { InOnline = 0; OutOnline = 0; CountOnline = 0; StatusOnline = QueueStatus.Initialized; } }
/// <summary> /// Instanciate a new memory mapped array for inter-process access. /// </summary> /// <param name="view">The memory mapped file view.</param> /// <param name="length">The count of entries of the array.</param> /// <param name="bytesPerEntry">The (maximal) count of bytes per entry.</param> /// <param name="cooperative"> /// If true, it accepts other length and bytesPerEntry if the array already exists. /// If falls it throws an exception if the array already exists but with other length or bytesPerEntry. /// </param> /// <param name="offset">An optional initial positive offset before the array starts.</param> /// <remarks>All members are neither thread-safe nor process-safe! It's up to you to synchronize access.</remarks> public MemoryMappedArray(MemoryMappedFileView view, int length, int bytesPerEntry, bool cooperative, int offset) { this.headerOffset = offset; this.firstOffset = 12 + offset; this.view = view; if (StatusOnline == ArrayStatus.Initialized) { //Already exists. Check compatibility. if (LengthOnline != length || BytesPerEntryOnline != bytesPerEntry) { if (cooperative) { //Accept other parameters. this.length = LengthOnline; this.bytesPerEntry = BytesPerEntryOnline; return; } else { throw new MemoryMappedArrayFailedException(); } } } else { //New Array. Initialize. int bytesNeeded = length * bytesPerEntry; if (bytesNeeded + firstOffset > view.Size) { throw new MemoryMappedArrayFailedException(); } LengthOnline = length; BytesPerEntryOnline = bytesPerEntry; StatusOnline = ArrayStatus.Initialized; } this.length = length; this.bytesPerEntry = bytesPerEntry; }
/// <summary> /// Create a view of the memory mapped file, allowing to read/write bytes. /// </summary> /// <param name="offset">An optional offset to the file.</param> /// <param name="size">The size of the view in terms of bytes.</param> /// <param name="access">Whether you need write access to the view.</param> /// <returns>A MemoryMappedFileView instance representing the view.</returns> public MemoryMappedFileView CreateView(int offset, int size, MemoryMappedFileView.ViewAccess access) { if(this.access == FileAccess.ReadOnly && access == MemoryMappedFileView.ViewAccess.ReadWrite) throw new ArgumentException("Only read access to views allowed on files without write access","access"); if(offset < 0) throw new ArgumentException("Offset must not be negative","size"); if(size < 0) throw new ArgumentException("Size must not be negative","size"); IntPtr mappedView = NTKernel.MapViewOfFile(fileMapping,(uint)access,0,(uint)offset,(uint)size); return new MemoryMappedFileView(mappedView,size,access); }