Beispiel #1
0
    /// <summary>
    /// 
    /// </summary>
    /// <param name="handle">执行回调</param>
    /// <param name="sleeptime">0 表示执行一次,否则执行到线程主动停止</param>
    public MFThread(ThreadHandle handle, int sleeptime = 0)
    {
        this.mThreadName = handle.ToString() + iThreadRef.ToString();
        this.mSleepTime = sleeptime;
        this.m_ThreadEvent = handle;

        iThreadRef++;
    }
Beispiel #2
0
        internal static unsafe void FinishInitializeThread()
        {
            int threadIndex = initialThread.threadIndex;

            // Get the GC ready for initialThread
            Transitions.RuntimeInitialized();
            Transitions.ThreadStart();
            initialThread.processGcEvent  = new AutoResetEvent(false);
            initialThread.autoEvent       = new AutoResetEvent(false);
            initialThread.joinEvent       = new ManualResetEvent(false);
            initialThread.singleQueueItem =
                new ThreadQueueItem [1] {
                new ThreadQueueItem(initialThread)
            };
            // Use CurrentThread to find our initial handle:
            VTable.Assert(initialThread == CurrentThread);
            initialThread.threadHandle = ThreadHandle.CurrentThread();
            // Instantiate the static variable that needs to be initialized
            m_LocalDataStoreMgr = new LocalDataStoreMgr();
            AddThread(threadIndex);
        }
Beispiel #3
0
        //=========================================================================
        // Spawns off a new thread which will begin executing at the ThreadStart
        // method on the IThreadable interface passed in the constructor. Once the
        // thread is dead, it cannot be restarted with another call to Start.
        //
        // Exceptions: ThreadStateException if the thread has already been started.
        //=========================================================================
        //| <include path='docs/doc[@for="Thread.Start"]/*' />
        public void Start()
        {
            lock ((Object)this) {
                if (closing)
                {
                    throw new ThreadStateException("Cannot start thread when closing");
                }

                ThreadState oldState = threadState;
                if (oldState != ThreadState.Unstarted)
                {
                    throw new ThreadStateException("Cannot start thread in state " + oldState);
                }

                threadState = ThreadState.Running;

                // Tell the GC that we have created the thread
                GC.NewThreadNotification(this, false);

                ThreadHandle.Start(threadHandle);
                GC.KeepAlive(this);
            }
        }
