Пример #1
0
        private static T ref_wrap_uintptr <T>(ClrSyncManager manager, ref T tgt, SimpleRefDel <T> originalCode)
        {
            T   ret;
            var ptr = ObjectTracking.GetCurrentRawAddress(ref tgt);

            manager.SyncVarAccess(ptr, MSyncVarOp.RWVAR_READWRITE);
            try
            {
                ret = originalCode(ref tgt);
            }
            catch (Exception e)
            {
                manager.CommitSyncVarAccess();
                throw e;
            }
            manager.CommitSyncVarAccess();
            return(ret);
        }
Пример #2
0
        private static T ref_wrap_gcaddr <T>(ClrSyncManager manager, ref T tgt, SimpleRefDel <T> originalCode)
        {
            GCAddress gca;

            if (GCAddress.FromByRef(ref tgt, out gca))
            {
                try
                {
                    manager.SyncVarAccess(gca, MSyncVarOp.RWVAR_READWRITE);
                    T ret;
                    try
                    {
                        ret = originalCode(ref tgt);
                    }
                    catch (Exception e)
                    {
                        manager.CommitSyncVarAccess();
                        throw e;
                    }
                    manager.CommitSyncVarAccess();
                    return(ret);
                }
                finally
                {
                    gca.Release();
                }
            }
            else
            {
                // GC tracking returns false when addr is
                // -	On the stack, or
                // -	Allocated by native code, or
                // -	When it points to certain static fields, and you have only volatile-tracking enabled, but not all read/write accesses.
                return(ref_wrap_uintptr <T>(manager, ref tgt, originalCode));
            }
        }
Пример #3
0
        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);
                }
            });
        }
Пример #4
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);
            }
        }