Beispiel #1
0
		protected void DeliverEventToList (object sender, EventArgs args, ListenerList list)
		{
			for (int i = 0; i < list.Count; i ++) {
				IWeakEventListener listener = list[i];
				listener.ReceiveWeakEvent (GetType(), sender, args);
			}
		}
Beispiel #2
0
		internal ListenerHandle(ListenerList parent, Type type, RepositoryListener listener
			)
		{
			this.parent = parent;
			this.type = type;
			this.listener = listener;
		}
Beispiel #3
0
        public override void InitializePlugin(IPoderosaWorld poderosa) {
            _instance = this;
            base.InitializePlugin(poderosa);
            _sessionMap = new TypedHashtable<ISession, SessionHost>();
            _documentMap = new TypedHashtable<IPoderosaDocument, DocumentHost>();
            _docViewRelationHandler = poderosa.PluginManager.CreateExtensionPoint("org.poderosa.core.sessions.docViewRelationHandler", typeof(IDocViewRelationEventHandler), this);
            _activeDocumentChangeListeners = new ListenerList<IActiveDocumentChangeListener>();
            _activeDocumentChangeListeners.Add(new WindowCaptionManager());

            _sessionListeners = new ListenerList<ISessionListener>();
        }
        protected void DeliverEventToList(object sender, EventArgs args, ListenerList list)
        {
            if (list == null)
                throw new ArgumentNullException("list");

            for (int i = 0; i < list.Count; i++)
            {
                IWeakEventListener listener = list[i];
                listener.ReceiveWeakEvent(GetType(), sender, args);
            }
        }
Beispiel #5
0
        public override void InitializePlugin(IPoderosaWorld poderosa) {
            base.InitializePlugin(poderosa);
            _instance = this;
            _commands = new List<IGeneralCommand>();
            _idToCommand = new TypedHashtable<string, IGeneralCommand>();
            _keyBind = new KeyBindConfiguration();
            _keyBindChangeListener = new ListenerList<IKeyBindChangeListener>();

            BasicCommandImplementation.Build();

            poderosa.PluginManager.FindExtensionPoint(PreferencePlugin.EXTENSIONPOINT_NAME).RegisterExtension(this);
        }
        protected void DeliverEventToList(object sender, EventArgs args, ListenerList list)
        {
            if (list == null)
            {
                throw new ArgumentNullException("list");
            }

            for (int i = 0; i < list.Count; i++)
            {
                IWeakEventListener listener = list[i];
                listener.ReceiveWeakEvent(GetType(), sender, args);
            }
        }
Beispiel #7
0
            /// <summary>
            /// If the given list is in use (which means an event is currently
            /// being delivered), replace it with a clone.  The existing
            /// users will finish delivering the event to the original list,
            /// without interference from changes to the new list.
            /// </summary>
            /// <returns>
            /// True if the list was cloned.  Callers will probably want to
            /// insert the new list in their own data structures.
            /// </returns>
            public static bool PrepareForWriting(ref ListenerList list)
            {
                bool inUse = list.BeginUse();

                list.EndUse();

                if (inUse)
                {
                    list = list.Clone();
                }

                return(inUse);
            }
Beispiel #8
0
        public override void InitializePlugin(IPoderosaWorld poderosa)
        {
            base.InitializePlugin(poderosa);
            _instance              = this;
            _commands              = new List <IGeneralCommand>();
            _idToCommand           = new TypedHashtable <string, IGeneralCommand>();
            _keyBind               = new KeyBindConfiguration();
            _keyBindChangeListener = new ListenerList <IKeyBindChangeListener>();

            BasicCommandImplementation.Build();

            poderosa.PluginManager.FindExtensionPoint(PreferencePlugin.EXTENSIONPOINT_NAME).RegisterExtension(this);
        }
Beispiel #9
0
        private void AddListener(INotifyPropertyChanged source, string propertyName, IWeakEventListener listener, EventHandler <PropertyChangedEventArgs> handler)
        {
            using (WriteLock)
            {
                HybridDictionary dict = (HybridDictionary)this[source];

                if (dict == null)
                {
                    // no entry in the hashtable - add a new one
                    dict = new HybridDictionary(true /* case insensitive */);

                    this[source] = dict;

                    // listen for the desired events
                    StartListening(source);
                }

                ListenerList list = (ListenerList)dict[propertyName];

                if (list == null)
                {
                    // no entry in the dictionary - add a new one
                    list = new ListenerList <PropertyChangedEventArgs>();

                    dict[propertyName] = list;
                }

                // make sure list is ready for writing
                if (ListenerList.PrepareForWriting(ref list))
                {
                    dict[propertyName] = list;
                }

                // add a listener to the list
                if (handler != null)
                {
                    ListenerList <PropertyChangedEventArgs> hlist = (ListenerList <PropertyChangedEventArgs>)list;
                    hlist.AddHandler(handler);
                }
                else
                {
                    list.Add(listener);
                }

                dict.Remove(AllListenersKey);   // invalidate list of all listeners
                _proposedAllListenersList = null;

                // schedule a cleanup pass
                ScheduleCleanup();
            }
        }
Beispiel #10
0
        private void RemoveListener(INotifyPropertyChanged source, string propertyName, IWeakEventListener listener, EventHandler <PropertyChangedEventArgs> handler)
        {
            using (WriteLock)
            {
                HybridDictionary dict = (HybridDictionary)this[source];

                if (dict != null)
                {
                    ListenerList list = (ListenerList)dict[propertyName];

                    if (list != null)
                    {
                        // make sure list is ready for writing
                        if (ListenerList.PrepareForWriting(ref list))
                        {
                            dict[propertyName] = list;
                        }

                        // remove a listener from the list
                        if (handler != null)
                        {
                            ListenerList <PropertyChangedEventArgs> hlist = (ListenerList <PropertyChangedEventArgs>)list;
                            hlist.RemoveHandler(handler);
                        }
                        else
                        {
                            list.Remove(listener);
                        }

                        // when the last listener goes away, remove the list
                        if (list.IsEmpty)
                        {
                            dict.Remove(propertyName);
                        }
                    }

                    if (dict.Count == 0)
                    {
                        StopListening(source);

                        Remove(source);
                    }

                    dict.Remove(AllListenersKey);   // invalidate list of all listeners
                    _proposedAllListenersList = null;
                }
            }
        }
        public void Add(Guid EventID, Del_HandleEvent EventHandler, enPriority HandlePriority)
        {
            //Case:Exist eventId matched ListenerGroup
            if (m_Listeners.TryGetValue(EventID, out var ListenerGroup))
            {
                //Case: Exist priority matched Listener List
                //Act: Just Add Listener
                if (ListenerGroup.TryGetValue(HandlePriority, out var ListenerList))
                {
                    m_PrioritiesDic.Add(EventHandler, HandlePriority);

                    ListenerList.Add(EventHandler);
                }
                //Case: no priority matched Listener List
                //Act: Make a instnace of Listener list first and Add Listener
                else
                {
                    ListenerList = new List <Del_HandleEvent>();

                    m_PrioritiesDic.Add(EventHandler, HandlePriority);

                    ListenerList.Add(EventHandler);

                    ListenerGroup.Add(HandlePriority, ListenerList);
                }
            }
            //Case: no eventId matched ListenerGroup
            else
            {
                //Make an instance of ListenerGroup
                ListenerGroup = new SortedDictionary <enPriority, List <Del_HandleEvent> >();

                //Make an instance of ListenerList
                List <Del_HandleEvent> ListenerList = new List <Del_HandleEvent>();

                //Save to dictionary
                m_PrioritiesDic.Add(EventHandler, HandlePriority);

                //add Handler
                ListenerList.Add(EventHandler);

                //add ListenerList
                ListenerGroup.Add(HandlePriority, ListenerList);

                //add ListenerGroup
                m_Listeners.Add(EventID, ListenerGroup);
            }
        }