Beispiel #4
0
        private void BufferWorkerThreadStart()
        {
            int cursor = 0;

            _bufferWorkerThreadHandle = ThreadHandle.OpenCurrent(ThreadAccess.All);

            _bufferWorkerThreadReadyEvent.Set();

            while (!_terminating)
            {
                NtStatus status;
                KphSsBlockHeader blockHeader;

                status = _readSemaphore.Wait(true);

                if (status == NtStatus.Alerted)
                    return;

                if (_buffer.Size - cursor < Marshal.SizeOf(typeof(KphSsBlockHeader)))
                    cursor = 0;

                blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(cursor, 0);

                if (blockHeader.Type == KphSsBlockType.Reset)
                {
                    cursor = 0;
                    blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(cursor, 0);
                }

                if (blockHeader.Type == KphSsBlockType.Event)
                {
                    var eventBlock = _buffer.ReadStruct<KphSsEventBlock>(cursor, 0);
                    int[] arguments;
                    IntPtr[] stackTrace;

                    arguments = new int[eventBlock.NumberOfArguments];
                    stackTrace = new IntPtr[eventBlock.TraceCount];

                    for (int i = 0; i < arguments.Length; i++)
                        arguments[i] = _buffer.ReadInt32(cursor + eventBlock.ArgumentsOffset, i);
                    for (int i = 0; i < stackTrace.Length; i++)
                        stackTrace[i] = _buffer.ReadIntPtr(cursor + eventBlock.TraceOffset, i);

                    SsEvent ssEvent = new SsEvent();

                    ssEvent.Time = DateTime.FromFileTime(eventBlock.Time);
                    ssEvent.ThreadId = eventBlock.ClientId.ThreadId;
                    ssEvent.ProcessId = eventBlock.ClientId.ProcessId;
                    ssEvent.Arguments = arguments;
                    ssEvent.StackTrace = stackTrace;

                    ssEvent.ArgumentsCopyFailed =
                        (eventBlock.Flags & KphSsEventFlags.CopyArgumentsFailed) == KphSsEventFlags.CopyArgumentsFailed;
                    ssEvent.ArgumentsProbeFailed =
                        (eventBlock.Flags & KphSsEventFlags.ProbeArgumentsFailed) == KphSsEventFlags.ProbeArgumentsFailed;
                    ssEvent.CallNumber = eventBlock.Number;

                    if ((eventBlock.Flags & KphSsEventFlags.UserMode) == KphSsEventFlags.UserMode)
                        ssEvent.Mode = KProcessorMode.UserMode;
                    else
                        ssEvent.Mode = KProcessorMode.KernelMode;

                    if (this.EventBlockReceived != null)
                        this.EventBlockReceived(ssEvent);
                }
                else if (blockHeader.Type == KphSsBlockType.Argument)
                {
                    var argBlock = _buffer.ReadStruct<KphSsArgumentBlock>(cursor, 0);
                    MemoryRegion dataRegion;
                    SsData ssArg = null;

                    dataRegion = new MemoryRegion(_buffer, cursor + KphSsArgumentBlock.DataOffset);

                    switch (argBlock.Type)
                    {
                        case KphSsArgumentType.Int8:
                            {
                                SsSimple simpleArg = new SsSimple();

                                simpleArg.Argument = argBlock.Data.Int8;
                                simpleArg.Type = typeof(Byte);
                                ssArg = simpleArg;
                            }
                            break;
                        case KphSsArgumentType.Int16:
                            {
                                SsSimple simpleArg = new SsSimple();

                                simpleArg.Argument = argBlock.Data.Int16;
                                simpleArg.Type = typeof(Int16);
                                ssArg = simpleArg;
                            }
                            break;
                        case KphSsArgumentType.Int32:
                            {
                                SsSimple simpleArg = new SsSimple();

                                simpleArg.Argument = argBlock.Data.Int32;
                                simpleArg.Type = typeof(Int32);
                                ssArg = simpleArg;
                            }
                            break;
                        case KphSsArgumentType.Int64:
                            {
                                SsSimple simpleArg = new SsSimple();

                                simpleArg.Argument = argBlock.Data.Int64;
                                simpleArg.Type = typeof(Int64);
                                ssArg = simpleArg;
                            }
                            break;
                        case KphSsArgumentType.Handle:
                            {
                                ssArg = new SsHandle(dataRegion);
                            }
                            break;
                        case KphSsArgumentType.UnicodeString:
                            {
                                ssArg = new SsUnicodeString(dataRegion);
                            }
                            break;
                        case KphSsArgumentType.ObjectAttributes:
                            {
                                ssArg = new SsObjectAttributes(dataRegion);
                            }
                            break;
                        case KphSsArgumentType.ClientId:
                            {
                                ssArg = new SsClientId(dataRegion);
                            }
                            break;
                    }

                    ssArg.Index = argBlock.Index;

                    if (ssArg != null)
                    {
                        if (this.ArgumentBlockReceived != null)
                            this.ArgumentBlockReceived(ssArg);
                    }
                }

                cursor += blockHeader.Size;

                _writeSemaphore.Release();
            }
        }
Beispiel #5
0
 private static extern void InformThreadNameChange(ThreadHandle t, string name, int len);
 private static unsafe partial void StartInternal(ThreadHandle t, int stackSize, int priority, char *pThreadName);
 private static partial void InformThreadNameChange(ThreadHandle t, string?name, int len);
 private static extern void InformThreadNameChange(ThreadHandle t, string name, int len);
