OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/fileapi/syncable/local_file_sync_context.h" | 5 #include "webkit/fileapi/syncable/local_file_sync_context.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | |
9 #include "base/location.h" | 8 #include "base/location.h" |
10 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
11 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
12 #include "base/task_runner_util.h" | 11 #include "base/task_runner_util.h" |
13 #include "webkit/fileapi/file_system_context.h" | 12 #include "webkit/fileapi/file_system_context.h" |
14 #include "webkit/fileapi/file_system_task_runners.h" | 13 #include "webkit/fileapi/file_system_task_runners.h" |
14 #include "webkit/fileapi/syncable/file_change.h" | |
15 #include "webkit/fileapi/syncable/local_file_change_tracker.h" | 15 #include "webkit/fileapi/syncable/local_file_change_tracker.h" |
16 #include "webkit/fileapi/syncable/syncable_file_operation_runner.h" | 16 #include "webkit/fileapi/syncable/syncable_file_operation_runner.h" |
17 | 17 |
18 namespace fileapi { | 18 namespace fileapi { |
19 | 19 |
20 LocalFileSyncContext::LocalFileSyncContext( | 20 LocalFileSyncContext::LocalFileSyncContext( |
21 base::SingleThreadTaskRunner* ui_task_runner, | 21 base::SingleThreadTaskRunner* ui_task_runner, |
22 base::SingleThreadTaskRunner* io_task_runner) | 22 base::SingleThreadTaskRunner* io_task_runner) |
23 : ui_task_runner_(ui_task_runner), | 23 : ui_task_runner_(ui_task_runner), |
24 io_task_runner_(io_task_runner) { | 24 io_task_runner_(io_task_runner), |
25 shutdown_on_ui_(false) { | |
25 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 26 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
26 } | 27 } |
27 | 28 |
28 void LocalFileSyncContext::MaybeInitializeFileSystemContext( | 29 void LocalFileSyncContext::MaybeInitializeFileSystemContext( |
29 const GURL& source_url, | 30 const GURL& source_url, |
30 FileSystemContext* file_system_context, | 31 FileSystemContext* file_system_context, |
31 const StatusCallback& callback) { | 32 const StatusCallback& callback) { |
32 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 33 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
33 if (ContainsKey(file_system_contexts_, file_system_context)) { | 34 if (ContainsKey(file_system_contexts_, file_system_context)) { |
34 DCHECK(!ContainsKey(origin_to_contexts_, source_url) || | 35 DCHECK(!ContainsKey(origin_to_contexts_, source_url) || |
(...skipping 12 matching lines...) Expand all Loading... | |
47 return; | 48 return; |
48 | 49 |
49 io_task_runner_->PostTask( | 50 io_task_runner_->PostTask( |
50 FROM_HERE, | 51 FROM_HERE, |
51 base::Bind(&LocalFileSyncContext::InitializeFileSystemContextOnIOThread, | 52 base::Bind(&LocalFileSyncContext::InitializeFileSystemContextOnIOThread, |
52 this, source_url, make_scoped_refptr(file_system_context))); | 53 this, source_url, make_scoped_refptr(file_system_context))); |
53 } | 54 } |
54 | 55 |
55 void LocalFileSyncContext::ShutdownOnUIThread() { | 56 void LocalFileSyncContext::ShutdownOnUIThread() { |
56 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 57 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
58 shutdown_on_ui_ = true; | |
57 io_task_runner_->PostTask( | 59 io_task_runner_->PostTask( |
58 FROM_HERE, | 60 FROM_HERE, |
59 base::Bind(&LocalFileSyncContext::ShutdownOnIOThread, | 61 base::Bind(&LocalFileSyncContext::ShutdownOnIOThread, |
60 this)); | 62 this)); |
61 } | 63 } |
62 | 64 |
65 void LocalFileSyncContext::PrepareForSync( | |
66 const FileSystemURL& url, | |
67 const ChangeListCallback& callback) { | |
68 // This is initially called on UI thread and to be relayed to IO thread. | |
69 if (!io_task_runner_->RunsTasksOnCurrentThread()) { | |
70 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
71 io_task_runner_->PostTask( | |
72 FROM_HERE, | |
73 base::Bind(&LocalFileSyncContext::PrepareForSync, this, url, callback)); | |
74 return; | |
75 } | |
76 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | |
77 if (sync_status()->IsWriting(url)) { | |
78 ui_task_runner_->PostTask( | |
79 FROM_HERE, | |
80 base::Bind(callback, SYNC_STATUS_FILE_BUSY, FileChangeList())); | |
81 return; | |
82 } | |
83 sync_status()->StartSyncing(url); | |
84 ui_task_runner_->PostTask( | |
85 FROM_HERE, | |
86 base::Bind(&LocalFileSyncContext::DidDisabledWritesForPrepareForSync, | |
87 this, url, callback)); | |
88 } | |
89 | |
90 void LocalFileSyncContext::RegisterURLForWaitingSync( | |
91 const FileSystemURL& url, | |
92 const URLCallback& on_syncable_callback) { | |
93 // This is initially called on UI thread and to be relayed to IO thread. | |
94 if (!io_task_runner_->RunsTasksOnCurrentThread()) { | |
95 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
96 io_task_runner_->PostTask( | |
97 FROM_HERE, | |
98 base::Bind(&LocalFileSyncContext::RegisterURLForWaitingSync, | |
99 this, url, on_syncable_callback)); | |
100 return; | |
101 } | |
102 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | |
103 if (sync_status()->IsWritable(url)) { | |
104 // No need to register; fire the callback now. | |
105 ui_task_runner_->PostTask(FROM_HERE, base::Bind(on_syncable_callback, url)); | |
106 return; | |
107 } | |
108 DCHECK(url_syncable_callback_.is_null()); | |
109 url_waiting_sync_on_io_ = url; | |
110 url_syncable_callback_ = on_syncable_callback; | |
tzik
2012/10/24 03:45:13
Could you support multiple URL to wait?
Remote sid
kinuko
2012/10/24 09:39:56
Does it work if we simply replace the URL to wait
kinuko
2012/10/24 14:07:05
For now I changed the code to simply replace the U
tzik
2012/10/25 08:14:42
Sorry for delayed comment, the replacement seems t
| |
111 } | |
112 | |
63 base::WeakPtr<SyncableFileOperationRunner> | 113 base::WeakPtr<SyncableFileOperationRunner> |
64 LocalFileSyncContext::operation_runner() const { | 114 LocalFileSyncContext::operation_runner() const { |
65 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 115 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); |
66 if (operation_runner_.get()) | 116 if (operation_runner_.get()) |
67 return operation_runner_->AsWeakPtr(); | 117 return operation_runner_->AsWeakPtr(); |
68 return base::WeakPtr<SyncableFileOperationRunner>(); | 118 return base::WeakPtr<SyncableFileOperationRunner>(); |
69 } | 119 } |
70 | 120 |
121 LocalFileSyncStatus* LocalFileSyncContext::sync_status() const { | |
122 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | |
123 return sync_status_.get(); | |
124 } | |
125 | |
126 void LocalFileSyncContext::OnSyncEnabled(const FileSystemURL& url) { | |
127 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | |
128 if (url_syncable_callback_.is_null() || | |
129 sync_status()->IsWriting(url_waiting_sync_on_io_)) | |
130 return; | |
131 // TODO(kinuko): may want to check how many pending tasks we have. | |
132 sync_status()->StartSyncing(url_waiting_sync_on_io_); | |
133 ui_task_runner_->PostTask(FROM_HERE, | |
134 base::Bind(url_syncable_callback_, | |
135 url_waiting_sync_on_io_)); | |
136 url_syncable_callback_.Reset(); | |
137 } | |
138 | |
139 void LocalFileSyncContext::OnWriteEnabled(const FileSystemURL& url) { | |
140 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | |
141 } | |
142 | |
71 LocalFileSyncContext::~LocalFileSyncContext() { | 143 LocalFileSyncContext::~LocalFileSyncContext() { |
72 } | 144 } |
73 | 145 |
74 void LocalFileSyncContext::ShutdownOnIOThread() { | 146 void LocalFileSyncContext::ShutdownOnIOThread() { |
75 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 147 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); |
76 operation_runner_.reset(); | 148 operation_runner_.reset(); |
77 } | 149 } |
78 | 150 |
79 void LocalFileSyncContext::InitializeFileSystemContextOnIOThread( | 151 void LocalFileSyncContext::InitializeFileSystemContextOnIOThread( |
80 const GURL& source_url, | 152 const GURL& source_url, |
(...skipping 10 matching lines...) Expand all Loading... | |
91 FROM_HERE, | 163 FROM_HERE, |
92 base::Bind(&LocalFileSyncContext::InitializeChangeTrackerOnFileThread, | 164 base::Bind(&LocalFileSyncContext::InitializeChangeTrackerOnFileThread, |
93 this, tracker_ptr, | 165 this, tracker_ptr, |
94 make_scoped_refptr(file_system_context)), | 166 make_scoped_refptr(file_system_context)), |
95 base::Bind(&LocalFileSyncContext::DidInitializeChangeTracker, this, | 167 base::Bind(&LocalFileSyncContext::DidInitializeChangeTracker, this, |
96 base::Owned(tracker_ptr), | 168 base::Owned(tracker_ptr), |
97 source_url, | 169 source_url, |
98 make_scoped_refptr(file_system_context))); | 170 make_scoped_refptr(file_system_context))); |
99 return; | 171 return; |
100 } | 172 } |
101 if (!operation_runner_.get()) | 173 if (!operation_runner_.get()) { |
102 operation_runner_.reset(new SyncableFileOperationRunner); | 174 DCHECK(!sync_status_.get()); |
175 sync_status_.reset(new LocalFileSyncStatus); | |
176 operation_runner_.reset(new SyncableFileOperationRunner( | |
177 kMaxConcurrentSyncableOperation, | |
178 sync_status_.get())); | |
179 sync_status_->AddObserver(this); | |
180 } | |
103 file_system_context->set_sync_context(this); | 181 file_system_context->set_sync_context(this); |
104 DidInitialize(source_url, file_system_context, SYNC_STATUS_OK); | 182 DidInitialize(source_url, file_system_context, SYNC_STATUS_OK); |
105 } | 183 } |
106 | 184 |
107 SyncStatusCode LocalFileSyncContext::InitializeChangeTrackerOnFileThread( | 185 SyncStatusCode LocalFileSyncContext::InitializeChangeTrackerOnFileThread( |
108 scoped_ptr<LocalFileChangeTracker>* tracker_ptr, | 186 scoped_ptr<LocalFileChangeTracker>* tracker_ptr, |
109 FileSystemContext* file_system_context) { | 187 FileSystemContext* file_system_context) { |
110 DCHECK(file_system_context); | 188 DCHECK(file_system_context); |
111 DCHECK(tracker_ptr); | 189 DCHECK(tracker_ptr); |
112 tracker_ptr->reset(new LocalFileChangeTracker( | 190 tracker_ptr->reset(new LocalFileChangeTracker( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 | 231 |
154 StatusCallbackQueue& callback_queue = | 232 StatusCallbackQueue& callback_queue = |
155 pending_initialize_callbacks_[file_system_context]; | 233 pending_initialize_callbacks_[file_system_context]; |
156 for (StatusCallbackQueue::iterator iter = callback_queue.begin(); | 234 for (StatusCallbackQueue::iterator iter = callback_queue.begin(); |
157 iter != callback_queue.end(); ++iter) { | 235 iter != callback_queue.end(); ++iter) { |
158 ui_task_runner_->PostTask(FROM_HERE, base::Bind(*iter, status)); | 236 ui_task_runner_->PostTask(FROM_HERE, base::Bind(*iter, status)); |
159 } | 237 } |
160 pending_initialize_callbacks_.erase(file_system_context); | 238 pending_initialize_callbacks_.erase(file_system_context); |
161 } | 239 } |
162 | 240 |
241 void LocalFileSyncContext::DidDisabledWritesForPrepareForSync( | |
242 const FileSystemURL& url, | |
243 const ChangeListCallback& callback) { | |
244 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
245 if (shutdown_on_ui_) { | |
246 callback.Run(SYNC_STATUS_ABORT, FileChangeList()); | |
247 return; | |
248 } | |
249 DCHECK(ContainsKey(origin_to_contexts_, url.origin())); | |
250 FileSystemContext* context = origin_to_contexts_[url.origin()]; | |
251 DCHECK(context); | |
252 DCHECK(context->change_tracker()); | |
253 | |
254 FileChangeList changes; | |
255 context->change_tracker()->GetChangesForURL(url, &changes); | |
256 callback.Run(SYNC_STATUS_OK, changes); | |
257 } | |
258 | |
163 } // namespace fileapi | 259 } // namespace fileapi |
OLD | NEW |