Beispiel #12
0
            internal void Remove(IWeakEventListener listener)
            {
                if (listener == null)
                {
                    return;
                }

                ListenerList.PrepareForWriting(ref _listeners);

                _listeners.Remove(listener);

                if (_listeners.IsEmpty)
                {
                    StopListening();
                }
            }
Beispiel #13
0
        public TerminalSettings()
        {
            //IPoderosaCulture culture = TerminalEmulatorPlugin.Instance.PoderosaWorld.Culture;
            //if (culture.IsJapaneseOS || culture.IsSimplifiedChineseOS || culture.IsTraditionalChineseOS || culture.IsKoreanOS)
            //    _encoding = EncodingType.UTF8;
            //else
            _encoding = EncodingType.ISO8859_1;

            _debug            = 0;
            _terminalType     = TerminalType.XTerm;
            _localecho        = false;
            _lineFeedRule     = LineFeedRule.Normal;
            _transmitnl       = NewLine.CR;
            _multiLogSettings = new MultiLogSettings();

            _listeners = new ListenerList <ITerminalSettingsChangeListener>();
        }
Beispiel #14
0
        public TerminalSettings() {
            IPoderosaCulture culture = TerminalEmulatorPlugin.Instance.PoderosaWorld.Culture;
            if (culture.IsJapaneseOS || culture.IsSimplifiedChineseOS || culture.IsTraditionalChineseOS || culture.IsKoreanOS)
                _encoding = EncodingType.UTF8;
            else
                _encoding = EncodingType.ISO8859_1;

            _terminalType = TerminalType.XTerm;
            _localecho = false;
            _lineFeedRule = LineFeedRule.Normal;
            _transmitnl = NewLine.CR;
            _renderProfile = null;
            _shellSchemeName = ShellSchemeCollection.DEFAULT_SCHEME_NAME;
            _enabledCharTriggerIntelliSense = false;
            _multiLogSettings = new MultiLogSettings();

            _listeners = new ListenerList<ITerminalSettingsChangeListener>();
        }
Beispiel #15
0
            // add a listener
            public void Add(IWeakEventListener listener, EventHandler <ValueChangedEventArgs> handler)
            {
                // make sure list is ready for writing
                ListenerList list = _listeners;

                if (ListenerList.PrepareForWriting(ref list))
                {
                    _listeners = (ListenerList <ValueChangedEventArgs>)list;
                }

                if (handler != null)
                {
                    _listeners.AddHandler(handler);
                }
                else
                {
                    _listeners.Add(listener);
                }
            }
Beispiel #16
0
            public void StoreAllListenersList(ListenerList <PropertyChangedEventArgs> list)
            {
                // test again, in case another thread changed _proposedAllListersList.
                if (_proposedAllListenersList == list)
                {
                    _dict[AllListenersKey] = new PropertyRecord(AllListenersKey, this, list);

                    _proposedAllListenersList = null;
                }

                // Another thread could have changed _proposedAllListersList
                // since we set it (earlier in this method), either
                // because it calculated a new one while handling a PropertyChanged(""),
                // or because it added/removed/purged a listener.
                // In that case, we will simply abandon our proposed list and we'll
                // have to compute it again the next time.  But that only happens
                // if there's thread contention.  It's not worth doing something
                // more complicated just for that case.
            }
        /// <summary>
        /// Remove dead entries from the data for the given source.   Returns true if
        /// some entries were actually removed.
        /// </summary>
        protected virtual bool Purge(object source, object data, bool purgeAll)
        {
            bool foundDirt = false;

            bool removeList = purgeAll || source == null;

            // remove dead entries from the list
            if (!removeList)
            {
                ListenerList list = (ListenerList)data;

                if (ListenerList.PrepareForWriting(ref list) && source != null)
                {
                    Table[this, source] = list;
                }

                if (list.Purge())
                {
                    foundDirt = true;
                }

                removeList = list.IsEmpty;
            }

            // if the list is no longer needed, stop listening to the event
            if (removeList)
            {
                if (source != null) // source may have been GC'd
                {
                    StopListening(source);

                    // remove the list completely (in the purgeAll case, we'll do it later)
                    if (!purgeAll)
                    {
                        Table.Remove(this, source);
                        foundDirt = true;
                    }
                }
            }

            return(foundDirt);
        }
        public TerminalSettings()
        {
            //IPoderosaCulture culture = TerminalEmulatorPlugin.Instance.PoderosaWorld.Culture;
            //if (culture.IsJapaneseOS || culture.IsSimplifiedChineseOS || culture.IsTraditionalChineseOS || culture.IsKoreanOS)
            //  _encoding = EncodingType.UTF8;
            //else
            //  _encoding = EncodingType.ISO8859_1;
            _encoding = Poderosa.Protocols.CygwinUtil.CygwinDefaultEncoding;

            _terminalType    = TerminalType.Cygwin;
            _localecho       = false;
            _lineFeedRule    = LineFeedRule.Normal;
            _transmitnl      = NewLine.CR;
            _renderProfile   = null;
            _shellSchemeName = ShellSchemeCollection.DEFAULT_SCHEME_NAME;
            _enabledCharTriggerIntelliSense = false;
            _multiLogSettings = new MultiLogSettings();

            _listeners = new ListenerList <ITerminalSettingsChangeListener>();
        }
        private void AddListener(object source, IWeakEventListener listener, Delegate handler)
        {
            object sourceKey = (source != null) ? source : StaticSource;

            using (Table.WriteLock)
            {
                ListenerList list = (ListenerList)Table[this, sourceKey];

                if (list == null)
                {
                    // no entry in the table - add a new one
                    list = NewListenerList();
                    Table[this, sourceKey] = list;

                    // listen for the desired event
                    StartListening(source);
                }

                // make sure list is ready for writing
                if (ListenerList.PrepareForWriting(ref list))
                {
                    Table[this, source] = list;
                }

                // add a target to the list of listeners
                if (handler != null)
                {
                    list.AddHandler(handler);
                }
                else
                {
                    list.Add(listener);
                }

                // schedule a cleanup pass (heuristic (b) described above)
                ScheduleCleanup();
            }
        }