Beispiel #9
0
            private void WaiterThreadStart()
            {
                ISynchronizable[] waitObjects = null;

                // Open a handle to the current thread.
                _threadHandle = ThreadHandle.OpenCurrent(ThreadAccess.Alert);

                // Signal that the thread has been initialized.
                _threadInitializedEvent.Set();

                while (!_terminating)
                {
                    bool doWait;

                    lock (_waitObjects)
                    {
                        // Check if we have any objects to wait for. If we do, use WaitAny. 
                        // Otherwise, wait forever (alertably).
                        if (_waitObjects.Count > 0)
                        {
                            waitObjects = _waitObjects.ToArray();
                            doWait = true;
                        }
                        else
                        {
                            doWait = false;
                        }
                    }

                    NtStatus waitStatus;

                    if (doWait)
                    {
                        try
                        {
                            // Wait for the objects, (almost) forever.
                            waitStatus = NativeHandle.WaitAny(waitObjects, true, long.MinValue, false);
                        }
                        catch (WindowsException)
                        {
                            // We probably got Access denied on one of the objects. 
                            // We can't do anything about this, so just wait forever.
                            waitStatus = ThreadHandle.Sleep(true, long.MinValue, false);
                        }
                    }
                    else
                    {
                        // Wait forever.
                        waitStatus = ThreadHandle.Sleep(true, long.MinValue, false);
                    }

                    if (waitStatus == NtStatus.Alerted)
                    {
                        // The wait was changed. Go back to refresh the wait objects array.
                        // The thread is also alerted to notify that the thread should terminate.
                        continue;
                    }
                    else if (waitStatus >= NtStatus.Wait0 && waitStatus <= NtStatus.Wait63)
                    {
                        // One of the objects was signaled.
                        ISynchronizable signaledObject = waitObjects[(int)(waitStatus - NtStatus.Wait0)];

                        // Remove the object now that it is signaled.
                        lock (_waitObjects)
                        {
                            // Just in case someone already removed the object.
                            if (_waitObjects.Contains(signaledObject))
                                _waitObjects.Remove(signaledObject);
                        }

                        // Call the object-signaled event.
                        OnObjectSignaled(signaledObject);

                        // Balance the threads (which may involve terminating the current one).
                        _owner.BalanceWaiterThreads();
                    }
                }
            }
        private void TryEnterLock( ThreadUnsafePolicy policy, MethodExecutionArgs args )
        {
            object syncObject;

            syncObject = GetSyncObject(policy, args.Instance, args.Method.DeclaringType);

            if ( runningThreadSafeMethods != null && runningThreadSafeMethods.ContainsKey( syncObject ) ) return;

            ThreadHandle currentThread = new ThreadHandle( Thread.CurrentThread );

            ThreadHandle actualThread = locks.AddOrUpdate( syncObject, o => currentThread,
                                                           ( o, thread ) =>
                                                               {
                                                                   if ( thread.Thread != currentThread.Thread )
                                                                       throw new ThreadUnsafeException(ThreadUnsafeErrorCode.SimultaneousAccess);

                                                                   // Same thread, but different ThreadHandle: we are in a nested call on the same thread.
                                                                   return thread;
                                                               } );

            if ( actualThread == currentThread )
            {
                args.MethodExecutionTag = syncObject;
            }
        }
