Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1031)

Side by Side Diff: Source/core/page/NetworkStateNotifier.cpp

Issue 289333003: Adds type information to the NetworkStateNotifier. Also allows for registration of observers. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Thread safe observer list Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "config.h" 26 #include "config.h"
27 #include "core/page/NetworkStateNotifier.h" 27 #include "core/page/NetworkStateNotifier.h"
28 28
29 #include "core/dom/ExecutionContext.h"
29 #include "core/page/Page.h" 30 #include "core/page/Page.h"
30 #include "wtf/Assertions.h" 31 #include "wtf/Assertions.h"
32 #include "wtf/Functional.h"
31 #include "wtf/MainThread.h" 33 #include "wtf/MainThread.h"
32 #include "wtf/StdLibExtras.h" 34 #include "wtf/StdLibExtras.h"
33 #include "wtf/Threading.h" 35 #include "wtf/Threading.h"
34 36
35 namespace WebCore { 37 namespace WebCore {
36 38
37 NetworkStateNotifier& networkStateNotifier() 39 NetworkStateNotifier& networkStateNotifier()
38 { 40 {
39 AtomicallyInitializedStatic(NetworkStateNotifier*, networkStateNotifier = ne w NetworkStateNotifier); 41 AtomicallyInitializedStatic(NetworkStateNotifier*, networkStateNotifier = ne w NetworkStateNotifier);
40 return *networkStateNotifier; 42 return *networkStateNotifier;
41 } 43 }
42 44
43 void NetworkStateNotifier::setOnLine(bool onLine) 45 void NetworkStateNotifier::setOnLine(bool onLine)
44 { 46 {
45 ASSERT(isMainThread()); 47 ASSERT(isMainThread());
46 48
47 { 49 {
48 MutexLocker locker(m_mutex); 50 MutexLocker locker(m_mutex);
49 if (m_isOnLine == onLine) 51 if (m_isOnLine == onLine)
50 return; 52 return;
51 53
52 m_isOnLine = onLine; 54 m_isOnLine = onLine;
53 } 55 }
54 56
55 Page::networkStateChanged(onLine); 57 Page::networkStateChanged(onLine);
56 } 58 }
57 59
60 void NetworkStateNotifier::setWebConnectionType(blink::WebNetworkConnection::Con nectionType type)
61 {
62 ASSERT(isMainThread());
63
64 MutexLocker locker(m_mutex);
65 if (m_type == type)
66 return;
67 m_type = type;
68
69 for (ObserverListMap::iterator it = m_observers.begin(); it != m_observers.e nd(); ++it) {
adamk 2014/05/20 15:00:36 What guarantees that the ExecutionContexts in this
jkarlin 2014/05/20 16:20:23 The observer must call removeObserver before the E
70 ExecutionContext* context = it->key;
71 context->postTask(bind(&NetworkStateNotifier::notifyObserversOnContext, this, context, type));
72 }
58 } 73 }
74
75 void NetworkStateNotifier::notifyObserversOnContext(ExecutionContext* context, b link::WebNetworkConnection::ConnectionType type)
76 {
77 ASSERT(context->isContextThread());
78
79 ObserverList* observerList = 0;
80
81 {
82 // The context could have been removed before we got here
83 MutexLocker locker(m_mutex);
adamk 2014/05/20 15:12:50 I think you need to lock for this entire method, e
jkarlin 2014/05/20 16:20:23 Nice catch, thanks. Made an alternate fix where th
84 ObserverListMap::iterator it = m_observers.find(context);
85 if (it == m_observers.end())
86 return;
87 observerList = &(it->value);
88 }
89
90 observerList->iterating = true;
91
92 for (Vector<ObserverType>::iterator it = observerList->observers.begin(); it != observerList->observers.end(); ++it)
93 (*it)->connectionTypeChange(type);
94
95 observerList->iterating = false;
96 }
97
98 void NetworkStateNotifier::addObserver(ObserverType observer, ExecutionContext* context)
99 {
100 ASSERT(context->isContextThread());
101 ASSERT(observer);
102
103 MutexLocker locker(m_mutex);
104 ObserverListMap::iterator it = m_observers.find(context);
105 if (it == m_observers.end()) {
106 m_observers.set(context, ObserverList());
107 it = m_observers.find(context);
108 }
109 ASSERT(!it->value.iterating); // Don't mutate observer list while notifying.
110 it->value.observers.append(observer);
111 }
112
113 void NetworkStateNotifier::removeObserver(ObserverType observer, ExecutionContex t* context)
114 {
115 ASSERT(context->isContextThread());
116 ASSERT(observer);
117
118 MutexLocker locker(m_mutex);
119 ObserverListMap::iterator it = m_observers.find(context);
120 if (it == m_observers.end())
121 return;
122
123 ASSERT(!it->value.iterating); // Don't mutate observer list while notifying.
124
125 Vector<ObserverType>* observers = &it->value.observers;
126
127 for (size_t i = 0; i < observers->size(); ++i) {
adamk 2014/05/20 15:00:36 Vector has a find() method (returning kNotFound if
jkarlin 2014/05/20 16:20:23 Done.
128 if (observers->at(i) == observer) {
129 observers->remove(i);
130 break;
131 }
132 }
133
134 if (observers->isEmpty())
135 m_observers.remove(it);
136 }
137
138 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698