summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-11 21:58:09 +0000
committerviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-11 21:58:09 +0000
commit39c99eaf84c735cfef1e656f8f0c95362e243de7 (patch)
treebb0de0a2c757786033193c90c38087f83020cab9
parentaa0c7a415c325885592eef57cefa1024aa92d8d4 (diff)
downloadchromium_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.cc205
-rw-r--r--ppapi/tests/test_file_io.h3
-rw-r--r--webkit/plugins/ppapi/ppb_file_io_impl.cc155
-rw-r--r--webkit/plugins/ppapi/ppb_file_io_impl.h25
-rw-r--r--webkit/plugins/ppapi/ppb_flash_impl.cc11
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