Beispiel #20
0
 private static uint KeepListener(
     GLib.Signal.EmissionHook listener,
     string objType, string signalName, string hookData)
 {
     GLib.GType type = GLib.GType.FromName(objType);
     if (type != GLib.GType.Invalid)
     {
         lock (listenerListMutex)
         {
             ListenerInfo info = new ListenerInfo();
             info.Id         = (uint)ListenerList.Count + 1;
             info.SignalName = signalName;
             info.Type       = type;
             info.HookId     = GLib.Signal.AddEmissionHook(signalName, type, listener);
             ListenerList.Add(info.Id, info);
             return(info.Id);
         }
     }
     else
     {
         throw new NotSupportedException("Invalid object type " + objType);
     }
 }
            protected void CopyTo(ListenerList newList)
            {
                IWeakEventListener iwel;

                for (int k = 0, n = Count; k < n; ++k)
                {
                    Listener listener = GetListener(k);
                    if (listener.Target != null)
                    {
                        if (listener.HasHandler)
                        {
                            Delegate handler = listener.Handler;
                            if (handler != null)
                            {
                                newList.AddHandler(handler);
                            }
                        }
                        else if ((iwel = listener.Target as IWeakEventListener) != null)
                        {
                            newList.Add(iwel);
                        }
                    }
                }
            }
        private void RemoveListener(object source, object target, Delegate handler)
        {
            object sourceKey = (source != null) ? source : StaticSource;

            using (Table.WriteLock)
            {
                ListenerList list = (ListenerList)Table[this, sourceKey];

                if (list != null)
                {
                    // make sure list is ready for writing
                    if (ListenerList.PrepareForWriting(ref list))
                    {
                        Table[this, sourceKey] = list;
                    }

                    // remove the target from the list of listeners
                    if (handler != null)
                    {
                        list.RemoveHandler(handler);
                    }
                    else
                    {
                        list.Remove((IWeakEventListener)target);
                    }

                    // after removing the last listener, stop listening
                    if (list.IsEmpty)
                    {
                        Table.Remove(this, sourceKey);

                        StopListening(source);
                    }
                }
            }
        }
 /// <summary>Prevents a default instance of the WeakCultureChangedEventManager class from being created.</summary>
 WeakCultureChangedEventManager()
 {
     // creates a new list and assign it to listeners
     this.listeners = new ListenerList();
 }
Beispiel #24
0
 /// <summary>
 /// Return a copy of the list.
 /// </summary>
 public virtual ListenerList Clone()
 {
     ListenerList result = new ListenerList();
     CopyTo(result);
     return result;
 }
        /// <summary>
        /// Remove dead entries from the data for the given source.   Returns true if
        /// some entries were actually removed.
        /// </summary>
        protected override bool Purge(object source, object data, bool purgeAll)
        {
            bool foundDirt = false;

            if (!purgeAll)
            {
                HybridDictionary dict = (HybridDictionary)data;
                int ignoredKeys       = 0;

                if (!BaseAppContextSwitches.EnableWeakEventMemoryImprovements)
                {
                    // copy the keys into a separate array, so that later on
                    // we can change the dictionary while iterating over the keys
                    ICollection ic   = dict.Keys;
                    String[]    keys = new String[ic.Count];
                    ic.CopyTo(keys, 0);

                    for (int i = keys.Length - 1; i >= 0; --i)
                    {
                        if (keys[i] == AllListenersKey)
                        {
                            ++ignoredKeys;
                            continue;       // ignore the special entry for now
                        }

                        // for each key, remove dead entries in its list
                        bool removeList = purgeAll || source == null;

                        if (!removeList)
                        {
                            ListenerList list = (ListenerList)dict[keys[i]];

                            if (ListenerList.PrepareForWriting(ref list))
                            {
                                dict[keys[i]] = list;
                            }

                            if (list.Purge())
                            {
                                foundDirt = true;
                            }

                            removeList = (list.IsEmpty);
                        }

                        // if there are no more entries, remove the key
                        if (removeList)
                        {
                            dict.Remove(keys[i]);
                        }
                    }
#if WeakEventTelemetry
                    LogAllocation(ic.GetType(), 1, 12);                     // dict.Keys - Hashtable+KeyCollection
                    LogAllocation(typeof(String[]), 1, 12 + ic.Count * 4);  // keys
#endif
                }
                else
                {
                    Debug.Assert(_toRemove.Count == 0, "to-remove list should be empty");

                    // enumerate the dictionary using IDE explicitly rather than
                    // foreach, to avoid allocating temporary DictionaryEntry objects
                    IDictionaryEnumerator ide = dict.GetEnumerator() as IDictionaryEnumerator;
                    while (ide.MoveNext())
                    {
                        String key = (String)ide.Key;
                        if (key == AllListenersKey)
                        {
                            ++ignoredKeys;
                            continue;       // ignore the special entry for now
                        }

                        // for each key, remove dead entries in its list
                        bool removeList = purgeAll || source == null;

                        if (!removeList)
                        {
                            ListenerList list = (ListenerList)ide.Value;

                            if (ListenerList.PrepareForWriting(ref list))
                            {
                                dict[key] = list;
                            }

                            if (list.Purge())
                            {
                                foundDirt = true;
                            }

                            removeList = (list.IsEmpty);
                        }

                        // if there are no more entries, remove the key
                        if (removeList)
                        {
                            _toRemove.Add(key);
                        }
                    }

                    // do the actual removal (outside the dictionary iteration)
                    if (_toRemove.Count > 0)
                    {
                        foreach (String key in _toRemove)
                        {
                            dict.Remove(key);
                        }
                        _toRemove.Clear();
                        _toRemove.TrimExcess();
                    }

#if WeakEventTelemetry
                    Type enumeratorType = ide.GetType();
                    if (enumeratorType.Name.IndexOf("NodeEnumerator") >= 0)
                    {
                        LogAllocation(enumeratorType, 1, 24);                    // ListDictionary+NodeEnumerator
                    }
                    else
                    {
                        LogAllocation(enumeratorType, 1, 36);                    // Hashtable+HashtableEnumerator
                    }
#endif
                }

                if (dict.Count == ignoredKeys)
                {
                    // if there are no more listeners at all, remove the entry from
                    // the main table, and prepare to stop listening
                    purgeAll = true;
                    if (source != null)     // source may have been GC'd
                    {
                        this.Remove(source);
                    }
                }
                else if (foundDirt)
                {
                    // if any entries were purged, invalidate the special entry
                    dict.Remove(AllListenersKey);
                    _proposedAllListenersList = null;
                }
            }

            if (purgeAll)
            {
                // stop listening.  List cleanup is handled by Purge()
                if (source != null) // source may have been GC'd
                {
                    StopListening(source);
                }
                foundDirt = true;
            }

            return(foundDirt);
        }
 public PropertyRecord(string propertyName, TypeRecord owner, ListenerList<PropertyChangedEventArgs> list)
 {
     _propertyName = propertyName;
     _typeRecord = owner;
     _list = list;
 }
            public void StoreAllListenersList(ListenerList<PropertyChangedEventArgs> list)
            {
                // test again, in case another thread changed _proposedAllListersList.
                if (_proposedAllListenersList == list)
                {
                    _dict[AllListenersKey] = new PropertyRecord(AllListenersKey, this, list);

                    _proposedAllListenersList = null;
                }

                // Another thread could have changed _proposedAllListersList
                // since we set it (earlier in this method), either
                // because it calculated a new one while handling a PropertyChanged(""),
                // or because it added/removed/purged a listener.
                // In that case, we will simply abandon our proposed list and we'll
                // have to compute it again the next time.  But that only happens
                // if there's thread contention.  It's not worth doing something
                // more complicated just for that case.
            }
            public ListenerList GetListenerList(string propertyName)
            {
                ListenerList list;

                if (!String.IsNullOrEmpty(propertyName))
                {
                    // source has changed a particular property.  Notify targets
                    // who are listening either for this property or for all properties.
                    PropertyRecord pr = (PropertyRecord)_dict[propertyName];
                    ListenerList<PropertyChangedEventArgs> listeners = (pr == null) ? null : pr.List;
                    PropertyRecord genericRecord = (PropertyRecord)_dict[String.Empty];
                    ListenerList<PropertyChangedEventArgs> genericListeners = (genericRecord == null) ? null : genericRecord.List;

                    if (genericListeners == null)
                    {
                        if (listeners != null)
                        {
                            list = listeners;           // only specific listeners
                        }
                        else
                        {
                            list = ListenerList.Empty;  // no listeners at all
                        }
                    }
                    else
                    {
                        if (listeners != null)
                        {
                            // there are both specific and generic listeners -
                            // combine the two lists.
                            list = new ListenerList<PropertyChangedEventArgs>(listeners.Count + genericListeners.Count);
                            for (int i=0, n=listeners.Count; i<n; ++i)
                                list.Add(listeners[i]);
                            for (int i=0, n=genericListeners.Count; i<n; ++i)
                                list.Add(genericListeners[i]);
                        }
                        else
                        {
                            list = genericListeners;    // only generic listeners
                        }
                    }
                }
                else
                {
                    // source has changed all properties.  Notify all targets.
                    // Use previously calculated combined list, if available.
                    PropertyRecord pr = (PropertyRecord)_dict[AllListenersKey];
                    ListenerList<PropertyChangedEventArgs> pcList = (pr == null) ? null : pr.List;

                    if (pcList == null)
                    {
                        // make one pass to compute the size of the combined list.
                        // This avoids expensive reallocations.
                        int size = 0;
                        foreach (DictionaryEntry de in _dict)
                        {
                            Debug.Assert((String)de.Key != AllListenersKey, "special key should not appear");
                            size += ((PropertyRecord)de.Value).List.Count;
                        }

                        // create the combined list
                        pcList = new ListenerList<PropertyChangedEventArgs>(size);

                        // fill in the combined list
                        foreach (DictionaryEntry de in _dict)
                        {
                            ListenerList listeners = ((PropertyRecord)de.Value).List;
                            for (int i=0, n=listeners.Count;  i<n;  ++i)
                            {
                                pcList.Add(listeners.GetListener(i));
                            }
                        }

                        // save the result for future use (see below)
                        _proposedAllListenersList = pcList;
                    }

                    list = pcList;
                }

                return list;
            }
