Exemplo n.º 1
0
            /// <summary>
            /// Performs the work.
            /// </summary>
            internal void PerformWork()
            {
                if (!_enabled)
                {
                    return;
                }

                try
                {
                    if (_args == null)
                    {
                        _result = _work.Method.Invoke(_work.Target, null);
                    }
                    else
                    {
                        _result = _work.Method.Invoke(_work.Target, _args.Length != 0 ? _args : null);
                    }
                }
                catch (Exception ex)
                {
                    _exception = ex;
                }

                _completedEvent.Set();
            }
Exemplo n.º 2
0
        public int Release(int count)
        {
#if USE_FAST_EVENT
            if (m_isClosed)
#else
            if (m_gate == null)
#endif
            { throw new ObjectDisposedException("Semaphore already closed"); }

            if (count < 1)
            {
                throw new ArgumentOutOfRangeException("count", "count must be > 0");
            }

            int cc = m_currentCount;
            if (InterlockedEx.Add(ref m_currentCount, count) > m_maximumCount)
            {
                throw new SemaphoreFullException("count exceeded maximum count");
            }

            m_gate.Set();              //Open gate

            return(cc);
        }
Exemplo n.º 3
0
        private void Update()
        {
            LinkedListEntry <IProvider> tempListHead = new LinkedListEntry <IProvider>();
            LinkedListEntry <IProvider> listEntry;
            NtStatus status = NtStatus.Success;

            _threadHandle = ThreadHandle.OpenCurrent(
                ThreadAccess.Alert | (ThreadAccess)StandardRights.Synchronize
                );
            _initializedEvent.Set();

            while (!_terminating)
            {
                LinkedList.InitializeListHead(tempListHead);

                Monitor.Enter(_listHead);

                // Main loop.

                while (true)
                {
                    if (status == NtStatus.Alerted)
                    {
                        // Check if we have any more providers to boost.
                        if (_boostCount == 0)
                        {
                            break;
                        }
                    }

                    listEntry = LinkedList.RemoveHeadList(_listHead);

                    if (listEntry == _listHead)
                    {
                        break;
                    }

                    // Add the provider to the temp list.
                    LinkedList.InsertTailList(tempListHead, listEntry);

                    if (status != NtStatus.Alerted)
                    {
                        if (!listEntry.Value.Enabled || listEntry.Value.Unregistering)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (listEntry.Value.Unregistering)
                        {
                            // Give the unregistering thread a chance to fix
                            // the boost count.
                            Monitor.Exit(_listHead);
                            Monitor.Enter(_listHead);

                            continue;
                        }
                    }

                    if (status == NtStatus.Alerted)
                    {
                        listEntry.Value.Boosting = false;
                        _boostCount--;
                    }

                    Monitor.Exit(_listHead);

                    try
                    {
                        listEntry.Value.Run();
                    }
                    finally
                    {
                        Monitor.Enter(_listHead);
                    }
                }

                // Re-add the items in the temp list to the main list.

                while ((listEntry = LinkedList.RemoveHeadList(tempListHead)) != tempListHead)
                {
                    LinkedList.InsertTailList(_listHead, listEntry);
                }

                Monitor.Exit(_listHead);

                // Wait for the interval. We may get alerted.
                status = _timerHandle.Wait(true);
            }
        }
Exemplo n.º 4
0
        private void LoadSymbols()
        {
            // Ensure we only load symbols once.
            if (Interlocked.CompareExchange(ref _symbolsStartedLoading, 1, 0) == 1)
            {
                return;
            }

            // Start loading symbols; avoid the UI blocking on the dbghelp call lock.
            _symbolsWorkQueue.QueueWorkItemTag(new Action(() =>
            {
                try
                {
                    // Needed (maybe) to display the EULA
                    Win32.SymbolServerSetOptions(SymbolServerOption.Unattended, 0);
                }
                catch (Exception ex)
                {
                    Logging.Log(ex);
                }

                try
                {
                    // Use the process handle if we have one, otherwise use the default ID generator.
                    if (_processHandle != null)
                    {
                        _symbols = new SymbolProvider(_processHandle);
                    }
                    else
                    {
                        _symbols = new SymbolProvider();
                    }

                    SymbolProvider.Options = SymbolOptions.DeferredLoads |
                                             (Settings.Instance.DbgHelpUndecorate ? SymbolOptions.UndName : 0);

                    if (!string.IsNullOrEmpty(Settings.Instance.DbgHelpSearchPath))
                    {
                        _symbols.SearchPath = Settings.Instance.DbgHelpSearchPath;
                    }

                    try
                    {
                        if (_pid > 4)
                        {
                            using (var phandle = new ProcessHandle(_pid, Program.MinProcessQueryRights | Program.MinProcessReadMemoryRights))
                            {
                                if (OSVersion.Architecture == OSArch.I386 || !phandle.IsWow64)
                                {
                                    // Load the process' modules.
                                    try { _symbols.LoadProcessModules(phandle); }
                                    catch { }
                                }
                                else
                                {
                                    // Load the process' WOW64 modules.
                                    try { _symbols.LoadProcessWow64Modules(_pid); }
                                    catch { }
                                }

                                // If the process is CSRSS we should load kernel modules
                                // due to the presence of kernel-mode threads.
                                if (phandle.KnownProcessType == KnownProcess.WindowsSubsystem)
                                {
                                    this.LoadKernelSymbols(true);
                                }
                            }
                        }
                        else
                        {
                            this.LoadKernelSymbols(true);
                        }
                    }
                    catch (WindowsException ex)
                    {
                        // Did we get Access Denied? At least load
                        // kernel32.dll and ntdll.dll.
                        try
                        {
                            ProcessHandle.Current.EnumModules(module =>
                            {
                                if (
                                    module.BaseName.Equals("kernel32.dll", StringComparison.OrdinalIgnoreCase) ||
                                    module.BaseName.Equals("ntdll.dll", StringComparison.OrdinalIgnoreCase)
                                    )
                                {
                                    _symbols.LoadModule(module.FileName, module.BaseAddress, module.Size);
                                }

                                return(true);
                            });
                        }
                        catch (Exception ex2)
                        {
                            Logging.Log(ex2);
                        }

                        Logging.Log(ex);
                    }
                    catch (Exception ex)
                    {
                        Logging.Log(ex);
                    }
                }
                finally
                {
                    _moduleLoadCompletedEvent.Set();
                }
            }), "symbols-load");
        }
Exemplo n.º 5
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();
                    }
                }
            }