• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
24  */
25 
26 #include "config.h"
27 #include "LocalStorageThread.h"
28 
29 #if ENABLE(DOM_STORAGE)
30 
31 #include "LocalStorageTask.h"
32 #include "StorageAreaSync.h"
33 
34 namespace WebCore {
35 
create()36 PassRefPtr<LocalStorageThread> LocalStorageThread::create()
37 {
38     return adoptRef(new LocalStorageThread);
39 }
40 
LocalStorageThread()41 LocalStorageThread::LocalStorageThread()
42     : m_threadID(0)
43 {
44     m_selfRef = this;
45 }
46 
start()47 bool LocalStorageThread::start()
48 {
49     MutexLocker lock(m_threadCreationMutex);
50 
51     if (m_threadID)
52         return true;
53 
54     m_threadID = createThread(LocalStorageThread::localStorageThreadStart, this, "WebCore: LocalStorage");
55 
56     return m_threadID;
57 }
58 
localStorageThreadStart(void * thread)59 void* LocalStorageThread::localStorageThreadStart(void* thread)
60 {
61     return static_cast<LocalStorageThread*>(thread)->localStorageThread();
62 }
63 
localStorageThread()64 void* LocalStorageThread::localStorageThread()
65 {
66     {
67         // Wait for LocalStorageThread::start() to complete.
68         MutexLocker lock(m_threadCreationMutex);
69     }
70 
71     while (true) {
72         RefPtr<LocalStorageTask> task;
73         if (!m_queue.waitForMessage(task))
74             break;
75 
76         task->performTask();
77     }
78 
79     // Detach the thread so its resources are no longer of any concern to anyone else
80     detachThread(m_threadID);
81     m_threadID = 0;
82 
83     // Clear the self refptr, possibly resulting in deletion
84     m_selfRef = 0;
85 
86     return 0;
87 }
88 
scheduleImport(PassRefPtr<StorageAreaSync> area)89 void LocalStorageThread::scheduleImport(PassRefPtr<StorageAreaSync> area)
90 {
91     ASSERT(!m_queue.killed() && m_threadID);
92     m_queue.append(LocalStorageTask::createImport(area));
93 }
94 
scheduleSync(PassRefPtr<StorageAreaSync> area)95 void LocalStorageThread::scheduleSync(PassRefPtr<StorageAreaSync> area)
96 {
97     ASSERT(!m_queue.killed() && m_threadID);
98     m_queue.append(LocalStorageTask::createSync(area));
99 }
100 
terminate()101 void LocalStorageThread::terminate()
102 {
103     ASSERT(isMainThread());
104 
105     // Ideally we'd never be killing a thread that wasn't live, so ASSERT it.
106     // But if we do in a release build, make sure to not wait on a condition that will never get signalled
107     ASSERT(!m_queue.killed() && m_threadID);
108     if (!m_threadID)
109         return;
110 
111     MutexLocker locker(m_terminateLock);
112 
113     m_queue.append(LocalStorageTask::createTerminate(this));
114 
115     m_terminateCondition.wait(m_terminateLock);
116 }
117 
performTerminate()118 void LocalStorageThread::performTerminate()
119 {
120     ASSERT(!isMainThread());
121 
122     m_queue.kill();
123 
124     MutexLocker locker(m_terminateLock);
125     m_terminateCondition.signal();
126 }
127 
128 }
129 
130 #endif // ENABLE(DOM_STORAGE)
131 
132