/// <summary> /// Defeats the protocol by removing the file and replacing it with one that contains the /// new process identifier - /// </summary> /// <param name="sem">A FileSempahore</param> /// <returns>True if successfull.</returns> private static bool ForceLock(ref FileSemaphore sem) { if (sem.RemoveLock() == false) { return(false); } return(Lock(ref sem)); }
/// <summary> /// <para>Write to the log file in such a way so as to avoid collisions in updating same.</para> /// <para>NOTE: THIS PROCESS USES LockWait. IF YOU ARE USING IT ACROSS MACHINES, THERE IS A SLIGHT CHANCE /// THAT YOUR PROCESS ID WILL NOT BE UNIQUE. CAVEAT USER.</para> /// </summary> /// <param name="sMessage">The message to write.</param> /// <returns>True if the log file was written.</returns> public bool LogWait(string sMessage) { bool br = false; if (FileSemaphore.LockWait(ref fSem) == true) { if (SimpleLog.Log(sMessage) != null) { br = true; } FileSemaphore.UnLock(ref fSem); } return(br); }
/// <summary> /// Lock a semaphore file. You can only UnLock a semaphore that either does not exists, or that your process /// has previously Locked. /// </summary> /// <param name="sem">A semaphore file (context)</param> /// <returns>True if the semaphore file was released.</returns> public static bool UnLock(ref FileSemaphore sem) { // STEP: If the semaphore file is not there, then the resource is unlocked. if (sem.IsLocked() == false) { return(true); } // STEP: The general public can ONLY remove a semaphore file IF it is theirs if (sem.iSemCode == sem.GetSemaphore()) { return(sem.RemoveLock()); } // Otherwise the user CANNOT unlock it! return(false); }
/// <summary> /// You can only Lock a file if the semaphore file does not exist. /// Use LockWait if you want to honor the timeout mechanism - otherwise /// it is COMPLETELY ignored - /// </summary> /// <param name="sem">A semaphore file (context)</param> /// <returns>Returns true if the semaphore was updated to your process ID.</returns> public static bool Lock(ref FileSemaphore sem) { // STEP: If it is locked, see if we have locked it - if (sem.IsLocked() == true) { int iResult = sem.GetSemaphore(); // See if it is already locked - by us if (iResult == sem.iSemCode) { return(true); } // See if it was just removed - if (iResult != 0) { return(false); } } // STEP: Lock it - return(sem.SetSemaphore(sem.iSemCode)); }
/// <summary> /// The ONLY place where the lock timeous is honored. /// </summary> /// <param name="sem">A semaphore file (context)</param> /// <returns>True when you are able to obtain a lock.</returns> public static bool LockWait(ref FileSemaphore sem) { if (sem.IsLocked()) { DateTime dtMax = DateTime.Now; // DESIRED: No matter who has locked it (even us!), ForceLock the // file if it has been around longer that it should have been - // - OBSERVED - // This is an odd fish - Sometimes the test case reports that // the file was written (or created) when we actually did so, // other times it just seems to take the value for the last // time the inode was created / written to... This type of // recovery is not on the critical path the moment, so we will // move on - // TODO: Resolve or report the above issue. /* * DateTime dtActual = File.GetLastWriteTime(sem.sFQSemFile); * dtActual = dtActual.AddSeconds(sem.dSec); * if(dtActual < dtMax) * return ForceLock(ref sem); */ // Set the most recent time to the future - dtMax = dtMax.AddSeconds(sem.dSec); // Prime the semaphore that we need to start timing - int iHasIt = sem.GetSemaphore(); // STEP: If we have locked it, then just leave it - if (iHasIt == sem.iSemCode) { return(true); } // STEP: Block while there is a lock file -OR- until a // process has locked the recource for the specified // recource timeout limit - while (sem.IsLocked() == true) { int iPeek = sem.GetSemaphore(); if (iPeek == 0) { continue; } if (iPeek == iHasIt) { if (DateTime.Now > dtMax) { return(ForceLock(ref sem)); // Time to FORCE the issue - } } else { dtMax = DateTime.Now; dtMax.AddSeconds(sem.dSec); } } } // STEP: The file is no longer there - Lock it - return(Lock(ref sem)); }
/// <summary> /// Use this constructor to share a log file ACROSS MANY machines AND operating systems. /// It allows you to place a file AND it's locking mechanism wherever you have access /// (across a LAN, etc.) /// </summary> /// <param name="sFQFileName">A fully qualified file log name.</param> public SharedSimpleLog(string sFQFileName) { log.FileName = sFQFileName; fSem = new FileSemaphore(log.FileName); }
/// <summary> /// Use this constructor to allow processes on the SAME MACHINE to share a MACHINE NAMED logging file. /// The file will be placed in the CURRENT DIRECTORY. /// </summary> public SharedSimpleLog() { fSem = new FileSemaphore(log.FileName); }