diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-11 21:58:09 +0000 |
---|---|---|
committer | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-11 21:58:09 +0000 |
commit | 39c99eaf84c735cfef1e656f8f0c95362e243de7 (patch) | |
tree | bb0de0a2c757786033193c90c38087f83020cab9 | |
parent | aa0c7a415c325885592eef57cefa1024aa92d8d4 (diff) | |
download | chromium_src-39c99eaf84c735cfef1e656f8f0c95362e243de7.zip chromium_src-39c99eaf84c735cfef1e656f8f0c95362e243de7.tar.gz chromium_src-39c99eaf84c735cfef1e656f8f0c95362e243de7.tar.bz2 |
Fix Pepper File IO callbacks.
Add some tests (for aborting calls).
Also fix Flash NetConnector callback running.
BUG=none
TEST=ppapi_tests
Review URL: http://codereview.chromium.org/6228004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71092 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ppapi/tests/test_file_io.cc | 205 | ||||
-rw-r--r-- | ppapi/tests/test_file_io.h | 3 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_file_io_impl.cc | 155 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_file_io_impl.h | 25 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_flash_impl.cc | 11 |
5 files changed, 332 insertions, 67 deletions
diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc index 591d656..11fe62b 100644 --- a/ppapi/tests/test_file_io.cc +++ b/ppapi/tests/test_file_io.cc @@ -1,10 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ppapi/tests/test_file_io.h" #include <stdio.h> +#include <string.h> #include "ppapi/c/pp_errors.h" #include "ppapi/c/dev/ppb_file_io_dev.h" @@ -83,6 +84,10 @@ void TestFileIO::RunTest() { RUN_TEST(Open); RUN_TEST(ReadWriteSetLength); RUN_TEST(TouchQuery); + RUN_TEST(AbortCalls); + // TODO(viettrungluu): add tests: + // - that PP_ERROR_PENDING is correctly returned + // - that operations respect the file open modes (flags) } std::string TestFileIO::TestOpen() { @@ -281,5 +286,203 @@ std::string TestFileIO::TestTouchQuery() { (info.last_modified_time != last_modified_time)) return "FileSystem::Query() has returned bad data."; + // Call |Query()| again, to make sure it works a second time. + rv = file_io.Query(&info, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileSystem::Query", rv); + + PASS(); +} + +std::string TestFileIO::TestAbortCalls() { + TestCompletionCallback callback; + + pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); + pp::FileRef_Dev file_ref(file_system, "/file_abort_calls"); + int32_t rv = file_system.Open(1024, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileSystem::Open", rv); + + // First, create a file which to do ops on. + { + pp::FileIO_Dev file_io; + rv = file_io.Open(file_ref, + PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE, + callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + + // N.B.: Should write at least 3 bytes. + rv = WriteEntireBuffer(&file_io, 0, "foobarbazquux"); + if (rv != PP_OK) + return ReportError("FileIO::Write", rv); + } + + // Abort |Open()|. + { + callback.reset_run_count(); + rv = pp::FileIO_Dev().Open(file_ref, PP_FILEOPENFLAG_READ, callback); + if (callback.run_count() > 0) + return "FileIO::Open ran callback synchronously."; + if (rv == PP_ERROR_WOULDBLOCK) { + rv = callback.WaitForResult(); + if (rv != PP_ERROR_ABORTED) + return "FileIO::Open not aborted."; + } else if (rv != PP_OK) { + return ReportError("FileIO::Open", rv); + } + } + + // Abort |Query()|. + { + PP_FileInfo_Dev info = { 0 }; + { + pp::FileIO_Dev file_io; + rv = file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + + callback.reset_run_count(); + rv = file_io.Query(&info, callback); + } // Destroy |file_io|. + if (rv == PP_ERROR_WOULDBLOCK) { + // Save a copy and make sure |info| doesn't get written to. + PP_FileInfo_Dev info_copy; + memcpy(&info_copy, &info, sizeof(info)); + rv = callback.WaitForResult(); + if (rv != PP_ERROR_ABORTED) + return "FileIO::Query not aborted."; + if (memcmp(&info_copy, &info, sizeof(info)) != 0) + return "FileIO::Query wrote data after resource destruction."; + } else if (rv != PP_OK) { + return ReportError("FileIO::Query", rv); + } + } + + // Abort |Touch()|. + { + { + pp::FileIO_Dev file_io; + rv = file_io.Open(file_ref, PP_FILEOPENFLAG_WRITE, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + + callback.reset_run_count(); + rv = file_io.Touch(0, 0, callback); + } // Destroy |file_io|. + if (rv == PP_ERROR_WOULDBLOCK) { + rv = callback.WaitForResult(); + if (rv != PP_ERROR_ABORTED) + return "FileIO::Touch not aborted."; + } else if (rv != PP_OK) { + return ReportError("FileIO::Touch", rv); + } + } + + // Abort |Read()|. + { + char buf[3] = { 0 }; + { + pp::FileIO_Dev file_io; + rv = file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + + callback.reset_run_count(); + rv = file_io.Read(0, buf, sizeof(buf), callback); + } // Destroy |file_io|. + if (rv == PP_ERROR_WOULDBLOCK) { + // Save a copy and make sure |buf| doesn't get written to. + char buf_copy[3]; + memcpy(&buf_copy, &buf, sizeof(buf)); + rv = callback.WaitForResult(); + if (rv != PP_ERROR_ABORTED) + return "FileIO::Read not aborted."; + if (memcmp(&buf_copy, &buf, sizeof(buf)) != 0) + return "FileIO::Read wrote data after resource destruction."; + } else if (rv != PP_OK) { + return ReportError("FileIO::Read", rv); + } + } + + // Abort |Write()|. + { + char buf[3] = { 0 }; + { + pp::FileIO_Dev file_io; + rv = file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + + callback.reset_run_count(); + rv = file_io.Write(0, buf, sizeof(buf), callback); + } // Destroy |file_io|. + if (rv == PP_ERROR_WOULDBLOCK) { + rv = callback.WaitForResult(); + if (rv != PP_ERROR_ABORTED) + return "FileIO::Write not aborted."; + } else if (rv != PP_OK) { + return ReportError("FileIO::Write", rv); + } + } + + // Abort |SetLength()|. + { + { + pp::FileIO_Dev file_io; + rv = file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + + callback.reset_run_count(); + rv = file_io.SetLength(3, callback); + } // Destroy |file_io|. + if (rv == PP_ERROR_WOULDBLOCK) { + rv = callback.WaitForResult(); + if (rv != PP_ERROR_ABORTED) + return "FileIO::SetLength not aborted."; + } else if (rv != PP_OK) { + return ReportError("FileIO::SetLength", rv); + } + } + + // Abort |Flush()|. + { + { + pp::FileIO_Dev file_io; + rv = file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + + callback.reset_run_count(); + rv = file_io.Flush(callback); + } // Destroy |file_io|. + if (rv == PP_ERROR_WOULDBLOCK) { + rv = callback.WaitForResult(); + if (rv != PP_ERROR_ABORTED) + return "FileIO::Flush not aborted."; + } else if (rv != PP_OK) { + return ReportError("FileIO::Flush", rv); + } + } + PASS(); } diff --git a/ppapi/tests/test_file_io.h b/ppapi/tests/test_file_io.h index c641c14..0140824 100644 --- a/ppapi/tests/test_file_io.h +++ b/ppapi/tests/test_file_io.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -21,6 +21,7 @@ class TestFileIO : public TestCase { std::string TestOpen(); std::string TestReadWriteSetLength(); std::string TestTouchQuery(); + std::string TestAbortCalls(); }; #endif // PAPPI_TESTS_TEST_FILE_IO_H_ diff --git a/webkit/plugins/ppapi/ppb_file_io_impl.cc b/webkit/plugins/ppapi/ppb_file_io_impl.cc index 4597809..3067e94 100644 --- a/webkit/plugins/ppapi/ppb_file_io_impl.cc +++ b/webkit/plugins/ppapi/ppb_file_io_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -43,7 +43,8 @@ int32_t Open(PP_Resource file_io_id, PP_Resource file_ref_id, int32_t open_flags, PP_CompletionCallback callback) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; @@ -58,7 +59,8 @@ int32_t Open(PP_Resource file_io_id, int32_t Query(PP_Resource file_io_id, PP_FileInfo_Dev* info, PP_CompletionCallback callback) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Query(info, callback); @@ -68,7 +70,8 @@ int32_t Touch(PP_Resource file_io_id, PP_Time last_access_time, PP_Time last_modified_time, PP_CompletionCallback callback) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Touch(last_access_time, last_modified_time, callback); @@ -79,7 +82,8 @@ int32_t Read(PP_Resource file_io_id, char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Read(offset, buffer, bytes_to_read, callback); @@ -90,7 +94,8 @@ int32_t Write(PP_Resource file_io_id, const char* buffer, int32_t bytes_to_write, PP_CompletionCallback callback) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Write(offset, buffer, bytes_to_write, callback); @@ -99,7 +104,8 @@ int32_t Write(PP_Resource file_io_id, int32_t SetLength(PP_Resource file_io_id, int64_t length, PP_CompletionCallback callback) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->SetLength(length, callback); @@ -107,14 +113,16 @@ int32_t SetLength(PP_Resource file_io_id, int32_t Flush(PP_Resource file_io_id, PP_CompletionCallback callback) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Flush(callback); } void Close(PP_Resource file_io_id) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return; file_io->Close(); @@ -134,7 +142,8 @@ const PPB_FileIO_Dev ppb_fileio = { }; int32_t GetOSFileDescriptor(PP_Resource file_io_id) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->GetOSFileDescriptor(); @@ -144,7 +153,8 @@ int32_t WillWrite(PP_Resource file_io_id, int64_t offset, int32_t bytes_to_write, PP_CompletionCallback callback) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->WillWrite(offset, bytes_to_write, callback); @@ -153,7 +163,8 @@ int32_t WillWrite(PP_Resource file_io_id, int32_t WillSetLength(PP_Resource file_io_id, int64_t length, PP_CompletionCallback callback) { - scoped_refptr<PPB_FileIO_Impl> file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); + scoped_refptr<PPB_FileIO_Impl> + file_io(Resource::GetAs<PPB_FileIO_Impl>(file_io_id)); if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->WillSetLength(length, callback); @@ -219,11 +230,9 @@ PPB_FileIO_Impl* PPB_FileIO_Impl::AsPPB_FileIO_Impl() { int32_t PPB_FileIO_Impl::Open(PPB_FileRef_Impl* file_ref, int32_t open_flags, PP_CompletionCallback callback) { - if (file_ != base::kInvalidPlatformFileValue) - return PP_ERROR_FAILED; - - DCHECK(!callback_.func); - callback_ = callback; + int32_t rv = CommonCallValidation(false, callback); + if (rv != PP_OK) + return rv; int flags = 0; if (open_flags & PP_FILEOPENFLAG_READ) @@ -241,28 +250,31 @@ int32_t PPB_FileIO_Impl::Open(PPB_FileRef_Impl* file_ref, flags |= base::PLATFORM_FILE_CREATE; else flags |= base::PLATFORM_FILE_OPEN_ALWAYS; - } else + } else { flags |= base::PLATFORM_FILE_OPEN; + } file_system_type_ = file_ref->GetFileSystemType(); if (!delegate_->AsyncOpenFile( file_ref->GetSystemPath(), flags, - callback_factory_.NewCallback(&PPB_FileIO_Impl::AsyncOpenFileCallback))) + callback_factory_.NewCallback( + &PPB_FileIO_Impl::AsyncOpenFileCallback))) return PP_ERROR_FAILED; + RegisterCallback(callback); return PP_ERROR_WOULDBLOCK; } int32_t PPB_FileIO_Impl::Query(PP_FileInfo_Dev* info, PP_CompletionCallback callback) { - if (file_ == base::kInvalidPlatformFileValue) - return PP_ERROR_FAILED; + int32_t rv = CommonCallValidation(true, callback); + if (rv != PP_OK) + return rv; - DCHECK(!callback_.func); - callback_ = callback; + if (!info) + return PP_ERROR_BADARGUMENT; - DCHECK(!info_); - DCHECK(info); + DCHECK(!info_); // If |info_|, a callback should be pending (caught above). info_ = info; if (!base::FileUtilProxy::GetFileInfoFromPlatformFile( @@ -270,17 +282,16 @@ int32_t PPB_FileIO_Impl::Query(PP_FileInfo_Dev* info, callback_factory_.NewCallback(&PPB_FileIO_Impl::QueryInfoCallback))) return PP_ERROR_FAILED; + RegisterCallback(callback); return PP_ERROR_WOULDBLOCK; } int32_t PPB_FileIO_Impl::Touch(PP_Time last_access_time, PP_Time last_modified_time, PP_CompletionCallback callback) { - if (file_ == base::kInvalidPlatformFileValue) - return PP_ERROR_FAILED; - - DCHECK(!callback_.func); - callback_ = callback; + int32_t rv = CommonCallValidation(true, callback); + if (rv != PP_OK) + return rv; if (!base::FileUtilProxy::Touch( delegate_->GetFileThreadMessageLoopProxy(), @@ -289,6 +300,7 @@ int32_t PPB_FileIO_Impl::Touch(PP_Time last_access_time, callback_factory_.NewCallback(&PPB_FileIO_Impl::StatusCallback))) return PP_ERROR_FAILED; + RegisterCallback(callback); return PP_ERROR_WOULDBLOCK; } @@ -296,11 +308,9 @@ int32_t PPB_FileIO_Impl::Read(int64_t offset, char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback) { - if (file_ == base::kInvalidPlatformFileValue) - return PP_ERROR_FAILED; - - DCHECK(!callback_.func); - callback_ = callback; + int32_t rv = CommonCallValidation(true, callback); + if (rv != PP_OK) + return rv; if (!base::FileUtilProxy::Read( delegate_->GetFileThreadMessageLoopProxy(), @@ -308,6 +318,7 @@ int32_t PPB_FileIO_Impl::Read(int64_t offset, callback_factory_.NewCallback(&PPB_FileIO_Impl::ReadWriteCallback))) return PP_ERROR_FAILED; + RegisterCallback(callback); return PP_ERROR_WOULDBLOCK; } @@ -315,11 +326,9 @@ int32_t PPB_FileIO_Impl::Write(int64_t offset, const char* buffer, int32_t bytes_to_write, PP_CompletionCallback callback) { - if (file_ == base::kInvalidPlatformFileValue) - return PP_ERROR_FAILED; - - DCHECK(!callback_.func); - callback_ = callback; + int32_t rv = CommonCallValidation(true, callback); + if (rv != PP_OK) + return rv; if (!base::FileUtilProxy::Write( delegate_->GetFileThreadMessageLoopProxy(), @@ -327,16 +336,15 @@ int32_t PPB_FileIO_Impl::Write(int64_t offset, callback_factory_.NewCallback(&PPB_FileIO_Impl::ReadWriteCallback))) return PP_ERROR_FAILED; + RegisterCallback(callback); return PP_ERROR_WOULDBLOCK; } int32_t PPB_FileIO_Impl::SetLength(int64_t length, PP_CompletionCallback callback) { - if (file_ == base::kInvalidPlatformFileValue) - return PP_ERROR_FAILED; - - DCHECK(!callback_.func); - callback_ = callback; + int32_t rv = CommonCallValidation(true, callback); + if (rv != PP_OK) + return rv; if (!base::FileUtilProxy::Truncate( delegate_->GetFileThreadMessageLoopProxy(), @@ -344,28 +352,30 @@ int32_t PPB_FileIO_Impl::SetLength(int64_t length, callback_factory_.NewCallback(&PPB_FileIO_Impl::StatusCallback))) return PP_ERROR_FAILED; + RegisterCallback(callback); return PP_ERROR_WOULDBLOCK; } int32_t PPB_FileIO_Impl::Flush(PP_CompletionCallback callback) { - if (file_ == base::kInvalidPlatformFileValue) - return PP_ERROR_FAILED; - - DCHECK(!callback_.func); - callback_ = callback; + int32_t rv = CommonCallValidation(true, callback); + if (rv != PP_OK) + return rv; if (!base::FileUtilProxy::Flush( delegate_->GetFileThreadMessageLoopProxy(), file_, callback_factory_.NewCallback(&PPB_FileIO_Impl::StatusCallback))) return PP_ERROR_FAILED; + RegisterCallback(callback); return PP_ERROR_WOULDBLOCK; } void PPB_FileIO_Impl::Close() { - if (file_ != base::kInvalidPlatformFileValue) + if (file_ != base::kInvalidPlatformFileValue) { base::FileUtilProxy::Close( delegate_->GetFileThreadMessageLoopProxy(), file_, NULL); + file_ = base::kInvalidPlatformFileValue; + } } int32_t PPB_FileIO_Impl::GetOSFileDescriptor() { @@ -391,13 +401,42 @@ int32_t PPB_FileIO_Impl::WillSetLength(int64_t length, return PP_OK; } -void PPB_FileIO_Impl::RunPendingCallback(int result) { - if (!callback_.func) - return; +int32_t PPB_FileIO_Impl::CommonCallValidation(bool is_opened, + PP_CompletionCallback callback) { + // Only asynchronous operation is supported. + if (!callback.func) { + NOTIMPLEMENTED(); + return PP_ERROR_BADARGUMENT; + } + + if (is_opened) { + if (file_ == base::kInvalidPlatformFileValue) + return PP_ERROR_FAILED; + } else { + if (file_ != base::kInvalidPlatformFileValue) + return PP_ERROR_FAILED; + } - PP_CompletionCallback callback = {0}; - std::swap(callback, callback_); - PP_RunCompletionCallback(&callback, result); + if (callback_.get() && !callback_->completed()) + return PP_ERROR_INPROGRESS; + + return PP_OK; +} + +void PPB_FileIO_Impl::RegisterCallback(PP_CompletionCallback callback) { + DCHECK(callback.func); + DCHECK(!callback_.get() || callback_->completed()); + + PP_Resource resource_id = GetReferenceNoAddRef(); + CHECK(resource_id); + callback_ = new TrackedCompletionCallback( + module()->GetCallbackTracker(), resource_id, callback); +} + +void PPB_FileIO_Impl::RunPendingCallback(int result) { + scoped_refptr<TrackedCompletionCallback> callback; + callback.swap(callback_); + callback->Run(result); // Will complete abortively if necessary. } void PPB_FileIO_Impl::StatusCallback(base::PlatformFileError error_code) { @@ -427,6 +466,7 @@ void PPB_FileIO_Impl::QueryInfoCallback( else info_->type = PP_FILETYPE_REGULAR; } + info_ = NULL; RunPendingCallback(PlatformFileErrorToPepperError(error_code)); } @@ -440,4 +480,3 @@ void PPB_FileIO_Impl::ReadWriteCallback(base::PlatformFileError error_code, } // namespace ppapi } // namespace webkit - diff --git a/webkit/plugins/ppapi/ppb_file_io_impl.h b/webkit/plugins/ppapi/ppb_file_io_impl.h index be3865e..16da265 100644 --- a/webkit/plugins/ppapi/ppb_file_io_impl.h +++ b/webkit/plugins/ppapi/ppb_file_io_impl.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,11 +8,13 @@ #include "base/basictypes.h" #include "base/file_path.h" #include "base/platform_file.h" +#include "base/ref_counted.h" #include "base/scoped_callback_factory.h" #include "base/scoped_ptr.h" #include "ppapi/c/dev/pp_file_info_dev.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_time.h" +#include "webkit/plugins/ppapi/callbacks.h" #include "webkit/plugins/ppapi/plugin_delegate.h" #include "webkit/plugins/ppapi/resource.h" @@ -72,7 +74,21 @@ class PPB_FileIO_Impl : public Resource { int32_t WillSetLength(int64_t length, PP_CompletionCallback callback); + private: + // Verifies: + // - that |callback| is valid (only nonblocking operation supported); + // - that the file is already opened or not (depending on |is_opened|); and + // - that no callback is already pending. + // Returns |PP_OK| to indicate that everything is valid or |PP_ERROR_...| if + // the call should be aborted and that code returned to the plugin. + int32_t CommonCallValidation(bool is_opened, PP_CompletionCallback callback); + + // Sets up |callback| as the pending callback. This should only be called once + // it is certain that |PP_ERROR_WOULDBLOCK| will be returned. + void RegisterCallback(PP_CompletionCallback callback); + void RunPendingCallback(int result); + void StatusCallback(base::PlatformFileError error_code); void AsyncOpenFileCallback(base::PlatformFileError error_code, base::PlatformFile file); @@ -81,14 +97,17 @@ class PPB_FileIO_Impl : public Resource { void ReadWriteCallback(base::PlatformFileError error_code, int bytes_read_or_written); - private: PluginDelegate* delegate_; base::ScopedCallbackFactory<PPB_FileIO_Impl> callback_factory_; base::PlatformFile file_; PP_FileSystemType_Dev file_system_type_; - PP_CompletionCallback callback_; + // Any pending callback for any PPB_FileIO(Trusted) call taking a callback. + scoped_refptr<TrackedCompletionCallback> callback_; + + // Output buffer pointer for |Query()|; only non-null when a callback is + // pending for it. PP_FileInfo_Dev* info_; DISALLOW_COPY_AND_ASSIGN(PPB_FileIO_Impl); diff --git a/webkit/plugins/ppapi/ppb_flash_impl.cc b/webkit/plugins/ppapi/ppb_flash_impl.cc index 8b1ff6c..8f20203 100644 --- a/webkit/plugins/ppapi/ppb_flash_impl.cc +++ b/webkit/plugins/ppapi/ppb_flash_impl.cc @@ -422,13 +422,16 @@ void PPB_Flash_NetConnector_Impl::CompleteConnectTcp( } } - callback_->Run(rv); // Will complete abortively if necessary. - - // Wipe everything out for safety. - callback_ = NULL; + // Theoretically, the plugin should be allowed to try another |ConnectTcp()| + // from the callback. + scoped_refptr<TrackedCompletionCallback> callback; + callback.swap(callback_); + // Wipe everything else out for safety. socket_out_ = NULL; local_addr_out_ = NULL; remote_addr_out_ = NULL; + + callback->Run(rv); // Will complete abortively if necessary. } } // namespace ppapi |