private void Notify(CodeScope scope, bool starting)
        {
            var extensionManager = new CodeScopeExtensionManager(scope);

            lock (_lockObject)
            {
                try
                {
                    foreach (var listener in _listeners)
                    {
                        try
                        {
                            if (starting)
                            {
                                listener.Started(extensionManager);
                            }
                            else
                            {
                                listener.Ended(extensionManager);
                            }
                        }
                        catch (Exception ex)
                        {
                            Log(LogLevel.Error, "Failed to process code scope listener", ex);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log(LogLevel.Error, "General failure processing code scope listeners", ex);
                }
            }
        }
        private void OnScopeStarting(CodeScope codeScope)
        {
            lock (_lockObject)
            {
                //see if we already have a chain started
                var root = GetCurrentRoot();
                if (root != null)
                {
                    codeScope.SetRoot(root.ChainID, root);
                    Add(root, codeScope);
                }
                else
                {
                    //start a new root scope chain
                    var chainID = Guid.NewGuid();
                    codeScope.SetRoot(chainID, codeScope);
                    codeScope.NextNode     = null;
                    codeScope.PreviousNode = null;

                    CallContext.SetData(CODE_SCOPE_KEY, codeScope.ChainID);
                    AddRoot(codeScope);
                }
            }

            Notify(codeScope, true);
            OnOperationFinished();
        }
 private void RemoveRoot(CodeScope root)
 {
     lock (_lockObject)
     {
         _scopes.Remove(root.ChainID);
     }
 }
 private void AddRoot(CodeScope root)
 {
     lock (_lockObject)
     {
         _scopes.Add(root.ChainID, new WeakReference <CodeScope>(root));
     }
 }
        private void Add(CodeScope head, CodeScope node)
        {
            if (head == null)
            {
                throw new ArgumentNullException(nameof(head));
            }

            var current = head;

            while (current.NextNode != null)
            {
                current = (CodeScope)current.NextNode;
            }

            current.NextNode  = node;
            node.PreviousNode = current;
        }
        private void OnScopeEnding(CodeScope codeScope)
        {
            lock (_lockObject)
            {
                var root = GetRoot(codeScope.ChainID);
                if (root != null)
                {
                    var tail = Remove(root);
                    if (root == tail)
                    {
                        RemoveRoot(root);
                        CallContext.FreeNamedDataSlot(CODE_SCOPE_KEY);
                    }
                }
            }

            Notify(codeScope, false);
            OnOperationFinished();
        }
        private CodeScope Remove(CodeScope head)
        {
            CodeScope last = null;

            while (head != null)
            {
                if (head.NextNode == null)
                {
                    last = head;
                }
                head = (CodeScope)head.NextNode;
            }

            if (last?.PreviousNode != null)
            {
                var previous = (CodeScope)last.PreviousNode;
                previous.NextNode = null;
            }

            return(last);
        }
 internal static void EndScope(CodeScope codeScope)
 {
     Instance.OnScopeEnding(codeScope);
 }
 internal static void BeginScope(CodeScope codeScope)
 {
     Instance.OnScopeStarting(codeScope);
 }