Beispiel #11
0
        //public IntPtr AddNumberRule(FilterType filterType, int number)
        //{
        //    return KProcessHacker.Instance.SsAddNumberRule(
        //        _ruleSetEntryHandle,
        //        filterType.ToKphSs(),
        //        number
        //        );
        //}

        //public IntPtr AddPreviousModeRule(FilterType filterType, KProcessorMode previousMode)
        //{
        //    return KProcessHacker.Instance.SsAddPreviousModeRule(
        //        _ruleSetEntryHandle,
        //        filterType.ToKphSs(),
        //        previousMode
        //        );
        //}

        //public IntPtr AddProcessIdRule(FilterType filterType, int pid)
        //{
        //    return KProcessHacker.Instance.SsAddProcessIdRule(
        //        _ruleSetEntryHandle,
        //        filterType.ToKphSs(),
        //        pid.ToIntPtr()
        //        );
        //}

        //public IntPtr AddThreadIdRule(FilterType filterType, int tid)
        //{
        //    return KProcessHacker.Instance.SsAddProcessIdRule(
        //        _ruleSetEntryHandle,
        //        filterType.ToKphSs(),
        //        tid.ToIntPtr()
        //        );
        //}

        private void BufferWorkerThreadStart()
        {
            // Open a handle to the current thread so other functions 
            // can alert us.
            _bufferWorkerThreadHandle = ThreadHandle.OpenCurrent(ThreadAccess.All);

            // We're ready.
            _bufferWorkerThreadReadyEvent.Set();

            while (!_terminating)
            {
                NtStatus status;
                KphSsBlockHeader blockHeader;

                // Wait for a block to read (enable alerting so we can 
                // be interrupted if someone wants us to stop).
                status = _readSemaphore.Wait(true);

                // Did we get alerted?
                if (status == NtStatus.Alerted)
                    return;

                // Check if we have an implicit cursor reset.
                if (_buffer.Size - _cursor < KphSsBlockHeader.SizeOf)
                    _cursor = 0;

                // Read the block header.
                blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(_cursor, KphSsBlockHeader.SizeOf, 0);

                // Check if we have an explicit cursor reset.
                if (blockHeader.Type == KphSsBlockType.Reset)
                {
                    _cursor = 0;
                    blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(_cursor, KphSsBlockHeader.SizeOf, 0);
                }

                // Process the block.
                switch (blockHeader.Type)
                {
                    case KphSsBlockType.Event:
                        if (this.EventBlockReceived != null)
                            this.EventBlockReceived(ReadEventBlock(new MemoryRegion(this._buffer, this._cursor)));
                        if (this.RawEventBlockReceived != null)
                            this.RawEventBlockReceived(new MemoryRegion(this._buffer, this._cursor));
                        break;
                    case KphSsBlockType.Argument:
                        if (this.ArgumentBlockReceived != null)
                            this.ArgumentBlockReceived(ReadArgumentBlock(new MemoryRegion(this._buffer, this._cursor)));
                        if (this.RawArgumentBlockReceived != null)
                            this.RawArgumentBlockReceived(new MemoryRegion(this._buffer, this._cursor));
                        break;
                }

                // Advance the cursor.
                _cursor += blockHeader.Size;
                // Signal that a buffer block is available for writing.
                _writeSemaphore.Release();
            }
        }
Beispiel #12
0
 //| <include path='docs/doc[@for="Thread.Sleep"]/*' />
 public static void Sleep(TimeSpan timeout)
 {
     ThreadHandle.Sleep(timeout);
 }
