Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "StorageNotifierService.h"
8 : #include "mozilla/ClearOnShutdown.h"
9 : #include "mozilla/StaticPtr.h"
10 :
11 : namespace mozilla {
12 : namespace dom {
13 :
14 : namespace {
15 :
16 : // This boolean is used to avoid the creation of the service after been
17 : // distroyed on shutdown.
18 : bool gStorageShuttingDown = false;
19 :
20 3 : StaticRefPtr<StorageNotifierService> gStorageNotifierService;
21 :
22 : } // anonymous
23 :
24 : /* static */ StorageNotifierService*
25 8 : StorageNotifierService::GetOrCreate()
26 : {
27 8 : MOZ_ASSERT(NS_IsMainThread());
28 8 : if (!gStorageNotifierService && !gStorageShuttingDown) {
29 2 : gStorageNotifierService = new StorageNotifierService();
30 2 : ClearOnShutdown(&gStorageNotifierService);
31 : }
32 :
33 8 : return gStorageNotifierService;
34 : }
35 :
36 2 : StorageNotifierService::StorageNotifierService()
37 : {
38 2 : MOZ_ASSERT(NS_IsMainThread());
39 2 : MOZ_ASSERT(!gStorageNotifierService);
40 2 : }
41 :
42 0 : StorageNotifierService::~StorageNotifierService()
43 : {
44 0 : MOZ_ASSERT(NS_IsMainThread());
45 0 : MOZ_ASSERT(!gStorageNotifierService);
46 0 : gStorageShuttingDown = true;
47 0 : }
48 :
49 : /* static */ void
50 0 : StorageNotifierService::Broadcast(StorageEvent* aEvent,
51 : const char16_t* aStorageType,
52 : bool aPrivateBrowsing,
53 : bool aImmediateDispatch)
54 : {
55 0 : MOZ_ASSERT(NS_IsMainThread());
56 :
57 0 : RefPtr<StorageNotifierService> service = gStorageNotifierService;
58 0 : if (!service) {
59 0 : return;
60 : }
61 :
62 0 : RefPtr<StorageEvent> event = aEvent;
63 :
64 : nsTObserverArray<RefPtr<StorageNotificationObserver>>::ForwardIterator
65 0 : iter(service->mObservers);
66 :
67 0 : while (iter.HasMore()) {
68 0 : RefPtr<StorageNotificationObserver> observer = iter.GetNext();
69 :
70 0 : RefPtr<Runnable> r = NS_NewRunnableFunction(
71 : "StorageNotifierService::Broadcast",
72 0 : [observer, event, aStorageType, aPrivateBrowsing] () {
73 0 : observer->ObserveStorageNotification(event, aStorageType, aPrivateBrowsing);
74 0 : });
75 :
76 0 : if (aImmediateDispatch) {
77 0 : r->Run();
78 : } else {
79 0 : nsCOMPtr<nsIEventTarget> et = observer->GetEventTarget();
80 0 : if (et) {
81 0 : et->Dispatch(r.forget());
82 : }
83 : }
84 : }
85 : }
86 :
87 : void
88 7 : StorageNotifierService::Register(StorageNotificationObserver* aObserver)
89 : {
90 7 : MOZ_ASSERT(NS_IsMainThread());
91 7 : MOZ_ASSERT(aObserver);
92 7 : MOZ_ASSERT(!mObservers.Contains(aObserver));
93 :
94 7 : mObservers.AppendElement(aObserver);
95 7 : }
96 :
97 : void
98 1 : StorageNotifierService::Unregister(StorageNotificationObserver* aObserver)
99 : {
100 1 : MOZ_ASSERT(NS_IsMainThread());
101 1 : MOZ_ASSERT(aObserver);
102 :
103 : // No assertion about mObservers containing aObserver because window calls
104 : // this method multiple times.
105 :
106 1 : mObservers.RemoveElement(aObserver);
107 1 : }
108 :
109 : } // namespace dom
110 : } // namespace mozilla
|