private void EndChildThread() { if (manager.BreakDeadlockMode) { MChessChess.WakeNextDeadlockedThread(false, true); } else { childdone = true; manager.ThreadEnd(childthread); } }
public static Action <Object> TaskCreateWrapper(ClrSyncManager manager) { return (delegate(Object o) { try { TaskArg p = (TaskArg)o; p.e.Set(); manager.ThreadBegin(p.s); MChessChess.LeaveChess(); Exception exception = null; try { var tryExecuteTask = p.taskScheduler.GetType().GetMethod("TryExecuteTask", global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance); tryExecuteTask.Invoke(p.taskScheduler, new object[] { p.task }); } catch (Exception e) // catch recoverable exception in user code { exception = e; } MChessChess.EnterChess(); manager.SetMethodInfo("Task.End"); manager.AggregateSyncVarAccess( new object[] { p.task, ((IAsyncResult)p.task).AsyncWaitHandle }, MSyncVarOp.RWEVENT); manager.CommitSyncVarAccess(); if (manager.BreakDeadlockMode) { MChessChess.WakeNextDeadlockedThread(false, true); } else if (exception == null) { manager.ThreadEnd(Original::Thread.CurrentThread); } else { manager.Shutdown(exception); } } catch (Exception e) // catch fatal exception in our code { manager.Shutdown(e); } }); }
public void ThreadEnd(int ctid) { if (ctid > 0) { Debug.Assert(ctid == CurrentTid); } if (!MChessChess.TaskEnd()) { if (MChessChess.IsBreakingDeadlock()) { BreakDeadlockMode = true; MChessChess.WakeNextDeadlockedThread(false, false); } else { ChessDetach(); } } }
public static WaitCallback ThreadCreateWrapper(ClrSyncManager manager) { return (delegate(object o) { try { ThreadRoutineArg p = (ThreadRoutineArg)o; manager.ThreadBegin(p.s); MChessChess.LeaveChess(); Exception exception = null; try { p.wcb(p.o); } catch (Exception e) // catch recoverable exception in user code { exception = e; } MChessChess.EnterChess(); if (manager.BreakDeadlockMode) { MChessChess.WakeNextDeadlockedThread(false, true); } else if (exception == null) { manager.ThreadEnd(Original::Thread.CurrentThread); } else { manager.Shutdown(exception); } } catch (Exception e) // catch fatal exception in our code { manager.Shutdown(e); } }); }
public static Original::ParameterizedThreadStart WrapParamThreadStart(Original::ParameterizedThreadStart del, ClrSyncManager manager) { return(delegate(object o) { try { manager.ThreadBegin(Original::Thread.CurrentThread); MChessChess.LeaveChess(); Exception exception = null; try { CheckThreadReadyForMonitoring(); del(o); } catch (Exception e) // catch recoverable exception in user code { exception = e; } MChessChess.EnterChess(); if (manager.BreakDeadlockMode) { MChessChess.WakeNextDeadlockedThread(false, true); } else if (exception == null) { manager.ThreadEnd(Original::Thread.CurrentThread); } else { manager.Shutdown(exception); } } catch (Exception e) // catch fatal exception in our code { manager.Shutdown(e); } }); }
public static WaitOrTimerCallback RegisterWaitForSingleObjectWrapper(ClrSyncManager manager) { return (delegate(object argument, bool timedOut) { try { global::System.Diagnostics.Debug.Assert(!timedOut); Helper.WaitOrTimerCallbackRoutineArg p = (Helper.WaitOrTimerCallbackRoutineArg)argument; p.a.Set(); manager.ThreadBegin(p.s); WaitHandle cancelObject = null; while (true) { manager.SetMethodInfo("RegisteredWaitForSingleObject.CheckCancellation"); manager.SyncVarAccess(p, MSyncVarOp.RWVAR_READWRITE); bool cancelled = p.canceled; cancelObject = p.onCancellation; if (cancelled) { p.finished = true; } manager.CommitSyncVarAccess(); if (cancelled) { break; } MChessChess.LeaveChess(); bool flag = __Substitutions.System.Threading.WaitHandle.WaitOne(p.waitObject, (int)p.millisecondsTimeOutInterval, false); p.callback(p.state, !flag); MChessChess.EnterChess(); if (p.executeOnlyOnce) { manager.SetMethodInfo("RegisteredWaitForSingleObject.ReadOnCancellation"); manager.SyncVarAccess(p, MSyncVarOp.RWVAR_READWRITE); cancelObject = p.onCancellation; p.finished = true; manager.CommitSyncVarAccess(); break; } } MChessChess.LeaveChess(); Exception exception = null; try { if (cancelObject != null) { __Substitutions.System.Threading.EventWaitHandle.Set((EventWaitHandle)cancelObject); } } catch (Exception e) // catch recoverable exception in monitored code { exception = e; } MChessChess.EnterChess(); if (manager.BreakDeadlockMode) { MChessChess.WakeNextDeadlockedThread(false, true); } else if (exception == null) { manager.ThreadEnd(Original::Thread.CurrentThread); } else { manager.Shutdown(exception); } } catch (Exception e) // catch fatal exception in our code { manager.Shutdown(e); } }); }
public ChessMain(MChessOptions m, Assembly a, string testClassName, string unitTestName) { this.mco = m; this.testAssembly = a; this.testclass = testClassName; this.unitTestMethodName = unitTestName; this.runUnitTest = !String.IsNullOrEmpty(unitTestMethodName); this.manager = new ClrSyncManager(m); MChessChess.Init(manager, mco); TryLoadReferencedAssemblies(new[] { testAssembly }); get_entries(testAssembly); popups(m); this.manager.SetExitCallBack((c, ex) => { string msg = ""; if (ex != null) { msg = @"Child thread raised exception " + ex.Message + @" Stack trace: " + ex.StackTrace + @" "; ReportErrorAndExit(msg, c, true, ex); } ReportErrorAndExitRaw("", c, true, true, null); }); try { do_startup(); // print warning if races are disabled if (MChessChess.GetExitCode() == 0 && !(mco.preemptAccesses || mco.sober || mco.maxExecutions == 1 || !String.IsNullOrEmpty(mco.enumerateObservations))) { MChessChess.ReportWarning("Race Detection Disabled. Races May Hide Bugs.", "", false); } // RunTest loop bool moreToTest = true; while (moreToTest) { if (!MChessChess.StartTest()) { ReportErrorAndExit("Internal failure: CHESS.StartTest failed", ChessExitCode.ChessFailure, false, null); } if (MyEngine.EnvironmentVars.FlipPreemptSense) { MChessChess.PreemptionDisable(); } do_run(); if (MyEngine.EnvironmentVars.FlipPreemptSense) { MChessChess.PreemptionEnable(); } if (manager.BreakDeadlockMode) { MChessChess.EnterChess(); MChessChess.WakeNextDeadlockedThread(true, false); // we are now done with the deadlock-breaking mode! Debug.Assert(!MChessChess.IsBreakingDeadlock()); manager.BreakDeadlockMode = false; MChessChess.LeaveChess(); } moreToTest = MChessChess.EndTest(); } do_shutdown(); } catch (Exception ex) { string message = @"CHESS internal failure. " + ex.Message + @" " + ex.StackTrace + @" "; ReportErrorAndExit(message, ChessExitCode.ChessFailure, false, ex); } ReportErrorAndExit("", (ChessExitCode)MChessChess.GetExitCode(), false, null); }
// dueTime: the amount of time to delay before callback is invoked, in milliseconds. // Specify Timeout.Infinite to prevent the timer from starting. // Specify zero (0) to start the timer immediately. // period: The time interval between invocations of callback, in milliseconds. // Specify Timeout.Infinite to disable periodic signaling. // The method specified for callback should be reentrant, because it is called on ThreadPool threads. // The method can be executed simultaneously on two thread pool threads if the timer interval is less // than the time required to execute the method, or if all thread pool threads are in use and the method // is queued multiple times. public static void TimerCreateWrapper(object start) { try { TimerRoutineArg argument = (TimerRoutineArg)start; argument.inLoop = true; argument.changed = false; argument.parentSemaphore.Release(); ClrSyncManager manager = ClrSyncManager.SyncManager; manager.ThreadBegin(argument.selfSemaphore); Exception exception = null; while (true) { manager.SetMethodInfo("Timer.read"); manager.SyncVarAccess(argument.timer, MSyncVarOp.RWVAR_READWRITE); manager.CommitSyncVarAccess(); if (timer2tra[argument.timer].disposed) { // the timer only goes away when it is disposed of // it may be disabled, but a Change can reenable it break; } manager.TaskYield(); // until fairness deals with unbounded thread creation manager.TaskYield(); // we yield twice if (!argument.dueTime.Equals(TimeSpan.FromTicks(Timeout.Infinite))) { MChessChess.LeaveChess(); try { argument.callback(argument.state); } catch (Exception e) // catch recoverable exception in monitored code { exception = e; } MChessChess.EnterChess(); // If period is zero (0) or Infinite and dueTime is not Infinite, callback is invoked once; // the periodic behavior of the timer is disabled, but can be re-enabled using the Change method. } if (exception != null) { break; } if (argument.changed) { argument.changed = false; continue; } if (argument.Period.Equals(TimeSpan.FromTicks(Timeout.Infinite)) || argument.Period.Equals(TimeSpan.FromTicks(0))) { break; } } argument.inLoop = false; if (timer2tra[argument.timer].disposed) { timer2tra.Remove(argument.timer); } if (manager.BreakDeadlockMode) { MChessChess.WakeNextDeadlockedThread(false, true); } else if (exception == null) { manager.ThreadEnd(System.Threading.Thread.CurrentThread); } else { manager.Shutdown(exception); } } catch (Exception e) // catch fatal error in our code { ClrSyncManager manager = ClrSyncManager.SyncManager; manager.Shutdown(e); } }