Beispiel #13
0
        //=========================================================================
        // Creates a new Thread object which will begin execution at
        // start.ThreadStart on a new thread when the Start method is called.
        //
        // Exceptions: ArgumentNullException if start == null.
        //=========================================================================
        //| <include path='docs/doc[@for="Thread.Thread"]/*' />
        public unsafe Thread(ThreadStart start)
        {
            Tracing.Log(Tracing.Audit, "Application Thread()");

            if (start == null)
            {
                throw new ArgumentNullException("start");
            }

            threadIndex = -1;
            threadState = ThreadState.Unstarted;
            threadStart = start;

            // Create the event for the thread to wait upon
            autoEvent       = new AutoResetEvent(false);
            joinEvent       = new ManualResetEvent(false);
            processGcEvent  = new AutoResetEvent(false);
            singleQueueItem = new ThreadQueueItem [1] {
                new ThreadQueueItem(this)
            };

            // Find a usable entry in the thread table
            // Disable local preemption while holding the lock. This might also be a
            // the property of the lock

            bool disabled = Processor.DisableLocalPreemption();

            Thread.threadTableLock.Acquire(CurrentThread);
            try {
                for (int i = 0; i < threadTable.Length; i++)
                {
                    int index = (threadIndexGenerator + i) % threadTable.Length;
                    if (threadTable[index] == null)
                    {
                        threadTable[index]   = this;
                        this.threadIndex     = index;
                        threadIndexGenerator = index + 1;
                        // NB: We call this once, afterwards the GC visitor calls it.
                        break;
                    }
                }
            }
            finally {
                Thread.threadTableLock.Release(CurrentThread);
                Processor.RestoreLocalPreemption(disabled);
            }

            VTable.Assert(threadIndex >= 0, "Out of thread slots!");

            //MemoryBarrier();

            // Must check closing after being insert into table to avoid race condition.
            if (closing)
            {
                threadState = ThreadState.Stopped;
                joinEvent.Set();
                Tracing.Log(Tracing.Warning, "Aborting: Runtime closing.");
                return;
            }

            ThreadHandle handleOnStack;
            UIntPtr      threadContext;

            if (!ThreadHandle.Create(threadIndex,
                                     new ContainerHandle(),
                                     out handleOnStack,
                                     out threadContext))
            {
                Tracing.Log(Tracing.Warning, "Aborting: ThreadHandle.Create failed.");
                threadState = ThreadState.Stopped;
                joinEvent.Set();
                return;
            }
            this.threadHandle         = handleOnStack;
            this.context              = (ThreadContext *)threadContext;
            this.context->threadIndex = unchecked ((ushort)threadIndex);
            this.context->UpdateAfterGC(this);
        }
Beispiel #14
0
 public static void Yield()
 {
     ThreadHandle.Yield();
 }
