Example #1
0
        public static Timer CreateTimer(ClrSyncManager manager, Original::TimerCallback timerCallback, object state, TimeSpan dueTime, TimeSpan period)
        {
            TimerRoutineArg argument = new TimerRoutineArg();

            argument.callback        = timerCallback;
            argument.state           = state;
            argument.dueTime         = dueTime;
            argument.Period          = period;
            argument.selfSemaphore   = new Semaphore(0, 1);
            argument.parentSemaphore = new Semaphore(0, 1);
            argument.disposed        = false;
            argument.changed         = true;

            Timer ret = new Timer(TimerCreateWrapper, argument, 0, Timeout.Infinite);

            argument.timer = ret;
            timer2tra.Add(ret, argument);
            int child = manager.TaskFork();

            argument.parentSemaphore.WaitOne();
            manager.RegisterTaskSemaphore(child, argument.selfSemaphore, false);
            manager.TaskResume(child);

            return(ret);
        }
Example #2
0
        // 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);
            }
        }