Beispiel #29
0
 public PropertyRecord(string propertyName, TypeRecord owner, ListenerList <PropertyChangedEventArgs> list)
 {
     _propertyName = propertyName;
     _typeRecord   = owner;
     _list         = list;
 }
Beispiel #30
0
        /// <summary>
        /// Remove dead entries from the data for the given source.   Returns true if
        /// some entries were actually removed.
        /// </summary>
        protected override bool Purge(object source, object data, bool purgeAll)
        {
            bool foundDirt = false;

            if (!purgeAll)
            {
                HybridDictionary dict = (HybridDictionary)data;
                int ignoredKeys       = 0;

                if (!BaseAppContextSwitches.EnableWeakEventMemoryImprovements)
                {
                    // copy the keys into a separate array, so that later on
                    // we can change the dictionary while iterating over the keys
                    ICollection ic   = dict.Keys;
                    String[]    keys = new String[ic.Count];
                    ic.CopyTo(keys, 0);

                    for (int i = keys.Length - 1; i >= 0; --i)
                    {
                        if (keys[i] == AllListenersKey)
                        {
                            ++ignoredKeys;
                            continue;       // ignore the special entry for now
                        }

                        // for each key, remove dead entries in its list
                        bool removeList = purgeAll || source == null;

                        if (!removeList)
                        {
                            ListenerList list = (ListenerList)dict[keys[i]];

                            if (ListenerList.PrepareForWriting(ref list))
                            {
                                dict[keys[i]] = list;
                            }

                            if (list.Purge())
                            {
                                foundDirt = true;
                            }

                            removeList = (list.IsEmpty);
                        }

                        // if there are no more entries, remove the key
                        if (removeList)
                        {
                            dict.Remove(keys[i]);
                        }
                    }
#if WeakEventTelemetry
                    LogAllocation(ic.GetType(), 1, 12);                     // dict.Keys - Hashtable+KeyCollection
                    LogAllocation(typeof(String[]), 1, 12 + ic.Count * 4);  // keys
#endif
                }
                else
                {
                    Debug.Assert(_toRemove.Count == 0, "to-remove list should be empty");

                    // If an "in-use" list is changed, we will re-install its clone
                    // back into the dictionary.  Doing this inside the loop
                    // causes an exception "collection was modified after the enumerator
                    // was instantiated" (DDVSO 812614), so instead just record
                    // what to do and do the actual work after the loop.
                    // This is a rare case - it only arises if a PropertyChanged event
                    // handler calls (indirectly) into the cleanup code - so allocate
                    // the temporary memory lazily on the stack.
                    // [In the bug, the indirect call comes about because the app's
                    // event handler calls ShowDialog(), which pushes a dispatcher
                    // frame to run a nested message pump. Then a pending cleanup task
                    // reaches the front of the dispatcher queue before the dialog
                    // is dismissed, effectively calling this method while the
                    // PropertyChanged event delivery is in progress.]
                    HybridDictionary toInstall = null;

                    // enumerate the dictionary using IDE explicitly rather than
                    // foreach, to avoid allocating temporary DictionaryEntry objects
                    IDictionaryEnumerator ide = dict.GetEnumerator() as IDictionaryEnumerator;
                    while (ide.MoveNext())
                    {
                        String key = (String)ide.Key;
                        if (key == AllListenersKey)
                        {
                            ++ignoredKeys;
                            continue;       // ignore the special entry for now
                        }

                        // for each key, remove dead entries in its list
                        bool removeList = purgeAll || source == null;

                        if (!removeList)
                        {
                            ListenerList list = (ListenerList)ide.Value;

                            bool inUse     = ListenerList.PrepareForWriting(ref list);
                            bool isChanged = false;

                            if (list.Purge())
                            {
                                isChanged = true;
                                foundDirt = true;
                            }

                            removeList = (list.IsEmpty);

                            // if a cloned list changed, remember the details
                            // so that the clone can be installed back into the
                            // dictionary outside the iteration (DDVSO 812614)
                            if (!removeList && inUse && isChanged)
                            {
                                if (toInstall == null)
                                {
                                    // lazy allocation
                                    toInstall = new HybridDictionary();
                                }

                                toInstall[key] = list;
                            }
                        }

                        // if there are no more entries, remove the key
                        if (removeList)
                        {
                            _toRemove.Add(key);
                        }
                    }

                    // do the actual removal (outside the dictionary iteration)
                    if (_toRemove.Count > 0)
                    {
                        foreach (String key in _toRemove)
                        {
                            dict.Remove(key);
                        }
                        _toRemove.Clear();
                        _toRemove.TrimExcess();
                    }

                    // do the actual re-install of "in-use" lists that changed
                    if (toInstall != null)
                    {
                        IDictionaryEnumerator installDE = toInstall.GetEnumerator() as IDictionaryEnumerator;
                        while (installDE.MoveNext())
                        {
                            String       key  = (String)installDE.Key;
                            ListenerList list = (ListenerList)installDE.Value;
                            dict[key] = list;
                        }
                    }

#if WeakEventTelemetry
                    Type enumeratorType = ide.GetType();
                    if (enumeratorType.Name.IndexOf("NodeEnumerator") >= 0)
                    {
                        LogAllocation(enumeratorType, 1, 24);                    // ListDictionary+NodeEnumerator
                    }
                    else
                    {
                        LogAllocation(enumeratorType, 1, 36);                    // Hashtable+HashtableEnumerator
                    }
#endif
                }

                if (dict.Count == ignoredKeys)
                {
                    // if there are no more listeners at all, remove the entry from
                    // the main table, and prepare to stop listening
                    purgeAll = true;
                    if (source != null)     // source may have been GC'd
                    {
                        this.Remove(source);
                    }
                }
                else if (foundDirt)
                {
                    // if any entries were purged, invalidate the special entry
                    dict.Remove(AllListenersKey);
                    _proposedAllListenersList = null;
                }
            }

            if (purgeAll)
            {
                // stop listening.  List cleanup is handled by Purge()
                if (source != null) // source may have been GC'd
                {
                    StopListening(source);
                }
                foundDirt = true;
            }

            return(foundDirt);
        }
