OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google 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 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
13 * | 13 * |
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * 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 "modules/indexeddb/IDBPendingTransactionMonitor.h" | 27 #include "modules/indexeddb/IDBPendingTransactionMonitor.h" |
28 | 28 |
29 #include "modules/indexeddb/IDBCursor.h" | |
30 #include "modules/indexeddb/IDBRequest.h" | |
31 #include "modules/indexeddb/IDBTransaction.h" | 29 #include "modules/indexeddb/IDBTransaction.h" |
32 | 30 |
33 namespace blink { | 31 namespace blink { |
34 | 32 |
35 IDBPendingTransactionMonitor::IDBPendingTransactionMonitor() | 33 IDBPendingTransactionMonitor::IDBPendingTransactionMonitor() |
36 { | 34 { |
37 } | 35 } |
38 | 36 |
39 IDBPendingTransactionMonitor::~IDBPendingTransactionMonitor() | |
40 { | |
41 } | |
42 | |
43 void IDBPendingTransactionMonitor::addNewTransaction(IDBTransaction& transaction
) | 37 void IDBPendingTransactionMonitor::addNewTransaction(IDBTransaction& transaction
) |
44 { | 38 { |
45 m_transactions.append(&transaction); | 39 m_transactions.append(&transaction); |
46 } | 40 } |
47 | 41 |
48 void IDBPendingTransactionMonitor::deactivateNewTransactions() | 42 void IDBPendingTransactionMonitor::deactivateNewTransactions() |
49 { | 43 { |
50 for (size_t i = 0; i < m_transactions.size(); ++i) | 44 for (size_t i = 0; i < m_transactions.size(); ++i) |
51 m_transactions[i]->setActive(false); | 45 m_transactions[i]->setActive(false); |
52 // FIXME: Exercise this call to clear() in a layout test. | 46 // FIXME: Exercise this call to clear() in a layout test. |
53 m_transactions.clear(); | 47 m_transactions.clear(); |
54 } | 48 } |
55 | 49 |
56 // IDBDisposerDispatcher should be RefCounted because it should outlive all of | |
57 // target objects. | |
58 class IDBDisposerDispatcher: public RefCounted<IDBDisposerDispatcher> { | |
59 public: | |
60 static PassRefPtr<IDBDisposerDispatcher> create() { return adoptRef(new IDBD
isposerDispatcher()); } | |
61 | |
62 private: | |
63 IDBDisposerDispatcher() { } | |
64 | |
65 template<typename Owner, typename Target> | |
66 class Disposer { | |
67 public: | |
68 static PassOwnPtr<Disposer> create(Owner& owner, Target& target) { retur
n adoptPtr(new Disposer(owner, target)); } | |
69 ~Disposer() | |
70 { | |
71 if (!m_isDisabled) | |
72 m_target.dispose(); | |
73 } | |
74 void setDisabled() { m_isDisabled = true; } | |
75 | |
76 private: | |
77 Disposer(Owner& owner, Target& target) | |
78 : m_owner(owner) | |
79 , m_target(target) | |
80 , m_isDisabled(false) | |
81 { | |
82 } | |
83 | |
84 RefPtr<Owner> m_owner; | |
85 Target& m_target; | |
86 bool m_isDisabled; | |
87 }; | |
88 | |
89 template<typename Target> | |
90 class DisposerMap { | |
91 DISALLOW_ALLOCATION(); | |
92 public: | |
93 void registerTarget(IDBDisposerDispatcher& dispatcher, Target& target) | |
94 { | |
95 ASSERT(!m_disposerMap.contains(&target)); | |
96 m_disposerMap.add(&target, Disposer<IDBDisposerDispatcher, Target>::
create(dispatcher, target)); | |
97 } | |
98 | |
99 void unregisterTarget(IDBDisposerDispatcher& dispatcher, Target& target) | |
100 { | |
101 // Skip this function if this is called in Target::dispose(). | |
102 if (ThreadState::current()->isSweepInProgress()) | |
103 return; | |
104 auto it = m_disposerMap.find(&target); | |
105 ASSERT(it != m_disposerMap.end()); | |
106 if (it == m_disposerMap.end()) | |
107 return; | |
108 // m_disposerMap.remove() will trigger ~Disposer. We should not call | |
109 // Target::dispose() in ~Disposer in this case. | |
110 it->value->setDisabled(); | |
111 m_disposerMap.remove(it); | |
112 } | |
113 | |
114 private: | |
115 PersistentHeapHashMap<WeakMember<Target>, OwnPtr<Disposer<IDBDisposerDis
patcher, Target>>> m_disposerMap; | |
116 }; | |
117 | |
118 DisposerMap<IDBRequest> m_requests; | |
119 DisposerMap<IDBCursor> m_cursors; | |
120 friend class IDBPendingTransactionMonitor; | |
121 }; | |
122 | |
123 void IDBPendingTransactionMonitor::registerRequest(IDBRequest& request) | |
124 { | |
125 if (!m_dispatcher) | |
126 m_dispatcher = IDBDisposerDispatcher::create(); | |
127 m_dispatcher->m_requests.registerTarget(*m_dispatcher, request); | |
128 } | |
129 | |
130 void IDBPendingTransactionMonitor::unregisterRequest(IDBRequest& request) | |
131 { | |
132 // We should not unregister without registeration. | |
133 ASSERT(m_dispatcher); | |
134 m_dispatcher->m_requests.unregisterTarget(*m_dispatcher, request); | |
135 } | |
136 | |
137 void IDBPendingTransactionMonitor::registerCursor(IDBCursor& cursor) | |
138 { | |
139 if (!m_dispatcher) | |
140 m_dispatcher = IDBDisposerDispatcher::create(); | |
141 m_dispatcher->m_cursors.registerTarget(*m_dispatcher, cursor); | |
142 } | |
143 | |
144 void IDBPendingTransactionMonitor::unregisterCursor(IDBCursor& cursor) | |
145 { | |
146 // We should not unregister without registeration. | |
147 ASSERT(m_dispatcher); | |
148 m_dispatcher->m_cursors.unregisterTarget(*m_dispatcher, cursor); | |
149 } | |
150 | |
151 } // namespace blink | 50 } // namespace blink |
OLD | NEW |