Commit b7a490e0 authored by teravest@chromium.org's avatar teravest@chromium.org

Pepper: Delete FileDownloader in trusted plugin.

This simplifies PnaclCoordinator considerably and reduces the total
amount of code in the trusted plugin.

BUG=239656

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=284684

R=dmichael@chromium.org

Review URL: https://codereview.chromium.org/393693004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284961 0039d316-1c4b-4281-b951-d872f2087c98
parent ed6fb985
...@@ -237,28 +237,6 @@ interface PPB_NaCl_Private { ...@@ -237,28 +237,6 @@ interface PPB_NaCl_Private {
/* Return whether the non-SFI mode is enabled. */ /* Return whether the non-SFI mode is enabled. */
PP_Bool IsNonSFIModeEnabled(); PP_Bool IsNonSFIModeEnabled();
/* Create a temporary file, which will be deleted by the time the
* last handle is closed (or earlier on POSIX systems), to use for
* the nexe with the cache information given by |pexe_url|,
* |abi_version|, |opt_level|, and |headers|. If the nexe is already present
* in the cache, |is_hit| is set to PP_TRUE and the contents of the nexe will
* be copied into the temporary file. Otherwise |is_hit| is set to PP_FALSE
* and the temporary file will be writeable. Currently the implementation is
* a stub, which always sets is_hit to false and calls the implementation of
* CreateTemporaryFile. In a subsequent CL it will call into the browser
* which will remember the association between the cache key and the fd, and
* copy the nexe into the cache after the translation finishes.
*/
int32_t GetNexeFd([in] PP_Instance instance,
[in] str_t pexe_url,
[in] uint32_t abi_version,
[in] uint32_t opt_level,
[in] str_t headers,
[in] str_t extra_flags,
[out] PP_Bool is_hit,
[out] PP_FileHandle nexe_handle,
[in] PP_CompletionCallback callback);
/* Report to the browser that translation of the pexe for |instance| /* Report to the browser that translation of the pexe for |instance|
* has finished, or aborted with an error. If |success| is true, the * has finished, or aborted with an error. If |success| is true, the
* browser may then store the translation in the cache. The renderer * browser may then store the translation in the cache. The renderer
...@@ -419,4 +397,18 @@ interface PPB_NaCl_Private { ...@@ -419,4 +397,18 @@ interface PPB_NaCl_Private {
* time. * time.
*/ */
void SetPNaClStartTime([in] PP_Instance instance); void SetPNaClStartTime([in] PP_Instance instance);
/* Downloads and streams a pexe file for PNaCl translation.
* Fetches the content at |pexe_url| for the given instance and opt_level.
* If a translated cached nexe is already available, |cache_hit_handle|
* is set and |cache_hit_callback| is called.
* Otherwise, |stream_callback| is called repeatedly with blocks of data
* as they are received. |stream_finished_callback| is called after all
* data has been received and dispatched to |stream_callback|.
*/
void StreamPexe([in] PP_Instance instance,
[in] str_t pexe_url,
[in] int32_t opt_level,
[in] PPP_PexeStreamHandler stream_handler,
[inout] mem_t stream_handler_user_data);
}; };
/* Copyright 2014 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.
*/
/* This file contains NaCl private interfaces. This interface is not versioned
* and is for internal Chrome use. It may change without notice. */
#inline c
#include "ppapi/c/private/pp_file_handle.h"
#endinl
label Chrome {
M25 = 1.0
};
interface PPP_PexeStreamHandler {
/**
* Invoked as a result of a cache hit for a translated pexe.
*/
void DidCacheHit([inout] mem_t user_data,
[in] PP_FileHandle nexe_file_handle);
/**
* Invoked as a result of a cache miss for a translated pexe.
* Provides the expected length of the pexe, as read from HTTP headers.
*/
void DidCacheMiss([inout] mem_t user_data,
[in] int64_t expected_total_length);
/**
* Invoked when a block of data has been downloaded.
* Only invoked after DidCacheMiss().
*/
void DidStreamData([inout] mem_t user_data,
[in] mem_t data,
[in] int32_t length);
/**
* Invoked when the stream has finished downloading, regardless of whether it
* succeeded. Not invoked if DidCacheHit() was called.
*/
void DidFinishStream([inout] mem_t user_data,
[in] int32_t pp_error);
};
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* found in the LICENSE file. * found in the LICENSE file.
*/ */
/* From private/ppb_nacl_private.idl modified Wed Jul 9 11:09:04 2014. */ /* From private/ppb_nacl_private.idl modified Thu Jul 10 10:34:30 2014. */
#ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ #ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
#define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ #define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "ppapi/c/pp_macros.h" #include "ppapi/c/pp_macros.h"
#include "ppapi/c/pp_stdint.h" #include "ppapi/c/pp_stdint.h"
#include "ppapi/c/pp_var.h" #include "ppapi/c/pp_var.h"
#include "ppapi/c/private/ppp_pexe_stream_handler.h"
#define PPB_NACL_PRIVATE_INTERFACE_1_0 "PPB_NaCl_Private;1.0" #define PPB_NACL_PRIVATE_INTERFACE_1_0 "PPB_NaCl_Private;1.0"
#define PPB_NACL_PRIVATE_INTERFACE PPB_NACL_PRIVATE_INTERFACE_1_0 #define PPB_NACL_PRIVATE_INTERFACE PPB_NACL_PRIVATE_INTERFACE_1_0
...@@ -270,27 +271,6 @@ struct PPB_NaCl_Private_1_0 { ...@@ -270,27 +271,6 @@ struct PPB_NaCl_Private_1_0 {
int32_t (*GetNumberOfProcessors)(void); int32_t (*GetNumberOfProcessors)(void);
/* Return whether the non-SFI mode is enabled. */ /* Return whether the non-SFI mode is enabled. */
PP_Bool (*IsNonSFIModeEnabled)(void); PP_Bool (*IsNonSFIModeEnabled)(void);
/* Create a temporary file, which will be deleted by the time the
* last handle is closed (or earlier on POSIX systems), to use for
* the nexe with the cache information given by |pexe_url|,
* |abi_version|, |opt_level|, and |headers|. If the nexe is already present
* in the cache, |is_hit| is set to PP_TRUE and the contents of the nexe will
* be copied into the temporary file. Otherwise |is_hit| is set to PP_FALSE
* and the temporary file will be writeable. Currently the implementation is
* a stub, which always sets is_hit to false and calls the implementation of
* CreateTemporaryFile. In a subsequent CL it will call into the browser
* which will remember the association between the cache key and the fd, and
* copy the nexe into the cache after the translation finishes.
*/
int32_t (*GetNexeFd)(PP_Instance instance,
const char* pexe_url,
uint32_t abi_version,
uint32_t opt_level,
const char* headers,
const char* extra_flags,
PP_Bool* is_hit,
PP_FileHandle* nexe_handle,
struct PP_CompletionCallback callback);
/* Report to the browser that translation of the pexe for |instance| /* Report to the browser that translation of the pexe for |instance|
* has finished, or aborted with an error. If |success| is true, the * has finished, or aborted with an error. If |success| is true, the
* browser may then store the translation in the cache. The renderer * browser may then store the translation in the cache. The renderer
...@@ -416,6 +396,19 @@ struct PPB_NaCl_Private_1_0 { ...@@ -416,6 +396,19 @@ struct PPB_NaCl_Private_1_0 {
* time. * time.
*/ */
void (*SetPNaClStartTime)(PP_Instance instance); void (*SetPNaClStartTime)(PP_Instance instance);
/* Downloads and streams a pexe file for PNaCl translation.
* Fetches the content at |pexe_url| for the given instance and opt_level.
* If a translated cached nexe is already available, |cache_hit_handle|
* is set and |cache_hit_callback| is called.
* Otherwise, |stream_callback| is called repeatedly with blocks of data
* as they are received. |stream_finished_callback| is called after all
* data has been received and dispatched to |stream_callback|.
*/
void (*StreamPexe)(PP_Instance instance,
const char* pexe_url,
int32_t opt_level,
const struct PPP_PexeStreamHandler_1_0* stream_handler,
void* stream_handler_user_data);
}; };
typedef struct PPB_NaCl_Private_1_0 PPB_NaCl_Private; typedef struct PPB_NaCl_Private_1_0 PPB_NaCl_Private;
......
/* Copyright 2014 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.
*/
/* From private/ppp_pexe_stream_handler.idl,
* modified Thu Jul 10 11:05:31 2014.
*/
#ifndef PPAPI_C_PRIVATE_PPP_PEXE_STREAM_HANDLER_H_
#define PPAPI_C_PRIVATE_PPP_PEXE_STREAM_HANDLER_H_
#include "ppapi/c/pp_macros.h"
#include "ppapi/c/pp_stdint.h"
#define PPP_PEXESTREAMHANDLER_INTERFACE_1_0 "PPP_PexeStreamHandler;1.0"
#define PPP_PEXESTREAMHANDLER_INTERFACE PPP_PEXESTREAMHANDLER_INTERFACE_1_0
/**
* @file
* This file contains NaCl private interfaces. This interface is not versioned
* and is for internal Chrome use. It may change without notice. */
#include "ppapi/c/private/pp_file_handle.h"
/**
* @addtogroup Interfaces
* @{
*/
struct PPP_PexeStreamHandler_1_0 {
/**
* Invoked as a result of a cache hit for a translated pexe.
*/
void (*DidCacheHit)(void* user_data, PP_FileHandle nexe_file_handle);
/**
* Invoked as a result of a cache miss for a translated pexe.
* Provides the expected length of the pexe, as read from HTTP headers.
*/
void (*DidCacheMiss)(void* user_data, int64_t expected_total_length);
/**
* Invoked when a block of data has been downloaded.
* Only invoked after DidCacheMiss().
*/
void (*DidStreamData)(void* user_data, const void* data, int32_t length);
/**
* Invoked when the stream has finished downloading, regardless of whether it
* succeeded. Not invoked if DidCacheHit() was called.
*/
void (*DidFinishStream)(void* user_data, int32_t pp_error);
};
typedef struct PPP_PexeStreamHandler_1_0 PPP_PexeStreamHandler;
/**
* @}
*/
#endif /* PPAPI_C_PRIVATE_PPP_PEXE_STREAM_HANDLER_H_ */
// Copyright (c) 2012 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.
#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_CALLBACK_SOURCE_H
#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_CALLBACK_SOURCE_H
#include "ppapi/cpp/completion_callback.h"
namespace plugin {
// Classes that implement this interface can be used with FileDownloader's
// DOWNLOAD_STREAM mode. For each chunk of the file as it downloads,
// The FileDownloader will get a callback of type
// pp::CompletionCallbackWithOutput<std::vector<char>*> using the
// GetCallback function, and call it immediately, passing a pointer to a
// vector with the data as the output field. The class is templatized just
// in case there are any other use cases in the future.
// This class really only exists as a way to get callbacks
// bound to an object (i.e. we don't need the asynchronous behavior of PPAPI)
// All we really need is tr1::function or base::bind or some such, but we don't
// have those in the plugin.
template<class T>
class CallbackSource {
public:
virtual ~CallbackSource();
// Returns a callback from callback_factory's NewCallbackWithOutput,
// bound to the implementing object.
virtual pp::CompletionCallbackWithOutput<T> GetCallback() = 0;
};
}
#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_CALLBACK_SOURCE_H
// Copyright (c) 2012 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/native_client/src/trusted/plugin/file_downloader.h"
#include <stdio.h>
#include <string.h>
#include <string>
#include "native_client/src/include/portability_io.h"
#include "native_client/src/shared/platform/nacl_check.h"
#include "native_client/src/shared/platform/nacl_time.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/cpp/url_request_info.h"
#include "ppapi/cpp/url_response_info.h"
#include "ppapi/native_client/src/trusted/plugin/callback_source.h"
#include "ppapi/native_client/src/trusted/plugin/plugin.h"
#include "ppapi/native_client/src/trusted/plugin/utility.h"
namespace plugin {
FileDownloader::FileDownloader(Plugin* instance)
: instance_(instance),
file_open_notify_callback_(pp::BlockUntilComplete()),
stream_finish_callback_(pp::BlockUntilComplete()),
mode_(DOWNLOAD_NONE),
data_stream_callback_source_(NULL) {
callback_factory_.Initialize(this);
temp_buffer_.resize(kTempBufferSize);
}
bool FileDownloader::OpenStream(
const nacl::string& url,
const pp::CompletionCallback& callback,
StreamCallbackSource* stream_callback_source) {
data_stream_callback_source_ = stream_callback_source;
PLUGIN_PRINTF(("FileDownloader::Open (url=%s)\n", url.c_str()));
if (callback.pp_completion_callback().func == NULL || instance_ == NULL)
return false;
status_code_ = -1;
file_open_notify_callback_ = callback;
mode_ = DOWNLOAD_TO_BUFFER_AND_STREAM;
pp::URLRequestInfo url_request(instance_);
// Allow CORS.
// Note that "SetAllowCrossOriginRequests" (currently) has the side effect of
// preventing credentials from being sent on same-origin requests. We
// therefore avoid setting this flag unless we know for sure it is a
// cross-origin request, resulting in behavior similar to XMLHttpRequest.
if (!instance_->DocumentCanRequest(url))
url_request.SetAllowCrossOriginRequests(true);
if (!extra_request_headers_.empty())
url_request.SetHeaders(extra_request_headers_);
// Reset the url loader and file reader.
// Note that we have the only reference to the underlying objects, so
// this will implicitly close any pending IO and destroy them.
url_loader_ = pp::URLLoader(instance_);
url_request.SetRecordDownloadProgress(true);
// Prepare the url request.
url_request.SetURL(url);
// Request asynchronous download of the url providing an on-load callback.
// As long as this step is guaranteed to be asynchronous, we can call
// synchronously all other internal callbacks that eventually result in the
// invocation of the user callback. The user code will not be reentered.
pp::CompletionCallback onload_callback =
callback_factory_.NewCallback(&FileDownloader::URLLoadStartNotify);
int32_t pp_error = url_loader_.Open(url_request, onload_callback);
PLUGIN_PRINTF(("FileDownloader::Open (pp_error=%" NACL_PRId32 ")\n",
pp_error));
CHECK(pp_error == PP_OK_COMPLETIONPENDING);
return true;
}
bool FileDownloader::InitialResponseIsValid() {
// Process the response, validating the headers to confirm successful loading.
url_response_ = url_loader_.GetResponseInfo();
if (url_response_.is_null()) {
PLUGIN_PRINTF((
"FileDownloader::InitialResponseIsValid (url_response_=NULL)\n"));
return false;
}
pp::Var full_url = url_response_.GetURL();
if (!full_url.is_string()) {
PLUGIN_PRINTF((
"FileDownloader::InitialResponseIsValid (url is not a string)\n"));
return false;
}
full_url_ = full_url.AsString();
status_code_ = url_response_.GetStatusCode();
PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid ("
"response status_code=%" NACL_PRId32 ")\n", status_code_));
return status_code_ == NACL_HTTP_STATUS_OK;
}
void FileDownloader::URLLoadStartNotify(int32_t pp_error) {
PLUGIN_PRINTF(("FileDownloader::URLLoadStartNotify (pp_error=%"
NACL_PRId32")\n", pp_error));
if (pp_error != PP_OK) {
file_open_notify_callback_.RunAndClear(pp_error);
return;
}
if (!InitialResponseIsValid()) {
file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED);
return;
}
file_open_notify_callback_.RunAndClear(PP_OK);
}
void FileDownloader::BeginStreaming(
const pp::CompletionCallback& callback) {
stream_finish_callback_ = callback;
// Finish streaming the body providing an optional callback.
pp::CompletionCallback onread_callback =
callback_factory_.NewOptionalCallback(
&FileDownloader::URLReadBodyNotify);
int32_t temp_size = static_cast<int32_t>(temp_buffer_.size());
int32_t pp_error = url_loader_.ReadResponseBody(&temp_buffer_[0],
temp_size,
onread_callback);
if (pp_error != PP_OK_COMPLETIONPENDING)
onread_callback.RunAndClear(pp_error);
}
void FileDownloader::URLReadBodyNotify(int32_t pp_error) {
PLUGIN_PRINTF(("FileDownloader::URLReadBodyNotify (pp_error=%"
NACL_PRId32")\n", pp_error));
if (pp_error < PP_OK) {
stream_finish_callback_.RunAndClear(pp_error);
} else if (pp_error == PP_OK) {
data_stream_callback_source_->GetCallback().RunAndClear(PP_OK);
stream_finish_callback_.RunAndClear(PP_OK);
} else {
PLUGIN_PRINTF(("Running data_stream_callback, temp_buffer_=%p\n",
&temp_buffer_[0]));
StreamCallback cb = data_stream_callback_source_->GetCallback();
*(cb.output()) = &temp_buffer_;
cb.RunAndClear(pp_error);
pp::CompletionCallback onread_callback =
callback_factory_.NewOptionalCallback(
&FileDownloader::URLReadBodyNotify);
int32_t temp_size = static_cast<int32_t>(temp_buffer_.size());
pp_error = url_loader_.ReadResponseBody(&temp_buffer_[0],
temp_size,
onread_callback);
if (pp_error != PP_OK_COMPLETIONPENDING)
onread_callback.RunAndClear(pp_error);
}
}
bool FileDownloader::GetDownloadProgress(
int64_t* bytes_received,
int64_t* total_bytes_to_be_received) const {
return url_loader_.GetDownloadProgress(bytes_received,
total_bytes_to_be_received);
}
nacl::string FileDownloader::GetResponseHeaders() const {
pp::Var headers = url_response_.GetHeaders();
if (!headers.is_string()) {
PLUGIN_PRINTF((
"FileDownloader::GetResponseHeaders (headers are not a string)\n"));
return nacl::string();
}
return headers.AsString();
}
} // namespace plugin
// Copyright (c) 2012 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.
#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
#include <deque>
#include "native_client/src/include/nacl_macros.h"
#include "native_client/src/include/nacl_string.h"
#include "native_client/src/public/nacl_file_info.h"
#include "ppapi/c/private/ppb_nacl_private.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/url_loader.h"
#include "ppapi/cpp/url_response_info.h"
#include "ppapi/native_client/src/trusted/plugin/callback_source.h"
#include "ppapi/utility/completion_callback_factory.h"
namespace plugin {
class Plugin;
typedef enum {
DOWNLOAD_TO_BUFFER_AND_STREAM = 0,
DOWNLOAD_NONE
} DownloadMode;
typedef std::vector<char>* FileStreamData;
typedef CallbackSource<FileStreamData> StreamCallbackSource;
typedef pp::CompletionCallbackWithOutput<FileStreamData> StreamCallback;
// A class that wraps PPAPI URLLoader and FileIO functionality for downloading
// the url into a file and providing an open file descriptor.
class FileDownloader {
public:
explicit FileDownloader(Plugin* instance);
~FileDownloader() {}
// Issues a GET on |url| to start downloading the response into a file,
// and finish streaming it. |callback| will be run after streaming is
// done or if an error prevents streaming from completing.
// Returns true when callback is scheduled to be called on success or failure.
// Returns false if callback is NULL, or if the PPB_FileIO_Trusted interface
// is not available.
// If |record_progress| is true, then download progress will be recorded,
// and can be polled through GetDownloadProgress().
// If |progress_callback| is not NULL and |record_progress| is true,
// then the callback will be invoked for every progress update received
// by the loader.
// Similar to Open(), but used for streaming the |url| data directly to the
// caller without writing to a temporary file. The callbacks provided by
// |stream_callback_source| are expected to copy the data before returning.
// |callback| is called once the response headers are received,
// and streaming must be completed separately via BeginStreaming().
bool OpenStream(const nacl::string& url,
const pp::CompletionCallback& callback,
StreamCallbackSource* stream_callback_source);
// Finish streaming the response body for a URL request started by either
// OpenStream(). Runs the given |callback| when streaming is done.
void BeginStreaming(const pp::CompletionCallback& callback);
// Once the GET request has finished, and the contents of the file
// represented by |url_| are available, |full_url_| is the full URL including
// the scheme, host and full path.
// Returns an empty string before the GET request has finished.
const nacl::string& full_url() const { return full_url_; }
// GetDownloadProgress() returns the current download progress, which is
// meaningful after Open() has been called. Progress only refers to the
// response body and does not include the headers.
//
// This data is only available if the |record_progress| true in the
// Open() call. If progress is being recorded, then |bytes_received|
// will be set to the number of bytes received thus far,
// and |total_bytes_to_be_received| will be set to the total number
// of bytes to be received. The total bytes to be received may be unknown,
// in which case |total_bytes_to_be_received| will be set to -1.
bool GetDownloadProgress(int64_t* bytes_received,
int64_t* total_bytes_to_be_received) const;
int status_code() const { return status_code_; }
nacl::string GetResponseHeaders() const;
void set_request_headers(const nacl::string& extra_request_headers) {
extra_request_headers_ = extra_request_headers;
}
private:
NACL_DISALLOW_COPY_AND_ASSIGN(FileDownloader);
// For DOWNLOAD_TO_BUFFER_AND_STREAM, the process is very similar:
// 1) Ask the browser to start streaming |url_| to an internal buffer.
// 2) Ask the browser to finish streaming to |temp_buffer_| on success.
// 3) Wait for streaming to finish, passing the data directly to the user.
// Each step is done asynchronously using callbacks. We create callbacks
// through a factory to take advantage of ref-counting.
// The public Open*() functions start step 1), and the public BeginStreaming
// function proceeds to step 2) and 3).
bool InitialResponseIsValid();
void URLLoadStartNotify(int32_t pp_error);
void URLReadBodyNotify(int32_t pp_error);
Plugin* instance_;
nacl::string full_url_;
nacl::string extra_request_headers_;
pp::URLResponseInfo url_response_;
pp::CompletionCallback file_open_notify_callback_;
pp::CompletionCallback stream_finish_callback_;
pp::URLLoader url_loader_;
pp::CompletionCallbackFactory<FileDownloader> callback_factory_;
int32_t status_code_;
DownloadMode mode_;
static const uint32_t kTempBufferSize = 16384;
std::vector<char> temp_buffer_;
StreamCallbackSource* data_stream_callback_source_;
};
} // namespace plugin
#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
'variables': { 'variables': {
'chromium_code': 1, # Use higher warning level. 'chromium_code': 1, # Use higher warning level.
'common_sources': [ 'common_sources': [
'file_downloader.cc',
'module_ppapi.cc', 'module_ppapi.cc',
'nacl_subprocess.cc', 'nacl_subprocess.cc',
'plugin.cc', 'plugin.cc',
......
...@@ -28,12 +28,13 @@ ...@@ -28,12 +28,13 @@
#include "ppapi/cpp/var.h" #include "ppapi/cpp/var.h"
#include "ppapi/cpp/view.h" #include "ppapi/cpp/view.h"
#include "ppapi/native_client/src/trusted/plugin/file_downloader.h"
#include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h"
#include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h"
#include "ppapi/native_client/src/trusted/plugin/service_runtime.h" #include "ppapi/native_client/src/trusted/plugin/service_runtime.h"
#include "ppapi/native_client/src/trusted/plugin/utility.h" #include "ppapi/native_client/src/trusted/plugin/utility.h"
#include "ppapi/utility/completion_callback_factory.h"
namespace nacl { namespace nacl {
class DescWrapper; class DescWrapper;
class DescWrapperFactory; class DescWrapperFactory;
......
...@@ -17,12 +17,12 @@ ...@@ -17,12 +17,12 @@
#include "ppapi/cpp/completion_callback.h" #include "ppapi/cpp/completion_callback.h"
#include "ppapi/native_client/src/trusted/plugin/callback_source.h"
#include "ppapi/native_client/src/trusted/plugin/file_downloader.h"
#include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h"
#include "ppapi/native_client/src/trusted/plugin/plugin_error.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
#include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h"
#include "ppapi/utility/completion_callback_factory.h"
struct PP_PNaClOptions; struct PP_PNaClOptions;
namespace plugin { namespace plugin {
...@@ -51,7 +51,7 @@ class TempFile; ...@@ -51,7 +51,7 @@ class TempFile;
// Translation proceeds in two steps: // Translation proceeds in two steps:
// (1) llc translates the bitcode in pexe_url_ to an object in obj_file_. // (1) llc translates the bitcode in pexe_url_ to an object in obj_file_.
// (2) ld links the object code in obj_file_ and produces a nexe in nexe_file_. // (2) ld links the object code in obj_file_ and produces a nexe in nexe_file_.
class PnaclCoordinator: public CallbackSource<FileStreamData> { class PnaclCoordinator {
public: public:
// Maximum number of object files passable to the translator. Cannot be // Maximum number of object files passable to the translator. Cannot be
// changed without changing the RPC signatures. // changed without changing the RPC signatures.
...@@ -69,12 +69,6 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { ...@@ -69,12 +69,6 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
// BitcodeToNative has completed (and the finish_callback called). // BitcodeToNative has completed (and the finish_callback called).
PP_FileHandle TakeTranslatedFileHandle(); PP_FileHandle TakeTranslatedFileHandle();
// Implement FileDownloader's template of the CallbackSource interface.
// This method returns a callback which will be called by the FileDownloader
// to stream the bitcode data as it arrives. The callback
// (BitcodeStreamGotData) passes it to llc over SRPC.
StreamCallback GetCallback();
// Return a callback that should be notified when |bytes_compiled| bytes // Return a callback that should be notified when |bytes_compiled| bytes
// have been compiled. // have been compiled.
pp::CompletionCallback GetCompileProgressCallback(int64_t bytes_compiled); pp::CompletionCallback GetCompileProgressCallback(int64_t bytes_compiled);
...@@ -92,6 +86,16 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { ...@@ -92,6 +86,16 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
expected_pexe_size_) < kProgressEventSlopPct; expected_pexe_size_) < kProgressEventSlopPct;
} }
void BitcodeStreamCacheHit(PP_FileHandle handle);
void BitcodeStreamCacheMiss(int64_t expected_pexe_size);
// Invoked when a pexe data chunk arrives (when using streaming translation)
void BitcodeStreamGotData(const void* data, int32_t length);
// Invoked when the pexe download finishes (using streaming translation)
void BitcodeStreamDidFinish(int32_t pp_error);
private: private:
NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator);
...@@ -104,19 +108,9 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { ...@@ -104,19 +108,9 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
// Invoke to issue a GET request for bitcode. // Invoke to issue a GET request for bitcode.
void OpenBitcodeStream(); void OpenBitcodeStream();
// Invoked when we've started an URL fetch for the pexe to check for
// caching metadata.
void BitcodeStreamDidOpen(int32_t pp_error);
// Invoked when we've gotten a temp FD for the nexe, either with the nexe
// data, or a writeable fd to save to.
void NexeFdDidOpen(int32_t pp_error);
// Invoked when a pexe data chunk arrives (when using streaming translation)
void BitcodeStreamGotData(int32_t pp_error, FileStreamData data);
// Invoked when a pexe data chunk is compiled. // Invoked when a pexe data chunk is compiled.
void BitcodeGotCompiled(int32_t pp_error, int64_t bytes_compiled); void BitcodeGotCompiled(int32_t pp_error, int64_t bytes_compiled);
// Invoked when the pexe download finishes (using streaming translation)
void BitcodeStreamDidFinish(int32_t pp_error);
// Once llc and ld nexes have been loaded and the two temporary files have // Once llc and ld nexes have been loaded and the two temporary files have
// been created, this starts the translation. Translation starts two // been created, this starts the translation. Translation starts two
// subprocesses, one for llc and one for ld. // subprocesses, one for llc and one for ld.
...@@ -180,12 +174,6 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { ...@@ -180,12 +174,6 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
// Translated nexe file, produced by the linker. // Translated nexe file, produced by the linker.
nacl::scoped_ptr<TempFile> temp_nexe_file_; nacl::scoped_ptr<TempFile> temp_nexe_file_;
// Passed to the browser, which sets it to true if there is a translation
// cache hit.
PP_Bool is_cache_hit_;
// Downloader for streaming translation
nacl::scoped_ptr<FileDownloader> streaming_downloader_;
// Used to report information when errors (PPAPI or otherwise) are reported. // Used to report information when errors (PPAPI or otherwise) are reported.
ErrorInfo error_info_; ErrorInfo error_info_;
......
...@@ -111,27 +111,15 @@ void PnaclTranslateThread::RunTranslate( ...@@ -111,27 +111,15 @@ void PnaclTranslateThread::RunTranslate(
} }
// Called from main thread to send bytes to the translator. // Called from main thread to send bytes to the translator.
void PnaclTranslateThread::PutBytes(std::vector<char>* bytes, int count) { void PnaclTranslateThread::PutBytes(const void* bytes, int32_t count) {
PLUGIN_PRINTF(("PutBytes (this=%p, bytes=%p, size=%" NACL_PRIuS
", count=%d)\n",
this, bytes, bytes ? bytes->size() : 0, count));
size_t buffer_size = 0;
CHECK(bytes != NULL); CHECK(bytes != NULL);
// Ensure that the buffer we send to the translation thread is the right size
// (count can be < the buffer size). This can be done without the lock.
buffer_size = bytes->size();
bytes->resize(count);
NaClXMutexLock(&cond_mu_); NaClXMutexLock(&cond_mu_);
data_buffers_.push_back(std::vector<char>()); data_buffers_.push_back(std::vector<char>());
bytes->swap(data_buffers_.back()); // Avoid copying the buffer data. data_buffers_.back().insert(data_buffers_.back().end(),
static_cast<const char*>(bytes),
static_cast<const char*>(bytes) + count);
NaClXCondVarSignal(&buffer_cond_); NaClXCondVarSignal(&buffer_cond_);
NaClXMutexUnlock(&cond_mu_); NaClXMutexUnlock(&cond_mu_);
// Ensure the buffer we send back to the coordinator is the expected size
bytes->resize(buffer_size);
} }
void PnaclTranslateThread::EndStream() { void PnaclTranslateThread::EndStream() {
......
...@@ -61,7 +61,7 @@ class PnaclTranslateThread { ...@@ -61,7 +61,7 @@ class PnaclTranslateThread {
void AbortSubprocesses(); void AbortSubprocesses();
// Send bitcode bytes to the translator. Called from the main thread. // Send bitcode bytes to the translator. Called from the main thread.
void PutBytes(std::vector<char>* data, int count); void PutBytes(const void* data, int count);
// Notify the translator that the end of the bitcode stream has been reached. // Notify the translator that the end of the bitcode stream has been reached.
// Called from the main thread. // Called from the main thread.
...@@ -69,6 +69,9 @@ class PnaclTranslateThread { ...@@ -69,6 +69,9 @@ class PnaclTranslateThread {
int64_t GetCompileTime() const { return compile_time_; } int64_t GetCompileTime() const { return compile_time_; }
// Returns true if RunTranslate() has been called, false otherwise.
bool started() const { return plugin_ != NULL; }
private: private:
// Helper thread entry point for translation. Takes a pointer to // Helper thread entry point for translation. Takes a pointer to
// PnaclTranslateThread and calls DoTranslate(). // PnaclTranslateThread and calls DoTranslate().
......
...@@ -18,20 +18,13 @@ ...@@ -18,20 +18,13 @@
namespace plugin { namespace plugin {
TempFile::TempFile(Plugin* plugin) : plugin_(plugin), TempFile::TempFile(Plugin* plugin, PP_FileHandle handle)
internal_handle_(PP_kInvalidFileHandle) { : plugin_(plugin),
} internal_handle_(handle) { }
TempFile::~TempFile() { } TempFile::~TempFile() { }
int32_t TempFile::Open(bool writeable) { int32_t TempFile::Open(bool writeable) {
// TODO(teravest): Clean up this Open() behavior; this is really confusing as
// written.
if (internal_handle_ == PP_kInvalidFileHandle) {
internal_handle_ =
plugin_->nacl_interface()->CreateTemporaryFile(plugin_->pp_instance());
}
if (internal_handle_ == PP_kInvalidFileHandle) { if (internal_handle_ == PP_kInvalidFileHandle) {
PLUGIN_PRINTF(("TempFile::Open failed w/ PP_kInvalidFileHandle\n")); PLUGIN_PRINTF(("TempFile::Open failed w/ PP_kInvalidFileHandle\n"));
return PP_ERROR_FAILED; return PP_ERROR_FAILED;
......
...@@ -36,7 +36,7 @@ class Plugin; ...@@ -36,7 +36,7 @@ class Plugin;
class TempFile { class TempFile {
public: public:
// Create a TempFile. // Create a TempFile.
explicit TempFile(Plugin* plugin); TempFile(Plugin* plugin, PP_FileHandle handle);
~TempFile(); ~TempFile();
// Opens a temporary file object and descriptor wrapper referring to the file. // Opens a temporary file object and descriptor wrapper referring to the file.
...@@ -55,9 +55,6 @@ class TempFile { ...@@ -55,9 +55,6 @@ class TempFile {
// and all wrappers. // and all wrappers.
PP_FileHandle TakeFileHandle(); PP_FileHandle TakeFileHandle();
// Used by GetNexeFd() to set the underlying internal handle.
PP_FileHandle* internal_handle() { return &internal_handle_; }
private: private:
NACL_DISALLOW_COPY_AND_ASSIGN(TempFile); NACL_DISALLOW_COPY_AND_ASSIGN(TempFile);
......
...@@ -3322,11 +3322,6 @@ static PP_Bool Pnacl_M25_PPB_NaCl_Private_IsNonSFIModeEnabled(void) { ...@@ -3322,11 +3322,6 @@ static PP_Bool Pnacl_M25_PPB_NaCl_Private_IsNonSFIModeEnabled(void) {
return iface->IsNonSFIModeEnabled(); return iface->IsNonSFIModeEnabled();
} }
static int32_t Pnacl_M25_PPB_NaCl_Private_GetNexeFd(PP_Instance instance, const char* pexe_url, uint32_t abi_version, uint32_t opt_level, const char* headers, const char* extra_flags, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback* callback) {
const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
return iface->GetNexeFd(instance, pexe_url, abi_version, opt_level, headers, extra_flags, is_hit, nexe_handle, *callback);
}
static void Pnacl_M25_PPB_NaCl_Private_ReportTranslationFinished(PP_Instance instance, PP_Bool success, int32_t opt_level, int64_t pexe_size, int64_t compile_time_us) { static void Pnacl_M25_PPB_NaCl_Private_ReportTranslationFinished(PP_Instance instance, PP_Bool success, int32_t opt_level, int64_t pexe_size, int64_t compile_time_us) {
const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
iface->ReportTranslationFinished(instance, success, opt_level, pexe_size, compile_time_us); iface->ReportTranslationFinished(instance, success, opt_level, pexe_size, compile_time_us);
...@@ -3477,6 +3472,11 @@ static void Pnacl_M25_PPB_NaCl_Private_SetPNaClStartTime(PP_Instance instance) { ...@@ -3477,6 +3472,11 @@ static void Pnacl_M25_PPB_NaCl_Private_SetPNaClStartTime(PP_Instance instance) {
iface->SetPNaClStartTime(instance); iface->SetPNaClStartTime(instance);
} }
static void Pnacl_M25_PPB_NaCl_Private_StreamPexe(PP_Instance instance, const char* pexe_url, int32_t opt_level, const struct PPP_PexeStreamHandler_1_0* stream_handler, void* stream_handler_user_data) {
const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
iface->StreamPexe(instance, pexe_url, opt_level, stream_handler, stream_handler_user_data);
}
/* End wrapper methods for PPB_NaCl_Private_1_0 */ /* End wrapper methods for PPB_NaCl_Private_1_0 */
/* Begin wrapper methods for PPB_NetAddress_Private_0_1 */ /* Begin wrapper methods for PPB_NetAddress_Private_0_1 */
...@@ -4331,6 +4331,8 @@ static struct PP_Var Pnacl_M18_PPP_Instance_Private_GetInstanceObject(PP_Instanc ...@@ -4331,6 +4331,8 @@ static struct PP_Var Pnacl_M18_PPP_Instance_Private_GetInstanceObject(PP_Instanc
/* End wrapper methods for PPP_Instance_Private_0_1 */ /* End wrapper methods for PPP_Instance_Private_0_1 */
/* Not generating wrapper methods for PPP_PexeStreamHandler_1_0 */
/* Not generating wrapper interface for PPB_Audio_1_0 */ /* Not generating wrapper interface for PPB_Audio_1_0 */
/* Not generating wrapper interface for PPB_Audio_1_1 */ /* Not generating wrapper interface for PPB_Audio_1_1 */
...@@ -5228,7 +5230,6 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { ...@@ -5228,7 +5230,6 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = {
.CreateTemporaryFile = (PP_FileHandle (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_CreateTemporaryFile, .CreateTemporaryFile = (PP_FileHandle (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_CreateTemporaryFile,
.GetNumberOfProcessors = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_GetNumberOfProcessors, .GetNumberOfProcessors = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_GetNumberOfProcessors,
.IsNonSFIModeEnabled = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_IsNonSFIModeEnabled, .IsNonSFIModeEnabled = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_IsNonSFIModeEnabled,
.GetNexeFd = (int32_t (*)(PP_Instance instance, const char* pexe_url, uint32_t abi_version, uint32_t opt_level, const char* headers, const char* extra_flags, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_GetNexeFd,
.ReportTranslationFinished = (void (*)(PP_Instance instance, PP_Bool success, int32_t opt_level, int64_t pexe_size, int64_t compile_time_us))&Pnacl_M25_PPB_NaCl_Private_ReportTranslationFinished, .ReportTranslationFinished = (void (*)(PP_Instance instance, PP_Bool success, int32_t opt_level, int64_t pexe_size, int64_t compile_time_us))&Pnacl_M25_PPB_NaCl_Private_ReportTranslationFinished,
.DispatchEvent = (void (*)(PP_Instance instance, PP_NaClEventType event_type, const char* resource_url, PP_Bool length_is_computable, uint64_t loaded_bytes, uint64_t total_bytes))&Pnacl_M25_PPB_NaCl_Private_DispatchEvent, .DispatchEvent = (void (*)(PP_Instance instance, PP_NaClEventType event_type, const char* resource_url, PP_Bool length_is_computable, uint64_t loaded_bytes, uint64_t total_bytes))&Pnacl_M25_PPB_NaCl_Private_DispatchEvent,
.ReportLoadSuccess = (void (*)(PP_Instance instance, uint64_t loaded_bytes, uint64_t total_bytes))&Pnacl_M25_PPB_NaCl_Private_ReportLoadSuccess, .ReportLoadSuccess = (void (*)(PP_Instance instance, uint64_t loaded_bytes, uint64_t total_bytes))&Pnacl_M25_PPB_NaCl_Private_ReportLoadSuccess,
...@@ -5258,7 +5259,8 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { ...@@ -5258,7 +5259,8 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = {
.ReportSelLdrStatus = (void (*)(PP_Instance instance, int32_t load_status, int32_t max_status))&Pnacl_M25_PPB_NaCl_Private_ReportSelLdrStatus, .ReportSelLdrStatus = (void (*)(PP_Instance instance, int32_t load_status, int32_t max_status))&Pnacl_M25_PPB_NaCl_Private_ReportSelLdrStatus,
.LogTranslateTime = (void (*)(const char* histogram_name, int64_t time_us))&Pnacl_M25_PPB_NaCl_Private_LogTranslateTime, .LogTranslateTime = (void (*)(const char* histogram_name, int64_t time_us))&Pnacl_M25_PPB_NaCl_Private_LogTranslateTime,
.OpenManifestEntry = (void (*)(PP_Instance instance, PP_Bool is_helper_process, const char* key, struct PP_NaClFileInfo* file_info, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_OpenManifestEntry, .OpenManifestEntry = (void (*)(PP_Instance instance, PP_Bool is_helper_process, const char* key, struct PP_NaClFileInfo* file_info, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_OpenManifestEntry,
.SetPNaClStartTime = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_SetPNaClStartTime .SetPNaClStartTime = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_SetPNaClStartTime,
.StreamPexe = (void (*)(PP_Instance instance, const char* pexe_url, int32_t opt_level, const struct PPP_PexeStreamHandler_1_0* stream_handler, void* stream_handler_user_data))&Pnacl_M25_PPB_NaCl_Private_StreamPexe
}; };
static const struct PPB_NetAddress_Private_0_1 Pnacl_Wrappers_PPB_NetAddress_Private_0_1 = { static const struct PPB_NetAddress_Private_0_1 Pnacl_Wrappers_PPB_NetAddress_Private_0_1 = {
...@@ -5481,6 +5483,8 @@ static const struct PPP_Instance_Private_0_1 Pnacl_Wrappers_PPP_Instance_Private ...@@ -5481,6 +5483,8 @@ static const struct PPP_Instance_Private_0_1 Pnacl_Wrappers_PPP_Instance_Private
.GetInstanceObject = &Pnacl_M18_PPP_Instance_Private_GetInstanceObject .GetInstanceObject = &Pnacl_M18_PPP_Instance_Private_GetInstanceObject
}; };
/* Not generating wrapper interface for PPP_PexeStreamHandler_1_0 */
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Compositor_0_1 = { static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Compositor_0_1 = {
.iface_macro = PPB_COMPOSITOR_INTERFACE_0_1, .iface_macro = PPB_COMPOSITOR_INTERFACE_0_1,
.wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_Compositor_0_1, .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_Compositor_0_1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment