void SampleALibReport() { Console.WriteLine("Sample: ALib Report via using ALox"); Log.AddDebugLogger(); Log.SetDomain("/SAMPLE", Scope.Filename); Log.SetVerbosity(Log.DebugLogger, Verbosity.Info, ""); Log.Info("Method \"Log.AddDebugLogger()\" by default creates a replacement for ALibs'\n" + "error/warning reporter. If this is a debug compiliation, let's have a try and\n" + "create 3 Messages:"); Report.GetDefault().PushHaltFlags(false, false); ALIB.ERROR("This is an error report!"); ALIB.WARNING("And this is a warning!"); AString illegalAccess = new AString(10); illegalAccess._("1234"); illegalAccess.SetCharAt_NC(5, '5'); Report.GetDefault().PopHaltFlags(); Log.SetVerbosity(Log.DebugLogger, Verbosity.Verbose, ALox.InternalDomains); ALIB.REPORT(2, "This is an ALib Report. Types other than '0' and '1' are user defined.\n" + "Verbosity of ALox.InternalDomains has to be increased to see them when using" + " ALoxReportWriter."); Log.Info("Note the domain prefix '" + ALox.InternalDomains.ToString() + "'. This addresses " + "the tree of internal domains\nof the Lox, which the report writer is just " + "using for ALib reports."); Log.RemoveDebugLogger(); }
/** ******************************************************************************************** * Releases ownership of this object. If Acquire() was called multiple times before, the same * number of calls to this method have to be performed to release ownership. **********************************************************************************************/ public void Release() { // are we in unsafe mode? if (mutex == null) { // not locked if (lockMode == LockMode.Recursive && lockCount == 0) { ALIB.ERROR("Release() without Acquire() (unsafe mode). This must never happen, check your code, set lock to safe mode!"); } // we are still decreasing the lockCount lockCount = lockMode == LockMode.Recursive ? lockCount - 1 : 0; // end of unsafe version of this method return; } // synchronize on mutex lock ( mutex ) { // not locked if (lockCount == 0) { ALIB.ERROR("Release() without Acquire(). This must never happen, check your code!"); } // decreasing the lockCount lockCount = lockMode == LockMode.Recursive ? lockCount - 1 : 0; // release and notify next waiting thread if (lockCount == 0) { owner = null; Monitor.Pulse(mutex); #if DEBUG acquirementLineNumber = -1; acquirementSourcefile = null; acquirementMethodName = null; #endif } } // synchronized }
/** ******************************************************************************************** * If parameter is true, the whole locking system is disabled. The only objective here is to * to gain execution speed, as thread synchronization causes relatively expensive system calls. * Use this method only if you are 100% sure that your (otherwise) critical section are executed * in a single threaded environment. And: "relative expensive" means: they are not really * expensive. This is provided only for the rare case that your critical section is very, * very frequently executed. * * @param safeness Determines if this object should use a mutex (\c Safeness.Safe) * or just do nothing (\c Safeness.Unsafe). *************************************************************************************************/ public void SetSafeness(Safeness safeness) { // are we in unsafe mode? if (mutex == null) { // already locked? ALIB Error if (lockCount != 0) { ALIB.ERROR("Cannot switch safeness mode while already locked. Current mode: unsafe, requested mode: " + safeness.ToString()); return; } // switch on? if (safeness == Safeness.Safe) { mutex = new Object(); } // end of unsafe version of this method return; } // synchronize on mutex lock ( mutex ) { // already locked? ALIB Error if (owner != null) { ALIB.ERROR("Cannot switch safeness mode while already locked. Current mode: safe, requested mode: " + safeness.ToString()); return; } // switch off? if (safeness == Safeness.Unsafe) { mutex = null; } } }
void Register(Lox lox, ContainerOp operation) { try { ALIB.Lock.Acquire(); // check if (lox == null) { ALIB.ERROR("null given"); return; } // remove if (operation == ContainerOp.Remove) { if (!loxes.Remove(lox)) { ALIB.WARNING("A lox named \"" + lox.GetName() + "\" could not be found for removal."); } } // insert else { foreach (Lox it in loxes) { if (it.GetName().Equals(lox.GetName( ))) { ALIB.ERROR("A lox named \"" + lox.GetName() + "\" was already registered. Registration ignored"); return; } } loxes.Add(lox); } } finally { ALIB.Lock.Release(); } }
// ############################################################################################# // Interface // ############################################################################################# /** ******************************************************************************************** * Thread which invokes this method gets registered as the current owner of this object, until the * same thread releases the ownership invoking Release(). * In the case that this object is already owned by another thread, the invoking thread is suspended * until ownership can be gained. * Multiple (nested) calls to this method are counted and the object is only released when the same * number of Release() calls have been made. * * @param cln (Optional) Caller info, compiler generated. Please omit. * @param csf (Optional) Caller info, compiler generated. Please omit. * @param cmn (Optional) Caller info, compiler generated. Please omit. **********************************************************************************************/ public void Acquire( [CallerLineNumber] int cln = 0, [CallerFilePath] String csf = "", [CallerMemberName] String cmn = "") { // are we in unsafe mode? if (mutex == null) { // we are still increasing the lockCount lockCount = lockMode == LockMode.Recursive ? lockCount + 1 : 1; // reached warning limit if (lockCount <= 0) { ALIB.ERROR("Unsafe mode: Counter invalid (<= 0): This should never happen. Set lock to safe mode!"); } else if (lockCount % RecursionWarningThreshold == 0) { ALIB.WARNING("Recursion depth " + lockCount + ". To prevent this, change ThreadSafe.recursionWarningThreshold or fix your code!"); } // end of unsafe version of this method return; } // get current thread Thread thisThread = Thread.CurrentThread; // synchronize on mutex lock ( mutex ) { // we already own the thread if (owner == thisThread) { // we are still increasing the lockCount lockCount = lockMode == LockMode.Recursive ? lockCount + 1 : 1; // reached warning limit if (lockCount % RecursionWarningThreshold == 0) { ALIB.WARNING("Recursion depth " + lockCount + ". To prevent this, change ThreadSafe.recursionWarningThreshold or fix your code!"); } return; } // we do not own this thread, wait until lock is free bool hasWarned = false; while (owner != null) { try { // wait unconditional if (waitWarningTimeLimitInMillis <= 0 || hasWarned) { Monitor.Wait(mutex); } // wait with time limit else { waitTime.Set(); Monitor.Wait(mutex, waitWarningTimeLimitInMillis); long time = waitTime.Age().InMillis(); if (time >= waitWarningTimeLimitInMillis) { hasWarned = true; ALIB.WARNING("Timeout (" + waitWarningTimeLimitInMillis + " ms). Change your codes critical section length if possible." + CString.NewLineChars + "This thread: " + thisThread.ManagedThreadId + "/" + thisThread.Name + CString.NewLineChars + "Owning thread: " + (owner != null ? (owner.ManagedThreadId + "/" + owner.Name) : "null") #if DEBUG + CString.NewLineChars + "Location of acquirement: " + acquirementSourcefile + ":" + acquirementLineNumber + " " + acquirementMethodName + "()" #endif ); } } } catch (Exception) {} // ignore spurious wakeups } // take control owner = thisThread; #if DEBUG acquirementLineNumber = cln; acquirementSourcefile = csf; acquirementMethodName = cmn; #endif lockCount = 1; } // synchronized }
// ############################################################################################# // public interface // ############################################################################################# /** **************************************************************************************** * Constructs a scope info. * @param name The name of the Lox we belong to * @param threadDictionary A dictionary to map thread IDs to user friendly names which is * managed outside of this class. ******************************************************************************************/ public ScopeInfo(String name, Dictionary <int, String> threadDictionary) { loxName = name.ToUpper(); ALIB.ASSERT_ERROR(!loxName.Equals("GLOBAL"), "Name \"GLOBAL\" not allowed for Lox instances"); this.threadDictionary = threadDictionary; cache = new SourceFile[cacheSize = DefaultCacheSize]; for (int i = 0; i < cacheSize; i++) { cache[i] = new SourceFile(); } actual = cache[0]; // read trim rules from config // do 2 times, 0== local list, 1== global list List <SourcePathTrimRule> trimInfoList; AString rules = new AString(); AString variableName = new AString(); for (int trimInfoNo = 0; trimInfoNo < 2; trimInfoNo++) { // check if done... or set list variableName._(); if (trimInfoNo == 0) { trimInfoList = LocalSPTRs; variableName._(loxName); } else { if (GlobalSPTRsReadFromConfig) { continue; } GlobalSPTRsReadFromConfig = true; trimInfoList = GlobalSPTRs; variableName._("GLOBAL"); } variableName._("_SOURCE_PATH_TRIM_RULES"); // get auto sizes from last session rules._(); if (ALIB.Config.Get(ALox.ConfigCategoryName, variableName, rules) != 0) { Tokenizer rulesTok = new Tokenizer(); Tokenizer ruleTok = new Tokenizer(); rulesTok.Set(rules, ';'); Substring ruleStr; while ((ruleStr = rulesTok.Next()).IsNotEmpty()) { try { ruleTok.Set(ruleStr, ','); SourcePathTrimRule rule = new SourcePathTrimRule(); rule.Path = new AString(); ruleTok.Next(); if (!(rule.IsPrefix = !ruleTok.Actual.StartsWith("*"))) { ruleTok.Actual.Consume(1); } rule.Path._(ruleTok.Actual); if (rule.Path.CharAtEnd() == '*') { rule.Path.DeleteEnd(1); } if (rule.Path.IsEmpty()) { continue; } if (Path.DirectorySeparatorChar == '/') { rule.Path.SearchAndReplaceAll("\\", "/"); } else { rule.Path.SearchAndReplaceAll("/", "\\"); } rule.IncludeString = ALIB.ReadInclusion(ruleTok.Next()); if (ruleTok.HasNext()) { ruleTok.Next().ConsumeInteger(out rule.TrimOffset); } rule.Sensitivity = ALIB.ReadCase(ruleTok.Next()); trimInfoList.Add(rule); } catch (Exception) { ALIB.ERROR("Error reading source path trim rule from configuration. Invalid String: " + ruleStr.ToString()); } } } } }