Beispiel #31
0
        /// <summary>
        /// Remove dead entries from the data for the given source.   Returns true if
        /// some entries were actually removed.
        /// </summary>
        protected override bool Purge(object source, object data, bool purgeAll)
        {
            bool foundDirt = false;

            if (!purgeAll)
            {
                HybridDictionary dict = (HybridDictionary)data;

                // copy the keys into a separate array, so that later on
                // we can change the dictionary while iterating over the keys
                ICollection ic   = dict.Keys;
                String[]    keys = new String[ic.Count];
                ic.CopyTo(keys, 0);

                for (int i = keys.Length - 1; i >= 0; --i)
                {
                    if (keys[i] == AllListenersKey)
                    {
                        continue;       // ignore the special entry for now
                    }
                    // for each key, remove dead entries in its list
                    bool removeList = purgeAll || source == null;

                    if (!removeList)
                    {
                        ListenerList list = (ListenerList)dict[keys[i]];

                        if (ListenerList.PrepareForWriting(ref list))
                        {
                            dict[keys[i]] = list;
                        }

                        if (list.Purge())
                        {
                            foundDirt = true;
                        }

                        removeList = (list.IsEmpty);
                    }

                    // if there are no more entries, remove the key
                    if (removeList)
                    {
                        dict.Remove(keys[i]);
                    }
                }

                if (dict.Count == 0)
                {
                    // if there are no more listeners at all, remove the entry from
                    // the main table, and prepare to stop listening
                    purgeAll = true;
                    if (source != null)     // source may have been GC'd
                    {
                        this.Remove(source);
                    }
                }
                else if (foundDirt)
                {
                    // if any entries were purged, invalidate the special entry
                    dict.Remove(AllListenersKey);
                    _proposedAllListenersList = null;
                }
            }

            if (purgeAll)
            {
                // stop listening.  List cleanup is handled by Purge()
                if (source != null) // source may have been GC'd
                {
                    StopListening(source);
                }
                foundDirt = true;
            }

            return(foundDirt);
        }
Beispiel #32
0
 internal void Add(IWeakEventListener listener)
 {
     ListenerList.PrepareForWriting(ref _listeners);
     _listeners.Add(listener);
 }
Beispiel #33
0
 internal bool Purge()
 {
     ListenerList.PrepareForWriting(ref _listeners);
     return(_listeners.Purge());
 }
        private void AddListener(INotifyPropertyChanged source, string propertyName, IWeakEventListener listener, EventHandler<PropertyChangedEventArgs> handler)
        {
            using (WriteLock)
            {
                HybridDictionary dict = (HybridDictionary)this[source];

                if (dict == null)
                {
                    // no entry in the hashtable - add a new one
                    dict = new HybridDictionary(true /* case insensitive */);

                    this[source] = dict;

                    // listen for the desired events
                    StartListening(source);
                }

                ListenerList list = (ListenerList)dict[propertyName];

                if (list == null)
                {
                    // no entry in the dictionary - add a new one
                    list = new ListenerList<PropertyChangedEventArgs>();

                    dict[propertyName] = list;
                }

                // make sure list is ready for writing
                if (ListenerList.PrepareForWriting(ref list))
                {
                    dict[propertyName] = list;
                }

                // add a listener to the list
                if (handler != null)
                {
                    ListenerList<PropertyChangedEventArgs> hlist = (ListenerList<PropertyChangedEventArgs>)list;
                    hlist.AddHandler(handler);
                }
                else
                {
                    list.Add(listener);
                }

                dict.Remove(AllListenersKey);   // invalidate list of all listeners
                _proposedAllListenersList = null;

                // schedule a cleanup pass
                ScheduleCleanup();
            }
        }
Beispiel #35
0
            public ListenerList GetListenerList(string propertyName)
            {
                ListenerList list;

                if (!String.IsNullOrEmpty(propertyName))
                {
                    // source has changed a particular property.  Notify targets
                    // who are listening either for this property or for all properties.
                    PropertyRecord pr = (PropertyRecord)_dict[propertyName];
                    ListenerList <PropertyChangedEventArgs> listeners = (pr == null) ? null : pr.List;
                    PropertyRecord genericRecord = (PropertyRecord)_dict[String.Empty];
                    ListenerList <PropertyChangedEventArgs> genericListeners = (genericRecord == null) ? null : genericRecord.List;

                    if (genericListeners == null)
                    {
                        if (listeners != null)
                        {
                            list = listeners;           // only specific listeners
                        }
                        else
                        {
                            list = ListenerList.Empty;  // no listeners at all
                        }
                    }
                    else
                    {
                        if (listeners != null)
                        {
                            // there are both specific and generic listeners -
                            // combine the two lists.
                            list = new ListenerList <PropertyChangedEventArgs>(listeners.Count + genericListeners.Count);
                            for (int i = 0, n = listeners.Count; i < n; ++i)
                            {
                                list.Add(listeners[i]);
                            }
                            for (int i = 0, n = genericListeners.Count; i < n; ++i)
                            {
                                list.Add(genericListeners[i]);
                            }
                        }
                        else
                        {
                            list = genericListeners;    // only generic listeners
                        }
                    }
                }
                else
                {
                    // source has changed all properties.  Notify all targets.
                    // Use previously calculated combined list, if available.
                    PropertyRecord pr = (PropertyRecord)_dict[AllListenersKey];
                    ListenerList <PropertyChangedEventArgs> pcList = (pr == null) ? null : pr.List;

                    if (pcList == null)
                    {
                        // make one pass to compute the size of the combined list.
                        // This avoids expensive reallocations.
                        int size = 0;
                        foreach (DictionaryEntry de in _dict)
                        {
                            Debug.Assert((String)de.Key != AllListenersKey, "special key should not appear");
                            size += ((PropertyRecord)de.Value).List.Count;
                        }

                        // create the combined list
                        pcList = new ListenerList <PropertyChangedEventArgs>(size);

                        // fill in the combined list
                        foreach (DictionaryEntry de in _dict)
                        {
                            ListenerList listeners = ((PropertyRecord)de.Value).List;
                            for (int i = 0, n = listeners.Count; i < n; ++i)
                            {
                                pcList.Add(listeners.GetListener(i));
                            }
                        }

                        // save the result for future use (see below)
                        _proposedAllListenersList = pcList;
                    }

                    list = pcList;
                }

                return(list);
            }
