/** **************************************************************************************** * Invokes grand-parent's method and in addition, de-registers with * \ref cs::aworx::lib::ALIB::StdOutputStreamsLock "ALIB.StdOutputStreamsLock" * @param acquirer The acquirer to remove. * @return The new number of \e acquirers set. ******************************************************************************************/ public override int RemoveAcquirer( ThreadLock acquirer ) { // d-register with ALIB lockers (if not done yet) if ( usesStdStreams ) { ALIB.Lock.Acquire(); int stdStreamLockRegistrationCounter= --this.stdStreamLockRegistrationCounter; ALIB.Lock.Release(); if ( stdStreamLockRegistrationCounter == 0 ) ALIB.StdOutputStreamsLock.RemoveAcquirer( this ); } Variable variable= new Variable(); // export autosizes to configuration variable.Define( ALox.AUTO_SIZES, GetName() ); AutoSizes.Export( variable.AddString() ); variable.Store(); // export "max elapsed time" to configuration variable.Define( ALox.MAX_ELAPSED_TIME, GetName() ); AString destVal= variable.Load() != 0 ? variable.GetString() : variable.AddString(); destVal._()._( MetaInfo.MaxElapsedTime.InSeconds() ); variable.Store(); // call parents' implementation return base.RemoveAcquirer( acquirer ); }
// ############################################################################################# // Interface // ############################################################################################# /** **************************************************************************************** * Adds an acquirer. * @param newAcquirer The acquirer to add. * @return The new number of \e acquirers set. ******************************************************************************************/ public virtual int AddAcquirer(ThreadLock newAcquirer) { int count = -1; #if DEBUG bool errAllreadyAdded = true; bool errHasToBeRecursive = false; int errWasAcquired = 0; #endif try { ALIB.Lock.Acquire(); count = acquirers.Count; // check doubly added if (newAcquirer == null || acquirers.IndexOf(newAcquirer) < 0) { #if DEBUG errAllreadyAdded = false; errWasAcquired = DbgCountAcquirements() == 0 ? 0 : 1; #endif // switch on? if (acquirers.Count == 1) { #if DEBUG errAllreadyAdded = false; #endif ThreadLock firstAcquirer = acquirers[0]; // non-anonymous acquirer? if (firstAcquirer != null) { if (firstAcquirer.GetMode() == LockMode.Recursive) { firstAcquirer.Acquire(); SetSafeness(Safeness.Safe); acquirers.Add(newAcquirer); count++; firstAcquirer.Release(); } #if DEBUG else { errHasToBeRecursive = false; } #endif } // critical section: our first acquirer is anonymous. As documented in class, // this must happen only in situations, when we are sure, that we are safe, e.g. still // single threaded execution of process bootstrap. else { // If this assert happens, its only good luck: we detected a misuse. But it should // be very seldom to be detected this way :-/ #if DEBUG if (errWasAcquired == 1) { errWasAcquired = 2; } #endif SetSafeness(Safeness.Safe); acquirers.Add(newAcquirer); count++; } } else { acquirers.Add(newAcquirer); } } } finally { ALIB.Lock.Release(); } #if DEBUG ALIB.ASSERT_ERROR(!errAllreadyAdded, "Acquirer already registered."); ALIB.ASSERT_ERROR(!errHasToBeRecursive, "Acquireres need to be in recursive mode "); ALIB.ASSERT_ERROR(errWasAcquired != 1, "Already aquired. Hint: Acquirer[0] must not acquire this before adding itself!"); ALIB.ASSERT_ERROR(errWasAcquired != 2, "Aquired and acquirer[0] anonymous. Misuse of SmartLock!"); #endif return(count); }
// ############################################################################################# // Reimplementing interface of grand-parent class SmartLock // ############################################################################################# /** **************************************************************************************** * Invokes grand-parent's method and in addition, if field #usesStdStreams is set, * registers with * \ref cs::aworx::lib::ALIB::StdOutputStreamsLock "ALIB.StdOutputStreamsLock", respectively * * @param newAcquirer The acquirer to add. * @return The new number of \e acquirers set. ******************************************************************************************/ public override int AddAcquirer( ThreadLock newAcquirer ) { // register with ALIB lockers (if not done yet) if ( usesStdStreams ) { ALIB.Lock.Acquire(); int stdStreamLockRegistrationCounter= this.stdStreamLockRegistrationCounter++; ALIB.Lock.Release(); if ( stdStreamLockRegistrationCounter == 0 ) ALIB.StdOutputStreamsLock.AddAcquirer( this ); } Variable variable= new Variable(); // import autosizes from configuration (last session) if ( variable.Define( ALox.AUTO_SIZES, GetName()).Load() != 0 ) AutoSizes.Import( variable.GetString() ); // import "max elapsed time" from configuration (last session) if ( variable.Define( ALox.MAX_ELAPSED_TIME, GetName()).Load() != 0 ) { long maxInSecs= variable.GetInteger(); Substring attrValue= new Substring(); if ( variable.GetAttribute( "limit", attrValue ) ) { long maxMax; attrValue.ConsumeLong( out maxMax ); if ( maxInSecs > maxMax ) maxInSecs= maxMax; } MetaInfo.MaxElapsedTime.FromSeconds( maxInSecs ); } // Variable <name>_FORMAT / <typeName>_FORMAT: ALIB.ASSERT_WARNING( ALox.FORMAT.DefaultValue == null, "Default value of variable FORMAT should be kept null" ); if( 0 == variable.Define( ALox.FORMAT, GetName() ).Load() && 0 == variable.Define( ALox.FORMAT, GetTypeName() ).Load() ) { // no variable created, yet. Let's create a 'personal' one on our name variable.Define( ALox.FORMAT, GetName() ); variable.AddString( MetaInfo.Format ); variable.AddString( MetaInfo.VerbosityError ); variable.AddString( MetaInfo.VerbosityWarning ); variable.AddString( MetaInfo.VerbosityInfo ); variable.AddString( MetaInfo.VerbosityVerbose ); variable.Store(); } else { MetaInfo.Format ._()._( variable.GetString(0) ); if( variable.Size() >= 2 ) MetaInfo.VerbosityError = variable.GetString(1).ToString(); if( variable.Size() >= 3 ) MetaInfo.VerbosityWarning= variable.GetString(2).ToString(); if( variable.Size() >= 4 ) MetaInfo.VerbosityInfo = variable.GetString(3).ToString(); if( variable.Size() >= 5 ) MetaInfo.VerbosityVerbose= variable.GetString(4).ToString(); } // Variable <name>_FORMAT_DATE_TIME / <typeName>_FORMAT_DATE_TIME: ALIB.ASSERT_WARNING( ALox.FORMAT_DATE_TIME.DefaultValue == null, "Default value of variable FORMAT_DATE_TIME should be kept null" ); if( 0 == variable.Define( ALox.FORMAT_DATE_TIME, GetName() ).Load() && 0 == variable.Define( ALox.FORMAT_DATE_TIME, GetTypeName() ).Load() ) { // no variable created, yet. Let's create a 'personal' one on our name variable.Define( ALox.FORMAT_DATE_TIME, GetName() ); variable.AddString( MetaInfo.DateFormat ); variable.AddString( MetaInfo.TimeOfDayFormat ); variable.AddString( MetaInfo.TimeElapsedDays ); variable.Store(); } else { MetaInfo.DateFormat = variable.GetString(0).ToString(); if( variable.Size() >= 2 ) MetaInfo.TimeOfDayFormat = variable.GetString(1).ToString(); if( variable.Size() >= 3 ) MetaInfo.TimeElapsedDays = variable.GetString(2).ToString(); } // Variable <name>FORMAT_TIME_DIFF / <typeName>FORMAT_TIME_DIFF: ALIB.ASSERT_WARNING( ALox.FORMAT_TIME_DIFF.DefaultValue == null, "Default value of variable FORMAT_TIME_DIFF should be kept null" ); if( 0 == variable.Define( ALox.FORMAT_TIME_DIFF, GetName() ).Load() && 0 == variable.Define( ALox.FORMAT_TIME_DIFF, GetTypeName() ).Load() ) { // no variable created, yet. Let's create a 'personal' one on our name variable.Define( ALox.FORMAT_TIME_DIFF, GetName() ); variable.AddInteger ( MetaInfo.TimeDiffMinimum); variable.AddString( MetaInfo.TimeDiffNone ); variable.AddString( MetaInfo.TimeDiffNanos ); variable.AddString( MetaInfo.TimeDiffMicros ); variable.AddString( MetaInfo.TimeDiffMillis ); variable.AddString( MetaInfo.TimeDiffSecs ); variable.AddString( MetaInfo.TimeDiffMins ); variable.AddString( MetaInfo.TimeDiffHours ); variable.AddString( MetaInfo.TimeDiffDays ); variable.Store(); } else { MetaInfo.TimeDiffMinimum= variable.GetInteger (0); if( variable.Size() >= 2 ) MetaInfo.TimeDiffNone = variable.GetString(1).ToString(); if( variable.Size() >= 3 ) MetaInfo.TimeDiffNanos = variable.GetString(2).ToString(); if( variable.Size() >= 4 ) MetaInfo.TimeDiffMicros = variable.GetString(3).ToString(); if( variable.Size() >= 5 ) MetaInfo.TimeDiffMillis = variable.GetString(4).ToString(); if( variable.Size() >= 6 ) MetaInfo.TimeDiffSecs = variable.GetString(5).ToString(); if( variable.Size() >= 7 ) MetaInfo.TimeDiffMins = variable.GetString(6).ToString(); if( variable.Size() >= 8 ) MetaInfo.TimeDiffHours = variable.GetString(7).ToString(); if( variable.Size() >= 9 ) MetaInfo.TimeDiffDays = variable.GetString(8).ToString(); } // Variable <name>FORMAT_MULTILINE / <typeName>FORMAT_MULTILINE: ALIB.ASSERT_WARNING( ALox.FORMAT_MULTILINE.DefaultValue == null, "Default value of variable FORMAT_MULTILINE should be kept null" ); if( 0 == variable.Define( ALox.FORMAT_MULTILINE, GetName() ).Load() && 0 == variable.Define( ALox.FORMAT_MULTILINE, GetTypeName() ).Load() ) { // no variable created, yet. Let's create a 'personal' one on our name variable.Define( ALox.FORMAT_MULTILINE, GetName() ); variable.AddInteger( MultiLineMsgMode ); variable.AddString ( FmtMultiLineMsgHeadline ); variable.AddString ( FmtMultiLinePrefix ); variable.AddString ( FmtMultiLineSuffix ); variable.Store(); } else { MultiLineMsgMode= (int) variable.GetInteger(0) ; if( variable.Size() >= 2 ) FmtMultiLineMsgHeadline= variable.GetString(1).ToString(); if( variable.Size() >= 3 ) FmtMultiLinePrefix = variable.GetString(2).ToString(); if( variable.Size() >= 4 ) FmtMultiLineSuffix = variable.GetString(3).ToString(); if( variable.Size() >= 5 ) { if (variable.GetString(4).Equals( "nulled" , Case.Ignore ) ) MultiLineDelimiter= null; else MultiLineDelimiter= variable.GetString(4).ToString(); } if( variable.Size() >= 6 ) MultiLineDelimiterRepl = variable.GetString(5).ToString(); } // call parents' implementation return base.AddAcquirer( newAcquirer ); }
public void ThreadLock_Simple() { UT_INIT(); Report.GetDefault().PushHaltFlags( false, false ); Log.AddDebugLogger(); Log.MapThreadName( "UnitTest" ); Log.SetDomain( "TestTLock", Scope.Method ); Log.SetVerbosity( Log.DebugLogger, Verbosity.Verbose, "ALIB" ); // lock a recursive lock ThreadLock aLock= new ThreadLock(); aLock.Acquire(); aLock.Release(); aLock.Acquire(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); aLock.Acquire(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); aLock.Release(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); aLock.Acquire(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); aLock.Release(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); aLock.Release(); UT_TRUE ( aLock.ToString().StartsWith("Unlocked") ); // set unsafe aLock.SetSafeness( Safeness.Unsafe ); UT_TRUE ( aLock.ToString().StartsWith("Unlocked") ); UT_TRUE ( aLock.ToString().Contains ("Unsafe") ); aLock.SetSafeness( Safeness.Safe ); UT_TRUE ( !aLock.ToString().Contains ("Unsafe") ); aLock.SetSafeness( Safeness.Unsafe ); UT_TRUE ( aLock.ToString().StartsWith("Unlocked") ); UT_TRUE ( aLock.ToString().Contains ("Unsafe") ); aLock.Acquire(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); aLock.Release(); UT_TRUE ( aLock.ToString().StartsWith("Unlocked") ); UT_TRUE ( aLock.ToString().Contains ("Unsafe") ); // unsafe aLock.Acquire(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); Log.Info("One warning should come now: "); aLock.SetSafeness( Safeness.Safe ); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); UT_TRUE ( aLock.ToString().Contains ("Unsafe") ); // safe (new lock) aLock= new ThreadLock(); aLock.Acquire(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); UT_TRUE ( !aLock.ToString().Contains ("Unsafe") ); Log.Info("One warning should come now: "); aLock.SetSafeness( Safeness.Unsafe ); UT_TRUE ( !aLock.ToString().StartsWith("null") ); UT_TRUE ( !aLock.ToString().Contains ("Unsafe") ); // test warnings (10) locks: aLock= new ThreadLock(); Log.Info("Two warnings should come now: "); for (int i= 0; i<20; i++) aLock.Acquire(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); for (int i= 0; i<20; i++) aLock.Release(); UT_TRUE ( aLock.ToString().StartsWith("Unlocked") ); // test a non-recursive lock aLock= new ThreadLock( LockMode.SingleLocks ); aLock.Acquire(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); aLock.Acquire(); UT_TRUE ( aLock.ToString().StartsWith("Locked") ); aLock.Release(); UT_TRUE ( aLock.ToString().StartsWith("Unlocked") ); Log.Info("One warning should come now: "); aLock.Release(); UT_TRUE ( aLock.ToString().StartsWith("Unlocked") ); Report.GetDefault().PopHaltFlags(); }
/** **************************************************************************************** * Removes an acquirer. * @param acquirerToRemove The acquirer to remove. * @return The new number of \e acquirers set. ******************************************************************************************/ public virtual int RemoveAcquirer(ThreadLock acquirerToRemove) { int count = 0; bool errNotFound = true; bool errWasAcquired = false; try { ALIB.Lock.Acquire(); #if DEBUG errWasAcquired = DbgCountAcquirements() != 0; #endif // search acquirer if (acquirers.IndexOf(acquirerToRemove) >= 0) { errNotFound = false; // switch off? if (acquirers.Count == 2) { ThreadLock acquirer1 = acquirers[0]; ThreadLock acquirer2 = acquirers[1]; if (acquirer1 == acquirerToRemove) { acquirer1 = null; } if (acquirer2 == acquirerToRemove) { acquirer2 = null; } // Aquire acquirers in their order of appearance if (acquirer1 != null) { acquirer1.Acquire(); } if (acquirer2 != null) { acquirer2.Acquire(); } SetSafeness(Safeness.Unsafe); acquirers.Remove(acquirerToRemove); if (acquirer2 != null) { acquirer2.Release(); } if (acquirer1 != null) { acquirer1.Release(); } } // just remove acquirer, keep mode else { acquirers.Remove(acquirerToRemove); } } count = acquirers.Count; } finally { ALIB.Lock.Release(); } ALIB.ASSERT_ERROR(!errNotFound, "Acquirer not found."); ALIB.ASSERT_ERROR(!errWasAcquired, "Aquired on release. Hint: Acquirers must acquire only when acquired themselves!"); return(count); }
public Test_ThreadLock_TestThreadParams( ThreadLock aLock, int holdTime, int repeats, bool verbose, Test_ThreadLock_SharedInt shared ) { this.aLock= aLock; this.holdTime= holdTime; this.repeats= repeats; this.verbose= verbose; this.shared= shared; }
public void ThreadLock_SpeedTest() { UT_INIT(); Log.SetVerbosity( new ConsoleLogger(), Verbosity.Verbose, "/" ); Log.MapThreadName( "UnitTest" ); Log.SetDomain( "TestTLock", Scope.Method ); ThreadLock aLock= new ThreadLock(); int repeats= 100000; int rrepeats= 5; Ticks stopwatch= new Ticks(); for ( int r= 0; r < rrepeats; r ++) { Log.Info("Run " + rrepeats ); aLock.SetSafeness( Safeness.Unsafe ); stopwatch.Set(); for ( int i= 0; i < repeats; i++ ) { aLock.Acquire(); aLock.Release(); } long time= stopwatch.Age().InMillis(); Log.Info("Safe mode, " + repeats + " lock/unlock ops: " + time + " ms" ); aLock.SetSafeness( Safeness.Safe ); stopwatch.Set(); for ( int i= 0; i < repeats; i++ ) { //aLock.acquire(); //aLock.release(); // in java, adding the following two loops, results in similar execution speed for ( int tt= 0; tt < 70; tt++ ) i+= tt; for ( int tt= 0; tt < 70; tt++ ) i-= tt; } time= stopwatch.Age().InMillis(); Log.Info("Unsafe mode, " + repeats + " lock/unlock ops: " + time + " ms" ); } }
public void ThreadLock_HeavyLoad() { UT_INIT(); Log.SetVerbosity( new ConsoleLogger(), Verbosity.Verbose, "/" ); Log.MapThreadName( "UnitTest" ); Log.SetDomain( "TestTLock", Scope.Filename ); ThreadLock aLock= new ThreadLock(); // uncomment this for unsafe mode // lock.setUnsafe( true ); Test_ThreadLock_SharedInt shared= new Test_ThreadLock_SharedInt(); int holdTime= 0; int repeats= 5000; bool verbose= false; Test_ThreadLock_TestThreadParams p1= new Test_ThreadLock_TestThreadParams( aLock, holdTime, repeats, verbose, shared ); Test_ThreadLock_TestThreadParams p2= new Test_ThreadLock_TestThreadParams( aLock, holdTime, repeats, verbose, shared ); Test_ThreadLock_TestThreadParams p3= new Test_ThreadLock_TestThreadParams( aLock, holdTime, repeats, verbose, shared ); Log.Info("starting three threads"); Thread t1= new Thread( new ParameterizedThreadStart( Test_ThreadLock_Test_run ) ); Thread t2= new Thread( new ParameterizedThreadStart( Test_ThreadLock_Test_run ) ); Thread t3= new Thread( new ParameterizedThreadStart( Test_ThreadLock_Test_run ) ); t1.Start( p1 ); t2.Start( p2 ); t3.Start( p3 ); // wait until all ended while ( t1.IsAlive || t2.IsAlive || t3.IsAlive ) ALIB.SleepMillis( 1 ); Log.Info("All threads ended. Shared value=" + shared.val ); UT_TRUE( shared.val == 0 ); }
public void SmartLock() { UT_INIT(); Report.GetDefault().PushHaltFlags( false, false ); // SmartLock with null-users { utWriter.lox.CntLogCalls= 0; SmartLock sl= new SmartLock(); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( null ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 1 ); utWriter.lox.CntLogCalls= 0; } // SmartLock with threadlocks { ThreadLock tl1 = new ThreadLock(); ThreadLock tl2 = new ThreadLock(); ThreadLock tl3 = new ThreadLock(); SmartLock sl= new SmartLock(); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( tl1 ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( tl2 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( tl3 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl3 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl3 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 1 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl2 ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl1 ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl1 ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 1 ); utWriter.lox.CntLogCalls= 0; } // mixed { ThreadLock tl1 = new ThreadLock(); ThreadLock tl2 = new ThreadLock(); ThreadLock tl3 = new ThreadLock(); SmartLock sl= new SmartLock(); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( tl1 ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( tl2 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( tl2 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 1 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.AddAcquirer ( tl3 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl1 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl1 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 1 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl3 ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Safe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 1 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 1 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl3 ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 1 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( tl2 ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 0 ); utWriter.lox.CntLogCalls= 0; sl.RemoveAcquirer( null ); UT_TRUE( sl.GetSafeness() == Safeness.Unsafe ); UT_TRUE( utWriter.lox.CntLogCalls== 1 ); utWriter.lox.CntLogCalls= 0; } Report.GetDefault().PopHaltFlags(); }
public void ThreadLock_Threaded() { UT_INIT(); Log.SetVerbosity( new ConsoleLogger(),Verbosity.Verbose, "/" ); Log.MapThreadName( "UnitTest" ); Log.SetDomain( "TestTLock", Scope.Filename ); Log.SetVerbosity( "CONSOLE", Verbosity.Verbose, "ALIB" ); ThreadLock aLock= new ThreadLock(); Test_ThreadLock_SharedInt shared= new Test_ThreadLock_SharedInt(); Log.Info("starting thread locked"); aLock.Acquire(); Test_ThreadLock_TestThreadParams tParam= new Test_ThreadLock_TestThreadParams( aLock, 10, 1, true, shared ); Thread thread = new Thread( new ParameterizedThreadStart( Test_ThreadLock_Test_run ) ); thread.Name= "A Thread"; thread.Start( tParam ); Log.Info("We wait 1100 ms. This should give a warning! "); ALIB.SleepMillis( 1100 ); aLock.Release(); // wait until t ended while (thread.IsAlive) ALIB.SleepMillis( 1 ); // now we do the same with a higher wait limit, no erro should come aLock.waitWarningTimeLimitInMillis= 5; aLock.Acquire(); tParam= new Test_ThreadLock_TestThreadParams( aLock, 10, 1, true, shared ); thread = new Thread( new ParameterizedThreadStart( Test_ThreadLock_Test_run ) ); thread.Start( tParam ); Log.Info("We wait 1 ms. This should NOT give a warning! "); ALIB.SleepMillis( 1 ); aLock.Release(); // wait until t ended while (thread.IsAlive) ALIB.SleepMillis( 1 ); }