Beispiel #15
0
        private void BufferWorkerThreadStart()
        {
            int cursor = 0;

            // Open a handle to the current thread so other functions 
            // can alert us.
            _bufferWorkerThreadHandle = ThreadHandle.OpenCurrent(ThreadAccess.All);

            // We're ready.
            _bufferWorkerThreadReadyEvent.Set();

            while (!_terminating)
            {
                NtStatus status;
                KphSsBlockHeader blockHeader;

                // Wait for a block to read (enable alerting so we can 
                // be interrupted if someone wants us to stop).
                status = _readSemaphore.Wait(true);

                // Did we get alerted?
                if (status == NtStatus.Alerted)
                    return;

                // Check if we have an implicit cursor reset.
                if (_buffer.Size - cursor < Marshal.SizeOf(typeof(KphSsBlockHeader)))
                    cursor = 0;

                // Read the block header.
                blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(cursor, 0);

                // Check if we have an explicit cursor reset.
                if (blockHeader.Type == KphSsBlockType.Reset)
                {
                    cursor = 0;
                    blockHeader = _buffer.ReadStruct<KphSsBlockHeader>(cursor, 0);
                }

                // Process the block.
                if (blockHeader.Type == KphSsBlockType.Event)
                {
                    var eventBlock = _buffer.ReadStruct<KphSsEventBlock>(cursor, 0);
                    int[] arguments;
                    IntPtr[] stackTrace;

                    // Reconstruct the argument and stack trace arrays.

                    arguments = new int[eventBlock.NumberOfArguments];
                    stackTrace = new IntPtr[eventBlock.TraceCount];

                    for (int i = 0; i < arguments.Length; i++)
                        arguments[i] = _buffer.ReadInt32(cursor + eventBlock.ArgumentsOffset, i);
                    for (int i = 0; i < stackTrace.Length; i++)
                        stackTrace[i] = _buffer.ReadIntPtr(cursor + eventBlock.TraceOffset, i);

                    // Create an event object.
                    SsEvent ssEvent = new SsEvent();

                    // Basic information
                    ssEvent.Time = DateTime.FromFileTime(eventBlock.Time);
                    ssEvent.ThreadId = eventBlock.ClientId.ThreadId;
                    ssEvent.ProcessId = eventBlock.ClientId.ProcessId;
                    ssEvent.Arguments = arguments;
                    ssEvent.StackTrace = stackTrace;

                    // Flags
                    ssEvent.ArgumentsCopyFailed =
                        (eventBlock.Flags & KphSsEventFlags.CopyArgumentsFailed) == KphSsEventFlags.CopyArgumentsFailed;
                    ssEvent.ArgumentsProbeFailed =
                        (eventBlock.Flags & KphSsEventFlags.ProbeArgumentsFailed) == KphSsEventFlags.ProbeArgumentsFailed;
                    ssEvent.CallNumber = eventBlock.Number;

                    if ((eventBlock.Flags & KphSsEventFlags.UserMode) == KphSsEventFlags.UserMode)
                        ssEvent.Mode = KProcessorMode.UserMode;
                    else
                        ssEvent.Mode = KProcessorMode.KernelMode;

                    // Raise the event.
                    if (this.EventBlockReceived != null)
                        this.EventBlockReceived(ssEvent);
                }
                else if (blockHeader.Type == KphSsBlockType.Argument)
                {
                    var argBlock = _buffer.ReadStruct<KphSsArgumentBlock>(cursor, 0);
                    MemoryRegion dataRegion;
                    SsData ssArg = null;

                    dataRegion = new MemoryRegion(_buffer, cursor + KphSsArgumentBlock.DataOffset);

                    // Process the argument block based on its type.
                    switch (argBlock.Type)
                    {
                        case KphSsArgumentType.Int8:
                            {
                                SsSimple simpleArg = new SsSimple();

                                simpleArg.Argument = argBlock.Data.Int8;
                                simpleArg.Type = typeof(Byte);
                                ssArg = simpleArg;
                            }
                            break;
                        case KphSsArgumentType.Int16:
                            {
                                SsSimple simpleArg = new SsSimple();

                                simpleArg.Argument = argBlock.Data.Int16;
                                simpleArg.Type = typeof(Int16);
                                ssArg = simpleArg;
                            }
                            break;
                        case KphSsArgumentType.Int32:
                            {
                                SsSimple simpleArg = new SsSimple();

                                simpleArg.Argument = argBlock.Data.Int32;
                                simpleArg.Type = typeof(Int32);
                                ssArg = simpleArg;
                            }
                            break;
                        case KphSsArgumentType.Int64:
                            {
                                SsSimple simpleArg = new SsSimple();

                                simpleArg.Argument = argBlock.Data.Int64;
                                simpleArg.Type = typeof(Int64);
                                ssArg = simpleArg;
                            }
                            break;
                        case KphSsArgumentType.Handle:
                            {
                                ssArg = new SsHandle(dataRegion);
                            }
                            break;
                        case KphSsArgumentType.UnicodeString:
                            {
                                ssArg = new SsUnicodeString(dataRegion);
                            }
                            break;
                        case KphSsArgumentType.ObjectAttributes:
                            {
                                ssArg = new SsObjectAttributes(dataRegion);
                            }
                            break;
                        case KphSsArgumentType.ClientId:
                            {
                                ssArg = new SsClientId(dataRegion);
                            }
                            break;
                    }

                    ssArg.Index = argBlock.Index;

                    // Raise the event.
                    if (ssArg != null)
                    {
                        if (this.ArgumentBlockReceived != null)
                            this.ArgumentBlockReceived(ssArg);
                    }
                }

                // Advance the cursor.
                cursor += blockHeader.Size;
                // Signal that a buffer block is available for writing.
                _writeSemaphore.Release();
            }
        }