OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2013 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 * | 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 |
(...skipping 25 matching lines...) Loading... | |
36 #include "platform/Logging.h" | 36 #include "platform/Logging.h" |
37 #include "platform/heap/glue/MessageLoopInterruptor.h" | 37 #include "platform/heap/glue/MessageLoopInterruptor.h" |
38 #include "platform/heap/glue/PendingGCRunner.h" | 38 #include "platform/heap/glue/PendingGCRunner.h" |
39 #include "public/platform/Platform.h" | 39 #include "public/platform/Platform.h" |
40 | 40 |
41 namespace blink { | 41 namespace blink { |
42 | 42 |
43 DatabaseThread::DatabaseThread() | 43 DatabaseThread::DatabaseThread() |
44 : m_transactionClient(adoptPtr(new SQLTransactionClient())) | 44 : m_transactionClient(adoptPtr(new SQLTransactionClient())) |
45 , m_transactionCoordinator(adoptPtrWillBeNoop(new SQLTransactionCoordinator( ))) | 45 , m_transactionCoordinator(adoptPtrWillBeNoop(new SQLTransactionCoordinator( ))) |
46 , m_cleanupSync(0) | |
47 , m_terminationRequested(false) | 46 , m_terminationRequested(false) |
48 { | 47 { |
49 } | 48 } |
50 | 49 |
51 DatabaseThread::~DatabaseThread() | 50 DatabaseThread::~DatabaseThread() |
52 { | 51 { |
53 ASSERT(m_openDatabaseSet.isEmpty()); | 52 ASSERT(m_openDatabaseSet.isEmpty()); |
54 // Oilpan: The database thread must have finished its cleanup tasks before | 53 ASSERT(!m_thread); |
55 // the following clear(). Otherwise, WebThread destructor blocks the caller | |
56 // thread, and causes a deadlock with ThreadState cleanup. | |
57 // DatabaseContext::stop() asks the database thread to close all of | |
58 // databases, and wait until GC heap cleanup of the database thread. So we | |
59 // can safely destruct WebThread here. | |
60 m_thread.clear(); | |
61 } | 54 } |
62 | 55 |
63 void DatabaseThread::trace(Visitor* visitor) | 56 void DatabaseThread::trace(Visitor* visitor) |
64 { | 57 { |
65 #if ENABLE(OILPAN) | 58 #if ENABLE(OILPAN) |
66 visitor->trace(m_openDatabaseSet); | 59 visitor->trace(m_openDatabaseSet); |
67 visitor->trace(m_transactionCoordinator); | 60 visitor->trace(m_transactionCoordinator); |
68 #endif | 61 #endif |
69 } | 62 } |
70 | 63 |
71 void DatabaseThread::start() | 64 void DatabaseThread::start() |
72 { | 65 { |
73 if (m_thread) | 66 if (m_thread) |
74 return; | 67 return; |
75 m_thread = WebThreadSupportingGC::create("WebCore: Database"); | 68 m_thread = WebThreadSupportingGC::create("WebCore: Database"); |
76 m_thread->postTask(new Task(WTF::bind(&DatabaseThread::setupDatabaseThread, this))); | 69 m_thread->postTask(new Task(WTF::bind(&DatabaseThread::setupDatabaseThread, this))); |
77 } | 70 } |
78 | 71 |
79 void DatabaseThread::setupDatabaseThread() | 72 void DatabaseThread::setupDatabaseThread() |
80 { | 73 { |
81 m_thread->attachGC(); | 74 m_thread->attachGC(); |
82 } | 75 } |
83 | 76 |
84 void DatabaseThread::requestTermination(TaskSynchronizer *cleanupSync) | 77 void DatabaseThread::terminate() |
85 { | 78 { |
86 MutexLocker lock(m_terminationRequestedMutex); | 79 MutexLocker lock(m_terminationRequestedMutex); |
Mads Ager (chromium)
2014/09/23 13:44:37
I think we should limit the scope of this lock so
| |
87 ASSERT(!m_terminationRequested); | 80 ASSERT(!m_terminationRequested); |
88 m_terminationRequested = true; | 81 m_terminationRequested = true; |
89 m_cleanupSync = cleanupSync; | |
90 WTF_LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this); | 82 WTF_LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this); |
91 m_thread->postTask(new Task(WTF::bind(&DatabaseThread::cleanupDatabaseThread , this))); | 83 m_thread->postTask(new Task(WTF::bind(&DatabaseThread::cleanupDatabaseThread , this))); |
84 // The WebThread destructor blocks until the database thread processes the c leanup task. | |
85 m_thread.clear(); | |
92 } | 86 } |
93 | 87 |
94 bool DatabaseThread::terminationRequested(TaskSynchronizer* taskSynchronizer) co nst | 88 bool DatabaseThread::terminationRequested(TaskSynchronizer* taskSynchronizer) co nst |
95 { | 89 { |
96 #if ENABLE(ASSERT) | 90 #if ENABLE(ASSERT) |
97 if (taskSynchronizer) | 91 if (taskSynchronizer) |
98 taskSynchronizer->setHasCheckedForTermination(); | 92 taskSynchronizer->setHasCheckedForTermination(); |
99 #endif | 93 #endif |
100 | 94 |
101 MutexLocker lock(m_terminationRequestedMutex); | 95 MutexLocker lock(m_terminationRequestedMutex); |
(...skipping 17 matching lines...) Loading... | |
119 for (WillBeHeapHashSet<RefPtrWillBeMember<DatabaseBackend> >::iterator i t = openSetCopy.begin(); it != end; ++it) | 113 for (WillBeHeapHashSet<RefPtrWillBeMember<DatabaseBackend> >::iterator i t = openSetCopy.begin(); it != end; ++it) |
120 (*it)->close(); | 114 (*it)->close(); |
121 } | 115 } |
122 | 116 |
123 m_thread->postTask(new Task(WTF::bind(&DatabaseThread::cleanupDatabaseThread Completed, this))); | 117 m_thread->postTask(new Task(WTF::bind(&DatabaseThread::cleanupDatabaseThread Completed, this))); |
124 } | 118 } |
125 | 119 |
126 void DatabaseThread::cleanupDatabaseThreadCompleted() | 120 void DatabaseThread::cleanupDatabaseThreadCompleted() |
127 { | 121 { |
128 m_thread->detachGC(); | 122 m_thread->detachGC(); |
129 if (m_cleanupSync) // Someone wanted to know when we were done cleaning up. | |
130 m_cleanupSync->taskCompleted(); | |
131 } | 123 } |
132 | 124 |
133 void DatabaseThread::recordDatabaseOpen(DatabaseBackend* database) | 125 void DatabaseThread::recordDatabaseOpen(DatabaseBackend* database) |
134 { | 126 { |
135 ASSERT(isDatabaseThread()); | 127 ASSERT(isDatabaseThread()); |
136 ASSERT(database); | 128 ASSERT(database); |
137 ASSERT(!m_openDatabaseSet.contains(database)); | 129 ASSERT(!m_openDatabaseSet.contains(database)); |
138 m_openDatabaseSet.add(database); | 130 m_openDatabaseSet.add(database); |
139 } | 131 } |
140 | 132 |
(...skipping 15 matching lines...) Loading... | |
156 | 148 |
157 void DatabaseThread::scheduleTask(PassOwnPtr<DatabaseTask> task) | 149 void DatabaseThread::scheduleTask(PassOwnPtr<DatabaseTask> task) |
158 { | 150 { |
159 ASSERT(m_thread); | 151 ASSERT(m_thread); |
160 ASSERT(!task->hasSynchronizer() || task->hasCheckedForTermination()); | 152 ASSERT(!task->hasSynchronizer() || task->hasCheckedForTermination()); |
161 // WebThread takes ownership of the task. | 153 // WebThread takes ownership of the task. |
162 m_thread->postTask(task.leakPtr()); | 154 m_thread->postTask(task.leakPtr()); |
163 } | 155 } |
164 | 156 |
165 } // namespace blink | 157 } // namespace blink |
OLD | NEW |