xpcom/ds/nsObserverList.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsObserverList.h"
     8 #include "nsAutoPtr.h"
     9 #include "nsCOMArray.h"
    10 #include "nsISimpleEnumerator.h"
    11 #include "xpcpublic.h"
    13 nsresult
    14 nsObserverList::AddObserver(nsIObserver* anObserver, bool ownsWeak)
    15 {
    16     NS_ASSERTION(anObserver, "Null input");
    18     if (!ownsWeak) {
    19         ObserverRef* o = mObservers.AppendElement(anObserver);
    20         if (!o)
    21             return NS_ERROR_OUT_OF_MEMORY;
    23         return NS_OK;
    24     }
    26     nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(anObserver);
    27     if (!weak)
    28         return NS_NOINTERFACE;
    30     ObserverRef *o = mObservers.AppendElement(weak);
    31     if (!o)
    32         return NS_ERROR_OUT_OF_MEMORY;
    34     return NS_OK;
    35 }
    37 nsresult
    38 nsObserverList::RemoveObserver(nsIObserver* anObserver)
    39 {
    40     NS_ASSERTION(anObserver, "Null input");
    42     if (mObservers.RemoveElement(static_cast<nsISupports*>(anObserver)))
    43         return NS_OK;
    45     nsCOMPtr<nsIWeakReference> observerRef = do_GetWeakReference(anObserver);
    46     if (!observerRef)
    47         return NS_ERROR_FAILURE;
    49     if (!mObservers.RemoveElement(observerRef))
    50         return NS_ERROR_FAILURE;
    52     return NS_OK;
    53 }
    55 nsresult
    56 nsObserverList::GetObserverList(nsISimpleEnumerator** anEnumerator)
    57 {
    58     nsRefPtr<nsObserverEnumerator> e(new nsObserverEnumerator(this));
    59     e.forget(anEnumerator);
    60     return NS_OK;
    61 }
    63 void
    64 nsObserverList::FillObserverArray(nsCOMArray<nsIObserver> &aArray)
    65 {
    66     aArray.SetCapacity(mObservers.Length());
    68     nsTArray<ObserverRef> observers(mObservers);
    70     for (int32_t i = observers.Length() - 1; i >= 0; --i) {
    71         if (observers[i].isWeakRef) {
    72             nsCOMPtr<nsIObserver> o(do_QueryReferent(observers[i].asWeak()));
    73             if (o) {
    74                 aArray.AppendObject(o);
    75             }
    76             else {
    77                 // the object has gone away, remove the weakref
    78                 mObservers.RemoveElement(observers[i].asWeak());
    79             }
    80         }
    81         else {
    82             aArray.AppendObject(observers[i].asObserver());
    83         }
    84     }
    85 }
    87 void
    88 nsObserverList::NotifyObservers(nsISupports *aSubject,
    89                                 const char *aTopic,
    90                                 const char16_t *someData)
    91 {
    92     nsCOMArray<nsIObserver> observers;
    93     FillObserverArray(observers);
    95     for (int32_t i = 0; i < observers.Count(); ++i) {
    96         observers[i]->Observe(aSubject, aTopic, someData);
    97     }
    98 }
   100 void
   101 nsObserverList::UnmarkGrayStrongObservers()
   102 {
   103     for (uint32_t i = 0; i < mObservers.Length(); ++i) {
   104         if (!mObservers[i].isWeakRef) {
   105             xpc_TryUnmarkWrappedGrayObject(mObservers[i].asObserver());
   106         }
   107     }
   108 }
   110 NS_IMPL_ISUPPORTS(nsObserverEnumerator, nsISimpleEnumerator)
   112 nsObserverEnumerator::nsObserverEnumerator(nsObserverList* aObserverList)
   113     : mIndex(0)
   114 {
   115     aObserverList->FillObserverArray(mObservers);
   116 }
   118 NS_IMETHODIMP
   119 nsObserverEnumerator::HasMoreElements(bool *aResult)
   120 {
   121     *aResult = (mIndex < mObservers.Count());
   122     return NS_OK;
   123 }
   125 NS_IMETHODIMP
   126 nsObserverEnumerator::GetNext(nsISupports* *aResult)
   127 {
   128     if (mIndex == mObservers.Count()) {
   129         NS_ERROR("Enumerating after HasMoreElements returned false.");
   130         return NS_ERROR_UNEXPECTED;
   131     }
   133     NS_ADDREF(*aResult = mObservers[mIndex]);
   134     ++mIndex;
   135     return NS_OK;
   136 }

mercurial