Beispiel #36
0
            /// <summary>
            /// If the given list is in use (which means an event is currently
            /// being delivered), replace it with a clone.  The existing
            /// users will finish delivering the event to the original list,
            /// without interference from changes to the new list.
            /// </summary>
            /// <returns>
            /// True if the list was cloned.  Callers will probably want to
            /// insert the new list in their own data structures.
            /// </returns>
            public static bool PrepareForWriting(ref ListenerList list)
            {
                bool inUse = list.BeginUse();
                list.EndUse();

                if (inUse)
                {
                    list = list.Clone();
                }

                return inUse;
            }
Beispiel #37
0
        /// <summary>
        /// Deliver an event to the listeners on the given list
        /// </summary>
        protected void DeliverEventToList(object sender, EventArgs args, ListenerList list) 
        {
            bool foundStaleEntries = false; 
            Type managerType = this.GetType(); 

            // deliver the event 
            for (int k=0, n=list.Count; k<n; ++k)
            {
                IWeakEventListener listener = list[k];
                if (listener != null) 
                {
                    bool handled = listener.ReceiveWeakEvent(managerType, sender, args); 
 
                    // if the event isn't handled, something is seriously wrong.  This
                    // means a listener registered to receive the event, but refused to 
                    // handle it when it was delivered.  Such a listener is coded incorrectly.
                    if (!handled)
                    {
                        Invariant.Assert(handled, 
                                    SR.Get(SRID.ListenerDidNotHandleEvent),
                                    SR.Get(SRID.ListenerDidNotHandleEventDetail, listener.GetType(), managerType)); 
                    } 
                }
                else 
                {
                    foundStaleEntries = true;
                }
            } 

            // if we found stale entries, schedule a cleanup (heuristic b) 
            if (foundStaleEntries) 
            {
                ScheduleCleanup(); 
            }
        }
Beispiel #38
0
            protected void CopyTo(ListenerList newList)
            {
                IWeakEventListener iwel;

                for (int k=0, n=Count; k<n; ++k)
                {
                    Listener listener = GetListener(k);
                    if (listener.Target != null)
                    {
                        if (listener.HasHandler)
                        {
                            Delegate handler = listener.Handler;
                            if (handler != null)
                            {
                                newList.AddHandler(handler);
                            }
                        }
                        else if ((iwel = listener.Target as IWeakEventListener) != null)
                        {
                            newList.Add(iwel);
                        }
                    }
                }
            }
Beispiel #39
0
        // event handler for PropertyChanged event
        private void OnPropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            ListenerList list;
            string       propertyName = args.PropertyName;

            // get the list of listeners
            using (ReadLock)
            {
                // look up the list of listeners
                HybridDictionary dict = (HybridDictionary)this[sender];

                if (dict == null)
                {
                    // this can happen when the last listener stops listening, but the
                    // source raises the event on another thread after the dictionary
                    // has been removed (bug 1235351)
                    list = ListenerList.Empty;
                }
                else if (!String.IsNullOrEmpty(propertyName))
                {
                    // source has changed a particular property.  Notify targets
                    // who are listening either for this property or for all properties.
                    ListenerList <PropertyChangedEventArgs> listeners        = (ListenerList <PropertyChangedEventArgs>)dict[propertyName];
                    ListenerList <PropertyChangedEventArgs> genericListeners = (ListenerList <PropertyChangedEventArgs>)dict[String.Empty];

                    if (genericListeners == null)
                    {
                        if (listeners != null)
                        {
                            list = listeners;           // only specific listeners
                        }
                        else
                        {
                            list = ListenerList.Empty;  // no listeners at all
                        }
                    }
                    else
                    {
                        if (listeners != null)
                        {
                            // there are both specific and generic listeners -
                            // combine the two lists.
                            list = new ListenerList <PropertyChangedEventArgs>(listeners.Count + genericListeners.Count);
                            for (int i = 0, n = listeners.Count; i < n; ++i)
                            {
                                list.Add(listeners.GetListener(i));
                            }
                            for (int i = 0, n = genericListeners.Count; i < n; ++i)
                            {
                                list.Add(genericListeners.GetListener(i));
                            }
                        }
                        else
                        {
                            list = genericListeners;    // only generic listeners
                        }
                    }
                }
                else
                {
                    // source has changed all properties.  Notify all targets.
                    // Use previously calculated combined list, if available.
                    list = (ListenerList)dict[AllListenersKey];

                    if (list == null)
                    {
                        // make one pass to compute the size of the combined list.
                        // This avoids expensive reallocations.
                        int size = 0;
                        foreach (DictionaryEntry de in dict)
                        {
                            Debug.Assert((String)de.Key != AllListenersKey, "special key should not appear");
                            size += ((ListenerList)de.Value).Count;
                        }

                        // create the combined list
                        list = new ListenerList <PropertyChangedEventArgs>(size);

                        // fill in the combined list
                        foreach (DictionaryEntry de in dict)
                        {
                            ListenerList listeners = ((ListenerList)de.Value);
                            for (int i = 0, n = listeners.Count; i < n; ++i)
                            {
                                list.Add(listeners.GetListener(i));
                            }
                        }

                        // save the result for future use (see below)
                        _proposedAllListenersList = list;
                    }
                }

                // mark the list "in use", even outside the read lock,
                // so that any writers will know not to modify it (they'll
                // modify a clone intead).
                list.BeginUse();
            }

            // deliver the event, being sure to undo the effect of BeginUse().
            try
            {
                DeliverEventToList(sender, args, list);
            }
            finally
            {
                list.EndUse();
            }

            // if we calculated an AllListeners list, we should now try to store
            // it in the dictionary so it can be used in the future.  This must be
            // done under a WriteLock - which is why we didn't do it immediately.
            if (_proposedAllListenersList == list)
            {
                using (WriteLock)
                {
                    // test again, in case another thread changed _proposedAllListersList.
                    if (_proposedAllListenersList == list)
                    {
                        HybridDictionary dict = (HybridDictionary)this[sender];
                        if (dict != null)
                        {
                            dict[AllListenersKey] = list;
                        }

                        _proposedAllListenersList = null;
                    }

                    // Another thread could have changed _proposedAllListersList
                    // since we set it (earlier in this method), either
                    // because it calculated a new one while handling a PropertyChanged(""),
                    // or because it added/removed/purged a listener.
                    // In that case, we will simply abandon our proposed list and we'll
                    // have to compute it again the next time.  But that only happens
                    // if there's thread contention.  It's not worth doing something
                    // more complicated just for that case.
                }
            }
        }
