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

Side by Side Diff: components/leveldb/leveldb_file_thread.cc

Issue 1839823002: mojo leveldb: Remove the created file thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: And cut out manual Signal()ing most places. Created 4 years, 8 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
« no previous file with comments | « components/leveldb/leveldb_file_thread.h ('k') | components/leveldb/leveldb_mojo_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/leveldb/leveldb_file_thread.h"
6
7 #include <set>
8
9 #include "base/bind.h"
10 #include "mojo/message_pump/message_pump_mojo.h"
11 #include "mojo/platform_handle/platform_handle_functions.h"
12
13 namespace leveldb {
14
15 namespace {
16 const char kLevelDBFileThreadName[] = "LevelDB_File_Thread";
17 } // namespace
18
19 struct LevelDBFileThread::OpaqueLock {
20 filesystem::FilePtr lock_file;
21 };
22
23 struct LevelDBFileThread::OpaqueDir {
24 explicit OpaqueDir(
25 mojo::InterfacePtrInfo<filesystem::Directory> directory_info) {
26 directory.Bind(std::move(directory_info));
27 }
28
29 filesystem::DirectoryPtr directory;
30 };
31
32 struct LevelDBFileThread::WaitableEventDependencies {
33 WaitableEventDependencies() {}
34 ~WaitableEventDependencies() {}
35 std::set<filesystem::DirectoryPtr*> directories;
36 std::set<filesystem::FilePtr*> files;
37 };
38
39 LevelDBFileThread::LevelDBFileThread()
40 : base::Thread(kLevelDBFileThreadName),
41 outstanding_opaque_dirs_(0) {
42 base::Thread::Options options;
43 options.message_pump_factory =
44 base::Bind(&mojo::common::MessagePumpMojo::Create);
45 StartWithOptions(options);
46 }
47
48 LevelDBFileThread::OpaqueDir* LevelDBFileThread::RegisterDirectory(
49 filesystem::DirectoryPtr directory) {
50 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
51
52 OpaqueDir* out_dir = nullptr;
53
54 // This proxies to the other thread, which proxies to mojo. Only on the reply
55 // from mojo do we return from this.
56 base::WaitableEvent done_event(false, false);
57 task_runner()->PostTask(
58 FROM_HERE, base::Bind(&LevelDBFileThread::RegisterDirectoryImpl,
59 this,
60 &done_event,
61 base::Passed(directory.PassInterface()),
62 &out_dir));
63 done_event.Wait();
64
65 return out_dir;
66 }
67
68 void LevelDBFileThread::UnregisterDirectory(OpaqueDir* dir) {
69 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
70
71 // This proxies to the other thread, which proxies to mojo. Only on the reply
72 // from mojo do we return from this.
73 base::WaitableEvent done_event(false, false);
74 task_runner()->PostTask(
75 FROM_HERE, base::Bind(&LevelDBFileThread::UnregisterDirectoryImpl,
76 this,
77 &done_event,
78 dir));
79 done_event.Wait();
80 }
81
82 base::File LevelDBFileThread::OpenFileHandle(OpaqueDir* dir,
83 const std::string& name,
84 uint32_t open_flags) {
85 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
86
87 base::File file;
88
89 // This proxies to the other thread, which proxies to mojo. Only on the reply
90 // from mojo do we return from this.
91 base::WaitableEvent done_event(false, false);
92 task_runner()->PostTask(
93 FROM_HERE, base::Bind(&LevelDBFileThread::OpenFileHandleImpl, this,
94 dir, name, &done_event, open_flags, &file));
95 done_event.Wait();
96
97 return file;
98 }
99
100 filesystem::FileError LevelDBFileThread::SyncDirectory(
101 OpaqueDir* dir,
102 const std::string& name) {
103 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
104
105 filesystem::FileError error;
106
107 // This proxies to the other thread, which proxies to mojo. Only on the reply
108 // from mojo do we return from this.
109 base::WaitableEvent done_event(false, false);
110 task_runner()->PostTask(
111 FROM_HERE, base::Bind(&LevelDBFileThread::SyncDirectoryImpl, this,
112 dir, name, &done_event, &error));
113 done_event.Wait();
114
115 return error;
116 }
117
118 bool LevelDBFileThread::FileExists(OpaqueDir* dir,
119 const std::string& name) {
120 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
121
122 bool exists;
123
124 // This proxies to the other thread, which proxies to mojo. Only on the reply
125 // from mojo do we return from this.
126 base::WaitableEvent done_event(false, false);
127 task_runner()->PostTask(
128 FROM_HERE, base::Bind(&LevelDBFileThread::FileExistsImpl, this,
129 dir, name, &done_event, &exists));
130 done_event.Wait();
131
132 return exists;
133 }
134
135 filesystem::FileError LevelDBFileThread::GetChildren(
136 OpaqueDir* dir,
137 const std::string& path,
138 std::vector<std::string>* result) {
139 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
140
141 filesystem::FileError error;
142
143 // This proxies to the other thread, which proxies to mojo. Only on the reply
144 // from mojo do we return from this.
145 base::WaitableEvent done_event(false, false);
146 task_runner()->PostTask(
147 FROM_HERE, base::Bind(&LevelDBFileThread::GetChildrenImpl, this,
148 dir, path, result, &done_event, &error));
149 done_event.Wait();
150
151 return error;
152 }
153
154 filesystem::FileError LevelDBFileThread::Delete(OpaqueDir* dir,
155 const std::string& path,
156 uint32_t delete_flags) {
157 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
158
159 filesystem::FileError error;
160
161 // This proxies to the other thread, which proxies to mojo. Only on the reply
162 // from mojo do we return from this.
163 base::WaitableEvent done_event(false, false);
164 task_runner()->PostTask(FROM_HERE,
165 base::Bind(&LevelDBFileThread::DeleteImpl, this,
166 dir, path, delete_flags, &done_event,
167 &error));
168 done_event.Wait();
169
170 return error;
171 }
172
173 filesystem::FileError LevelDBFileThread::CreateDir(OpaqueDir* dir,
174 const std::string& path) {
175 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
176
177 filesystem::FileError error;
178
179 // This proxies to the other thread, which proxies to mojo. Only on the reply
180 // from mojo do we return from this.
181 base::WaitableEvent done_event(false, false);
182 task_runner()->PostTask(
183 FROM_HERE, base::Bind(&LevelDBFileThread::CreateDirImpl, this,
184 dir, path, &done_event, &error));
185 done_event.Wait();
186
187 return error;
188 }
189
190 filesystem::FileError LevelDBFileThread::GetFileSize(OpaqueDir* dir,
191 const std::string& path,
192 uint64_t* file_size) {
193 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
194
195 filesystem::FileError error;
196
197 // This proxies to the other thread, which proxies to mojo. Only on the reply
198 // from mojo do we return from this.
199 base::WaitableEvent done_event(false, false);
200 task_runner()->PostTask(
201 FROM_HERE, base::Bind(&LevelDBFileThread::GetFileSizeImpl, this,
202 dir, path, file_size, &done_event, &error));
203 done_event.Wait();
204
205 return error;
206 }
207
208 filesystem::FileError LevelDBFileThread::RenameFile(
209 OpaqueDir* dir,
210 const std::string& old_path,
211 const std::string& new_path) {
212 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
213
214 filesystem::FileError error;
215
216 // This proxies to the other thread, which proxies to mojo. Only on the reply
217 // from mojo do we return from this.
218 base::WaitableEvent done_event(false, false);
219 task_runner()->PostTask(
220 FROM_HERE, base::Bind(&LevelDBFileThread::RenameFileImpl, this,
221 dir, old_path, new_path, &done_event, &error));
222 done_event.Wait();
223
224 return error;
225 }
226
227 std::pair<filesystem::FileError, LevelDBFileThread::OpaqueLock*>
228 LevelDBFileThread::LockFile(OpaqueDir* dir,
229 const std::string& path) {
230 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
231
232 filesystem::FileError error;
233 OpaqueLock* out_lock = nullptr;
234
235 // This proxies to the other thread, which proxies to mojo. Only on the reply
236 // from mojo do we return from this.
237 base::WaitableEvent done_event(false, false);
238 task_runner()->PostTask(
239 FROM_HERE, base::Bind(&LevelDBFileThread::LockFileImpl, this,
240 dir, path, &done_event, &error, &out_lock));
241 done_event.Wait();
242
243 return std::make_pair(error, out_lock);
244 }
245
246 filesystem::FileError LevelDBFileThread::UnlockFile(OpaqueLock* lock) {
247 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
248
249 // Take ownership of the incoming lock so it gets destroyed whatever happens.
250 scoped_ptr<OpaqueLock> scoped_lock(lock);
251
252 filesystem::FileError error;
253
254 // This proxies to the other thread, which proxies to mojo. Only on the reply
255 // from mojo do we return from this.
256 base::WaitableEvent done_event(false, false);
257 task_runner()->PostTask(
258 FROM_HERE, base::Bind(&LevelDBFileThread::UnlockFileImpl, this,
259 base::Passed(&scoped_lock), &done_event, &error));
260 done_event.Wait();
261
262 return error;
263 }
264
265 LevelDBFileThread::~LevelDBFileThread() {
266 Stop();
267 DCHECK_EQ(0, outstanding_opaque_dirs_);
268 }
269
270 bool LevelDBFileThread::RegisterDirAndWaitableEvent(
271 OpaqueDir* dir,
272 base::WaitableEvent* done_event) {
273 if (!dir->directory.is_bound()) {
274 // The directory went out of scope between the PostTask on the other thread
275 // and now.
276 done_event->Signal();
277 return true;
278 }
279
280 waitable_event_dependencies_[done_event].directories.insert(&dir->directory);
281 return false;
282 }
283
284 void LevelDBFileThread::CompleteWaitableEvent(base::WaitableEvent* done_event) {
285 // Clean up the dependencies that we no longer care about.
286 waitable_event_dependencies_.erase(done_event);
287 done_event->Signal();
288 }
289
290 void LevelDBFileThread::OnConnectionError() {
291 // One of our interface ptrs has become unbound. Signal the event which has
292 // it as a dependency.
293 auto it = waitable_event_dependencies_.begin();
294 while (it != waitable_event_dependencies_.end()) {
295 bool unbound_ptr_found = false;
296 for (const auto* dir : it->second.directories) {
297 if (!dir->is_bound()) {
298 unbound_ptr_found = true;
299 break;
300 }
301 }
302
303 if (!unbound_ptr_found) {
304 for (const auto* file : it->second.files) {
305 if (!file->is_bound()) {
306 unbound_ptr_found = true;
307 break;
308 }
309 }
310 }
311
312 if (unbound_ptr_found) {
313 base::WaitableEvent* e = it->first;
314 it = waitable_event_dependencies_.erase(it);
315 e->Signal();
316 } else {
317 ++it;
318 }
319 }
320 }
321
322 void LevelDBFileThread::OnSimpleComplete(base::WaitableEvent* done_event,
323 filesystem::FileError* out_error,
324 filesystem::FileError in_error) {
325 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
326 *out_error = in_error;
327 CompleteWaitableEvent(done_event);
328 }
329
330 void LevelDBFileThread::RegisterDirectoryImpl(
331 base::WaitableEvent* done_event,
332 mojo::InterfacePtrInfo<filesystem::Directory> directory_info,
333 OpaqueDir** out_dir) {
334 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
335
336 // Take the Directory pipe and bind it on this thread.
337 *out_dir = new OpaqueDir(std::move(directory_info));
338 outstanding_opaque_dirs_++;
339
340 // Register the connection error handler for the resulting DirectoryPtr
341 (*out_dir)->directory.set_connection_error_handler(
342 base::Bind(&LevelDBFileThread::OnConnectionError, this));
343
344 done_event->Signal();
345 }
346
347 void LevelDBFileThread::UnregisterDirectoryImpl(
348 base::WaitableEvent* done_event,
349 OpaqueDir* dir) {
350 // Only delete the directories on the thread that owns them.
351 delete dir;
352 outstanding_opaque_dirs_--;
353 CompleteWaitableEvent(done_event);
354 }
355
356 void LevelDBFileThread::OpenFileHandleImpl(OpaqueDir* dir,
357 std::string name,
358 base::WaitableEvent* done_event,
359 uint32_t open_flags,
360 base::File* out_file) {
361 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
362
363 if (RegisterDirAndWaitableEvent(dir, done_event))
364 return;
365
366 dir->directory->OpenFileHandle(
367 mojo::String::From(name), open_flags,
368 base::Bind(&LevelDBFileThread::OnOpenFileHandleComplete, this, done_event,
369 out_file));
370 }
371
372 void LevelDBFileThread::OnOpenFileHandleComplete(
373 base::WaitableEvent* done_event,
374 base::File* output_file,
375 filesystem::FileError err,
376 mojo::ScopedHandle handle) {
377 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
378
379 if (err != filesystem::FileError::OK) {
380 *output_file = base::File(static_cast<base::File::Error>(err));
381 } else {
382 MojoPlatformHandle platform_handle;
383 MojoResult extract_result =
384 MojoExtractPlatformHandle(handle.release().value(), &platform_handle);
385
386 if (extract_result == MOJO_RESULT_OK) {
387 *output_file = base::File(platform_handle);
388 } else {
389 NOTREACHED();
390 *output_file = base::File(base::File::Error::FILE_ERROR_FAILED);
391 }
392 }
393
394 CompleteWaitableEvent(done_event);
395 }
396
397 void LevelDBFileThread::SyncDirectoryImpl(OpaqueDir* dir,
398 std::string name,
399 base::WaitableEvent* done_event,
400 filesystem::FileError* out_error) {
401 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
402
403 if (RegisterDirAndWaitableEvent(dir, done_event))
404 return;
405
406 // Step one: open the directory |name| from the toplevel directory.
407 scoped_ptr<filesystem::DirectoryPtr> target(new filesystem::DirectoryPtr);
408
409 dir->directory->OpenDirectory(
410 name, GetProxy(target.get()),
411 filesystem::kFlagRead | filesystem::kFlagWrite,
412 base::Bind(&LevelDBFileThread::OnSyncDirctoryOpened, this,
413 base::Passed(&target), done_event, out_error));
414 }
415
416 void LevelDBFileThread::OnSyncDirctoryOpened(
417 scoped_ptr<filesystem::DirectoryPtr> dir,
418 base::WaitableEvent* done_event,
419 filesystem::FileError* out_error,
420 filesystem::FileError in_error) {
421 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
422
423 if (in_error != filesystem::FileError::OK) {
424 *out_error = in_error;
425 CompleteWaitableEvent(done_event);
426 return;
427 }
428
429 // Add a dependency between the new directory we opened and the current
430 // waitable event.
431 dir->set_connection_error_handler(
432 base::Bind(&LevelDBFileThread::OnConnectionError, this));
433 waitable_event_dependencies_[done_event].directories.insert(dir.get());
434
435 // We move the object into the bind before we call. Copy to the stack.
436 filesystem::DirectoryPtr* local = dir.get();
437 (*local)->Flush(base::Bind(&LevelDBFileThread::OnSyncDirectoryComplete, this,
438 base::Passed(&dir), done_event, out_error));
439 }
440
441 void LevelDBFileThread::OnSyncDirectoryComplete(
442 scoped_ptr<filesystem::DirectoryPtr> dir,
443 base::WaitableEvent* done_event,
444 filesystem::FileError* out_error,
445 filesystem::FileError in_error) {
446 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
447 *out_error = in_error;
448 CompleteWaitableEvent(done_event);
449 }
450
451 void LevelDBFileThread::FileExistsImpl(OpaqueDir* dir,
452 std::string name,
453 base::WaitableEvent* done_event,
454 bool* exists) {
455 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
456
457 if (RegisterDirAndWaitableEvent(dir, done_event))
458 return;
459
460 dir->directory->Exists(
461 mojo::String::From(name),
462 base::Bind(&LevelDBFileThread::OnFileExistsComplete, this,
463 done_event, exists));
464 }
465
466 void LevelDBFileThread::OnFileExistsComplete(base::WaitableEvent* done_event,
467 bool* exists,
468 filesystem::FileError err,
469 bool in_exists) {
470 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
471 *exists = in_exists;
472 CompleteWaitableEvent(done_event);
473 }
474
475 void LevelDBFileThread::GetChildrenImpl(OpaqueDir* dir,
476 std::string name,
477 std::vector<std::string>* contents,
478 base::WaitableEvent* done_event,
479 filesystem::FileError* out_error) {
480 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
481
482 if (RegisterDirAndWaitableEvent(dir, done_event))
483 return;
484
485 // Step one: open the directory |name| from the toplevel directory.
486 scoped_ptr<filesystem::DirectoryPtr> target(new filesystem::DirectoryPtr);
487 mojo::InterfaceRequest<filesystem::Directory> proxy = GetProxy(target.get());
488 dir->directory->OpenDirectory(
489 name, std::move(proxy), filesystem::kFlagRead | filesystem::kFlagWrite,
490 base::Bind(&LevelDBFileThread::OnGetChildrenOpened, this,
491 base::Passed(&target), contents, done_event, out_error));
492 }
493
494 void LevelDBFileThread::OnGetChildrenOpened(
495 scoped_ptr<filesystem::DirectoryPtr> dir,
496 std::vector<std::string>* contents,
497 base::WaitableEvent* done_event,
498 filesystem::FileError* out_error,
499 filesystem::FileError in_error) {
500 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
501
502 if (in_error != filesystem::FileError::OK) {
503 *out_error = in_error;
504 CompleteWaitableEvent(done_event);
505 return;
506 }
507
508 // Add a dependency between the new directory we opened and the current
509 // waitable event.
510 dir->set_connection_error_handler(
511 base::Bind(&LevelDBFileThread::OnConnectionError, this));
512 waitable_event_dependencies_[done_event].directories.insert(dir.get());
513
514 // We move the object into the bind before we call. Copy to the stack.
515 filesystem::DirectoryPtr* local = dir.get();
516 (*local)->Read(base::Bind(&LevelDBFileThread::OnGetChildrenComplete, this,
517 base::Passed(&dir), contents, done_event,
518 out_error));
519 }
520
521 void LevelDBFileThread::OnGetChildrenComplete(
522 scoped_ptr<filesystem::DirectoryPtr> dir,
523 std::vector<std::string>* out_contents,
524 base::WaitableEvent* done_event,
525 filesystem::FileError* out_error,
526 filesystem::FileError in_error,
527 mojo::Array<filesystem::DirectoryEntryPtr> directory_contents) {
528 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
529
530 if (!directory_contents.is_null()) {
531 for (size_t i = 0; i < directory_contents.size(); ++i)
532 out_contents->push_back(directory_contents[i]->name.To<std::string>());
533 }
534
535 *out_error = in_error;
536 CompleteWaitableEvent(done_event);
537 }
538
539 void LevelDBFileThread::DeleteImpl(OpaqueDir* dir,
540 std::string name,
541 uint32_t delete_flags,
542 base::WaitableEvent* done_event,
543 filesystem::FileError* out_error) {
544 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
545
546 if (RegisterDirAndWaitableEvent(dir, done_event))
547 return;
548
549 dir->directory->Delete(mojo::String::From(name), delete_flags,
550 base::Bind(&LevelDBFileThread::OnSimpleComplete, this,
551 done_event, out_error));
552 }
553
554 void LevelDBFileThread::CreateDirImpl(OpaqueDir* dir,
555 std::string name,
556 base::WaitableEvent* done_event,
557 filesystem::FileError* out_error) {
558 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
559
560 if (RegisterDirAndWaitableEvent(dir, done_event))
561 return;
562
563 dir->directory->OpenDirectory(
564 name, nullptr,
565 filesystem::kFlagRead | filesystem::kFlagWrite | filesystem::kFlagCreate,
566 base::Bind(&LevelDBFileThread::OnSimpleComplete, this, done_event,
567 out_error));
568 }
569
570 void LevelDBFileThread::GetFileSizeImpl(OpaqueDir* dir,
571 const std::string& path,
572 uint64_t* file_size,
573 base::WaitableEvent* done_event,
574 filesystem::FileError* out_error) {
575 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
576
577 if (RegisterDirAndWaitableEvent(dir, done_event))
578 return;
579
580 dir->directory->StatFile(
581 path, base::Bind(&LevelDBFileThread::OnGetFileSizeImpl, this, file_size,
582 done_event, out_error));
583 }
584
585 void LevelDBFileThread::OnGetFileSizeImpl(
586 uint64_t* file_size,
587 base::WaitableEvent* done_event,
588 filesystem::FileError* out_error,
589 filesystem::FileError in_error,
590 filesystem::FileInformationPtr file_info) {
591 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
592 if (file_info)
593 *file_size = file_info->size;
594 *out_error = in_error;
595 CompleteWaitableEvent(done_event);
596 }
597
598 void LevelDBFileThread::RenameFileImpl(OpaqueDir* dir,
599 const std::string& old_path,
600 const std::string& new_path,
601 base::WaitableEvent* done_event,
602 filesystem::FileError* out_error) {
603 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
604
605 if (RegisterDirAndWaitableEvent(dir, done_event))
606 return;
607
608 dir->directory->Rename(mojo::String::From(old_path),
609 mojo::String::From(new_path),
610 base::Bind(&LevelDBFileThread::OnSimpleComplete, this,
611 done_event, out_error));
612 }
613
614 void LevelDBFileThread::LockFileImpl(OpaqueDir* dir,
615 const std::string& path,
616 base::WaitableEvent* done_event,
617 filesystem::FileError* out_error,
618 OpaqueLock** out_lock) {
619 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
620
621 if (RegisterDirAndWaitableEvent(dir, done_event))
622 return;
623
624 // Since a lock is associated with a file descriptor, we need to open and
625 // have a persistent file on the other side of the connection.
626 scoped_ptr<filesystem::FilePtr> target(new filesystem::FilePtr);
627 mojo::InterfaceRequest<filesystem::File> proxy = GetProxy(target.get());
628 dir->directory->OpenFile(
629 mojo::String::From(path), std::move(proxy),
630 filesystem::kFlagOpenAlways | filesystem::kFlagRead |
631 filesystem::kFlagWrite,
632 base::Bind(&LevelDBFileThread::OnOpenLockFileComplete, this,
633 base::Passed(&target), done_event, out_error, out_lock));
634 }
635
636 void LevelDBFileThread::OnOpenLockFileComplete(
637 scoped_ptr<filesystem::FilePtr> file,
638 base::WaitableEvent* done_event,
639 filesystem::FileError* out_error,
640 OpaqueLock** out_lock,
641 filesystem::FileError in_error) {
642 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
643
644 if (in_error != filesystem::FileError::OK) {
645 *out_error = in_error;
646 CompleteWaitableEvent(done_event);
647 return;
648 }
649
650 // Add a dependency between the new file we opened and the current waitable
651 // event. (This dependency will get cleared in OnLockFileComplete if we
652 // complete this call safely.)
653 file->set_connection_error_handler(
654 base::Bind(&LevelDBFileThread::OnConnectionError, this));
655 waitable_event_dependencies_[done_event].files.insert(file.get());
656
657 filesystem::FilePtr* local = file.get();
658 (*local)->Lock(base::Bind(&LevelDBFileThread::OnLockFileComplete, this,
659 base::Passed(&file), done_event, out_error,
660 out_lock));
661 }
662
663 void LevelDBFileThread::OnLockFileComplete(scoped_ptr<filesystem::FilePtr> file,
664 base::WaitableEvent* done_event,
665 filesystem::FileError* out_error,
666 OpaqueLock** out_lock,
667 filesystem::FileError in_error) {
668 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
669
670 *out_error = in_error;
671
672 if (in_error == filesystem::FileError::OK) {
673 OpaqueLock* l = new OpaqueLock;
674 l->lock_file = std::move(*file);
675 *out_lock = l;
676 }
677
678 CompleteWaitableEvent(done_event);
679 }
680
681 void LevelDBFileThread::UnlockFileImpl(scoped_ptr<OpaqueLock> lock,
682 base::WaitableEvent* done_event,
683 filesystem::FileError* out_error) {
684 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
685
686 OpaqueLock* local = lock.get();
687 local->lock_file->Unlock(base::Bind(&LevelDBFileThread::OnUnlockFileCompleted,
688 this, base::Passed(&lock), done_event,
689 out_error));
690 }
691
692 void LevelDBFileThread::OnUnlockFileCompleted(scoped_ptr<OpaqueLock> lock,
693 base::WaitableEvent* done_event,
694 filesystem::FileError* out_error,
695 filesystem::FileError in_error) {
696 // We're passed the OpauqeLock here for ownership reasons, but it's going to
697 // get destructed on its own here.
698 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
699 *out_error = in_error;
700 CompleteWaitableEvent(done_event);
701 }
702
703 void LevelDBFileThread::Init() {
704 }
705
706 void LevelDBFileThread::CleanUp() {
707 }
708
709 } // namespace leveldb
OLDNEW
« no previous file with comments | « components/leveldb/leveldb_file_thread.h ('k') | components/leveldb/leveldb_mojo_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698