//~FileManager() //{ // Dispose(); //} public void Dispose() { foreach (var viewWrap in _allWraps) { viewWrap._va.Dispose(); } _vw.Dispose(); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); try { FileMutex.WaitOne(); CloseMapFile(); if (PersistenceMode == PersistenceMode.TemporaryPersist) { var count = _tempSemaphore.Release(); // if no more access to the file, then delete it if (count == _MAX_SHARED_ACCESS - 1) { DeleteBackingFileIfExists(_fileName); } _tempSemaphore.Dispose(); } } finally { FileMutex.ReleaseMutex(); } FileMutex.Dispose(); }
protected virtual void Dispose(bool disposing) { if (disposing) { foreach (var viewWrap in _allWraps) { viewWrap._va.Dispose(); } _vw.Dispose(); } try { FileMutex.WaitOne(); CloseMapFile(); if (PersistenceMode == PersistenceMode.TemporaryPersist) { var count = _tempSemaphore.Release(); // if no more access to the file, then delete it if (count == _MAX_SHARED_ACCESS - 1) { DeleteBackingFileIfExists(_fileName); } _tempSemaphore.Dispose(); } } finally { FileMutex.ReleaseMutex(); } FileMutex.Dispose(); }
private void AppendToFile(string fileName, string appendString) { FileMutex.WaitOne(); using (StreamWriter w = File.AppendText(fileName)) { w.WriteLine(appendString); } FileMutex.ReleaseMutex(); }
protected virtual void Init() { CheckRuntimeCompatibility(); isClosed = false; isLocal = baseIdentification.IsLocal(); // The check if it is a new Database must be executed before object // writer initialization. Because Object Writer Init // Creates the file so the check (which is based on the file existence // would always return false*/ bool isNewDatabase = IsNewDatabase(); commitListeners = new OdbArrayList <ICommitListener>(); classIntrospector = provider.GetClassIntrospector(); ISession session = BuildDefaultSession(); // Object Writer must be created before object Reader objectWriter = BuildObjectWriter(); // Object writer is a two Phase init object objectWriter.Init2(); objectReader = BuildObjectReader(); AddSession(session, false); // If the file does not exist, then a default header must be created if (isNewDatabase) { objectWriter.CreateEmptyDatabaseHeader(OdbTime.GetCurrentTimeInMs(), baseIdentification.GetUserName(), baseIdentification.GetPassword()); } else { try { GetObjectReader().ReadDatabaseHeader(baseIdentification.GetUserName(), baseIdentification.GetPassword()); } catch (ODBAuthenticationRuntimeException e) { Close(); throw; } } objectWriter.AfterInit(); objectIntrospector = BuildObjectIntrospector(); this.triggerManager = BuildTriggerManager(); // This forces the initialization of the meta model MetaModel metaModel = GetMetaModel(); if (OdbConfiguration.CheckModelCompatibility()) { CheckMetaModelCompatibility(classIntrospector.Instrospect(metaModel.GetAllClasses())); } // logically locks access to the file (only for this Virtual machine) FileMutex.GetInstance().OpenFile(GetStorageDeviceName()); // Updates the Transaction Id in the file objectWriter.WriteLastTransactionId(GetCurrentTransactionId()); this.objectWriter.SetTriggerManager(this.triggerManager); this.introspectionCallbackForInsert = new DefaultInstrumentationCallbackForStore(this, triggerManager, false); this.introspectionCallbackForUpdate = new DefaultInstrumentationCallbackForStore(this, triggerManager, true); }
public ServerFileMutexPair(string mutexName, bool initiallyOwned, out bool createdNew) { AliveMutex = new FileMutex(mutexName + "-alive"); HeldMutex = new FileMutex(mutexName + "-held"); createdNew = AliveMutex.TryLock(0); if (initiallyOwned && createdNew) { if (!TryLock(0)) { throw new Exception("Failed to lock mutex after creating it"); } } }
public void TestMakeMutexName() { Debug.WriteLine("TEST START: TestMakeMutexName"); const string namePrefix = FileMutex.MutexNamePrefix; // This is why the relative path should be in its normal form // Calling Write("root/subroot/file.bin") and Write("root/subroot/../subroot/file.bin") from two different threads // will result in acquiring two different mutexes and therefore possible race conditions Assert.AreEqual(FileMutex.MakeMutexName("root/subroot/file.bin"), namePrefix + "root/subroot/file.bin"); Assert.AreEqual( FileMutex.MakeMutexName("root/subroot/../subroot/file.bin"), namePrefix + "root/subroot/../subroot/file.bin"); // All path formats get converted to the generic form (which uses '/' as a delimiter) Assert.AreEqual(FileMutex.MakeMutexName("root\\subroot\\file.bin"), namePrefix + "root/subroot/file.bin"); Assert.AreEqual( FileMutex.MakeMutexName("root\\subroot\\..\\subroot\\file.bin"), namePrefix + "root/subroot/../subroot/file.bin"); }
/// <summary> /// Grow the array to support more data /// </summary> /// <param name="requiredMinCapacity">The size to grow from</param> public void EnsureCapacity(long requiredMinCapacity) { Trace.Assert(requiredMinCapacity > 0); // catch int overflow if there is more than one fixed in Backing constructor if (Capacity >= requiredMinCapacity) { return; } FileMutex.WaitOne(); try { switch (PersistenceMode) { case PersistenceMode.Persist: case PersistenceMode.TemporaryPersist: var oldSize = Capacity; var newCapacity = (long)(oldSize * ((100F + _GROW_PERCENTAGE) / 100F)); Capacity = newCapacity < requiredMinCapacity ? requiredMinCapacity : newCapacity; CloseMapFile(); Trace.Assert(Mmf == null); Mmf = CreateOrOpenFile(_fileName, Capacity, PersistenceMode, FileMutex, true); // recreate views so that unsafe r/w on already created wrap do not throw foreach (var viewWrap in _vw.Values) { viewWrap._va.Dispose(); viewWrap._va = Mmf.CreateViewAccessor(); } break; case PersistenceMode.Ephemeral: throw new NotSupportedException("In-memory MMFs do not support resizing. Set initial capacity large enough, only actually used memory will be consumed from RAM"); default: throw new ArgumentOutOfRangeException(); } } finally { FileMutex.ReleaseMutex(); } }