Beispiel #40
0
        /// <summary>
        /// Add a listener to the given source for the event. 
        /// </summary>
        protected void ProtectedAddListener(object source, IWeakEventListener listener) 
        { 
            Debug.Assert(listener != null, "Listener cannot be null");
 
            object sourceKey = (source != null) ? source : StaticSource;

            using (Table.WriteLock)
            { 
                ListenerList list = (ListenerList)Table[this, sourceKey];
 
                if (list == null) 
                {
                    // no entry in the table - add a new one 
                    list = new ListenerList();
                    Table[this, sourceKey] = list;

                    // listen for the desired event 
                    StartListening(source);
                } 
 
                // make sure list is ready for writing
                if (ListenerList.PrepareForWriting(ref list)) 
                {
                    Table[this, source] = list;
                }
 
                // add a target to the list of listeners
                list.Add(listener); 
 
                // schedule a cleanup pass (heuristic (b) described above)
                ScheduleCleanup(); 
            }
        }
Beispiel #41
0
 /// <summary>
 /// Prevents a default instance of the <see cref="WeakOddsFormatChangedEventManager"/> class from being created. 
 /// Creates a new instance of WeakOddsFormatChangedEventManager
 /// </summary>
 private WeakOddsFormatChangedEventManager()
 {
     // creates a new list and assign it to listeners
     this.listeners = new ListenerList();
 }
Beispiel #42
0
        /// <summary>
        /// Deliver an event to the listeners on the given list
        /// </summary>
        protected void DeliverEventToList(object sender, EventArgs args, ListenerList list)
        {
            bool foundStaleEntries = list.DeliverEvent(sender, args, this.GetType());

            // if we found stale entries, schedule a cleanup (heuristic b)
            if (foundStaleEntries)
            {
                ScheduleCleanup();
            }
        }
Beispiel #43
0
 /// <summary>
 /// Prevents a default instance of the <see cref="WeakCultureChangedEventManager"/> class from being created.
 /// Creates a new instance of WeakCultureChangedEventManager
 /// </summary>
 private WeakCultureChangedEventManager()
 {
     // creates a new list and assign it to listeners
     listeners = new ListenerList();
 }
        // 
        //  Private Methods
        // 

        // PropertyChanged is a special case - we superimpose per-property granularity
        // on top of this event, by keeping separate lists of listeners for
        // each property. 

        // Add a listener to the named property (empty means "any property") 
        private void PrivateAddListener(INotifyPropertyChanged source, IWeakEventListener listener, string propertyName) 
        {
            Debug.Assert(listener != null && source != null && propertyName != null, 
                "Listener, source, and propertyName of event cannot be null");

            using (WriteLock)
            { 
                HybridDictionary dict = (HybridDictionary)this[source];
 
                if (dict == null) 
                {
                    // no entry in the hashtable - add a new one 
                    dict = new HybridDictionary(true /* case insensitive */);

                    this[source] = dict;
 
                    // listen for the desired events
                    StartListening(source); 
                } 

                ListenerList list = (ListenerList)dict[propertyName]; 

                if (list == null)
                {
                    // no entry in the dictionary - add a new one 
                    list = new ListenerList();
 
                    dict[propertyName] = list; 
                }
 
                // make sure list is ready for writing
                if (ListenerList.PrepareForWriting(ref list))
                {
                    dict[propertyName] = list; 
                }
 
                // add a listener to the list 
                list.Add(listener);
                dict.Remove(AllListenersKey);   // invalidate list of all listeners 
                _proposedAllListenersList = null;

                // schedule a cleanup pass
                ScheduleCleanup(); 
            }
        } 
        // event handler for PropertyChanged event
        private void OnPropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            ListenerList list;
            string propertyName = args.PropertyName;

            // get the list of listeners
            using (ReadLock)
            {
                // look up the list of listeners
                HybridDictionary dict = (HybridDictionary)this[sender];

                if (dict == null)
                {
                    // this can happen when the last listener stops listening, but the
                    // source raises the event on another thread after the dictionary
                    // has been removed (bug 1235351)
                    list = ListenerList.Empty;
                }
                else if (!String.IsNullOrEmpty(propertyName))
                {
                    // source has changed a particular property.  Notify targets
                    // who are listening either for this property or for all properties.
                    ListenerList<PropertyChangedEventArgs> listeners = (ListenerList<PropertyChangedEventArgs>)dict[propertyName];
                    ListenerList<PropertyChangedEventArgs> genericListeners = (ListenerList<PropertyChangedEventArgs>)dict[String.Empty];

                    if (genericListeners == null)
                    {
                        if (listeners != null)
                        {
                            list = listeners;           // only specific listeners
                        }
                        else
                        {
                            list = ListenerList.Empty;  // no listeners at all
                        }
                    }
                    else
                    {
                        if (listeners != null)
                        {
                            // there are both specific and generic listeners -
                            // combine the two lists.
                            list = new ListenerList<PropertyChangedEventArgs>(listeners.Count + genericListeners.Count);
                            for (int i=0, n=listeners.Count; i<n; ++i)
                                list.Add(listeners.GetListener(i));
                            for (int i=0, n=genericListeners.Count; i<n; ++i)
                                list.Add(genericListeners.GetListener(i));
                        }
                        else
                        {
                            list = genericListeners;    // only generic listeners
                        }
                    }
                }
                else
                {
                    // source has changed all properties.  Notify all targets.
                    // Use previously calculated combined list, if available.
                    list = (ListenerList)dict[AllListenersKey];

                    if (list == null)
                    {
                        // make one pass to compute the size of the combined list.
                        // This avoids expensive reallocations.
                        int size = 0;
                        foreach (DictionaryEntry de in dict)
                        {
                            Debug.Assert((String)de.Key != AllListenersKey, "special key should not appear");
                            size += ((ListenerList)de.Value).Count;
                        }

                        // create the combined list
                        list = new ListenerList<PropertyChangedEventArgs>(size);

                        // fill in the combined list
                        foreach (DictionaryEntry de in dict)
                        {
                            ListenerList listeners = ((ListenerList)de.Value);
                            for (int i=0, n=listeners.Count;  i<n;  ++i)
                            {
                                list.Add(listeners.GetListener(i));
                            }
                        }

                        // save the result for future use (see below)
                        _proposedAllListenersList = list;
                    }
                }

                // mark the list "in use", even outside the read lock,
                // so that any writers will know not to modify it (they'll
                // modify a clone intead).
                list.BeginUse();
            }

            // deliver the event, being sure to undo the effect of BeginUse().
            try
            {
                DeliverEventToList(sender, args, list);
            }
            finally
            {
                list.EndUse();
            }

            // if we calculated an AllListeners list, we should now try to store
            // it in the dictionary so it can be used in the future.  This must be
            // done under a WriteLock - which is why we didn't do it immediately.
            if (_proposedAllListenersList == list)
            {
                using (WriteLock)
                {
                    // test again, in case another thread changed _proposedAllListersList.
                    if (_proposedAllListenersList == list)
                    {
                        HybridDictionary dict = (HybridDictionary)this[sender];
                        if (dict != null)
                        {
                            dict[AllListenersKey] = list;
                        }

                        _proposedAllListenersList = null;
                    }

                    // Another thread could have changed _proposedAllListersList
                    // since we set it (earlier in this method), either
                    // because it calculated a new one while handling a PropertyChanged(""),
                    // or because it added/removed/purged a listener.
                    // In that case, we will simply abandon our proposed list and we'll
                    // have to compute it again the next time.  But that only happens
                    // if there's thread contention.  It's not worth doing something
                    // more complicated just for that case.
                }
            }
        }
Beispiel #46
0
        public void Run(string[] args)
        {
            if (args.Length == 0)
            {
                Help();
                return;
            }

            var e = args.GetEnumerator();

            while (e.MoveNext())
            {
                var a = ((string)e.Current).ToLowerInvariant();
                if (a == "-help" || a == "-h" || a == "-?")
                {
                    Help();
                    return;
                }
                else if (a == "-output" || a == "-out")
                {
                    if (e.MoveNext())
                    {
                        ViewFactory.Builder.SetPath((string)e.Current);
                        View = ViewFactory.CreateView();
                    }
                    else
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                }
                else if (a == "-target")
                {
                    if (e.MoveNext())
                    {
                        target = new ConnectionTarget();
                        if (!target.Parse((string)e.Current))
                        {
                            throw new Exception(BAD_TARGET);
                        }
                    }
                    else
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                }
                else if (a == "-address" || a == "-addr")
                {
                    if (e.MoveNext())
                    {
                        if (target == null)
                        {
                            throw new Exception(NO_TARGET);
                        }
                        target.Address = (string)e.Current;
                    }
                    else
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                }
                else if (a == "-port")
                {
                    if (e.MoveNext())
                    {
                        nonSecurePort = int.Parse((string)e.Current);
                    }
                    else
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                    if (nonSecurePort <= 0 || 65536 <= nonSecurePort)
                    {
                        throw new Exception(BAD_NPORT);
                    }
                }
                else if (a == "-secureport" || a == "-secport")
                {
                    if (e.MoveNext())
                    {
                        securePort = int.Parse((string)e.Current);
                    }
                    else
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                    if (securePort <= 0 || 65536 <= securePort)
                    {
                        throw new Exception(BAD_SPORT);
                    }
                }
                else if (a == "-certpath")
                {
                    if (e.MoveNext())
                    {
                        certificatePath = (string)e.Current;
                    }
                    else
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                }
                else if (a == "-certpassword" || a == "-certpasswd" || a == "-certpass")
                {
                    if (e.MoveNext())
                    {
                        certificatePassword = (string)e.Current;
                    }
                    else
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                }
                else if (a == "-shutdown")
                {
                    commandRequest = "shutdown";
                }
                else if (a == "-commandtarget" || a == "-cmdtarget")
                {
                    if (e.MoveNext())
                    {
                        commandTarget = (string)e.Current;
                    }
                    else
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                    var ss = commandTarget.Split(new char[] { ':' });
                    if (ss.Length == 2)
                    {
                        commandTarget = ss[0];
                        commandPort   = int.Parse(ss[1]);
                    }
                    else if (ss.Length != 1)
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                }
                else if (a == "-commandport" || a == "-cmdport")
                {
                    if (e.MoveNext())
                    {
                        commandPort = int.Parse((string)e.Current);
                    }
                    else
                    {
                        throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                    }
                }
#if DEBUG
                else if (a == "-debug")
                {
                    System.Diagnostics.Debugger.Launch();
                }
#endif
                else
                {
                    throw new Exception(BAD_COMMAND_LINE_SYNTAX);
                }
            }

            if (target != null)
            {
                if (nonSecurePort == 0 && target.Type == ConnectionType.Raw)
                {
                    nonSecurePort = HttpConstants.HTTP_PORT;
                }
                if (nonSecurePort > 0)
                {
                    var nonSecureListener = new NonSecureListener()
                    {
                        Destination = target,
                        Port        = nonSecurePort
                    };
                    ListenerList.Add(nonSecureListener);
                }

                if ((certificatePath != null && certificatePassword == null) || (certificatePath == null && certificatePassword != null))
                {
                    throw new Exception(CERTIFICATE_PATH_AND_PASSWORD);
                }
                if (securePort == 0 && (target.Type == ConnectionType.Encrypted || certificatePath != null))
                {
                    securePort = HttpConstants.HTTPS_PORT;
                }
                if (securePort > 0)
                {
                    if (certificatePath == null || certificatePassword == null)
                    {
                        throw new Exception(CERTIFICATE_PATH_AND_PASSWORD);
                    }
                    var secureListener = new SecureListener()
                    {
                        Destination               = target,
                        Port                      = securePort,
                        ServerCertificatePath     = certificatePath,
                        ServerCertificatePassword = certificatePassword
                    };
                    ListenerList.Add(secureListener);
                }
            }

            if (ListenerList.Count > 0)
            {
                if (commandRequest != null)
                {
                    throw new Exception(EXCLUSIVE_REQUESTS);
                }

                var commandListener = new CommandListener()
                {
                    Port       = commandPort,
                    OnShutdown = ShutDown
                };
                ListenerList.Add(commandListener);

                foreach (var listener in ListenerList)
                {
                    listener.Start();
                }

                TerminateEvent.WaitOne();

                foreach (var listener in ListenerList)
                {
                    listener.Stop();
                }

                foreach (var listener in ListenerList)
                {
                    listener.Wait();
                }
            }
            else if (commandRequest != null)
            {
                var commandClient = new CommandClient()
                {
                    Hostname = commandTarget,
                    Port     = commandPort
                };
                commandClient.Send(commandRequest);
            }
            else
            {
                throw new Exception(BAD_COMMAND_LINE_SYNTAX);
            }
        }
 /// <summary>
 /// Prevents a default instance of the <see cref="WeakOddsFormatChangedEventManager"/> class from being created.
 /// Creates a new instance of WeakOddsFormatChangedEventManager
 /// </summary>
 private WeakOddsFormatChangedEventManager()
 {
     // creates a new list and assign it to listeners
     this.listeners = new ListenerList();
 }
Beispiel #48
0
 /// <summary>
 /// Purge dead entries.</summary>
 /// <returns>True if any entries were purged, otherwise false</returns>
 public bool Purge()
 {
     ListenerList.PrepareForWriting(ref m_listeners);
     return(m_listeners.Purge());
 }