blob: ee19848ceaba940fc1f8a7575cb8e167714845d1 [file] [log] [blame]
[email protected]c77144722013-01-19 04:16:361// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef PPAPI_PROXY_FILE_IO_RESOURCE_H_
6#define PPAPI_PROXY_FILE_IO_RESOURCE_H_
7
8#include <string>
9
[email protected]d35d3f42013-10-02 19:52:2010#include "base/memory/ref_counted.h"
[email protected]c6420f082013-09-18 22:42:4111#include "base/memory/scoped_ptr.h"
[email protected]8f96cef2013-04-01 16:51:1312#include "ppapi/c/private/pp_file_handle.h"
[email protected]c77144722013-01-19 04:16:3613#include "ppapi/proxy/connection.h"
14#include "ppapi/proxy/plugin_resource.h"
15#include "ppapi/proxy/ppapi_proxy_export.h"
16#include "ppapi/shared_impl/file_io_state_manager.h"
[email protected]c6420f082013-09-18 22:42:4117#include "ppapi/shared_impl/resource.h"
[email protected]4837a982013-11-25 18:11:1318#include "ppapi/shared_impl/scoped_pp_resource.h"
[email protected]c77144722013-01-19 04:16:3619#include "ppapi/thunk/ppb_file_io_api.h"
20
21namespace ppapi {
22
23class TrackedCallback;
24
25namespace proxy {
26
27class PPAPI_PROXY_EXPORT FileIOResource
28 : public PluginResource,
29 public thunk::PPB_FileIO_API {
30 public:
31 FileIOResource(Connection connection, PP_Instance instance);
32 virtual ~FileIOResource();
33
34 // Resource overrides.
35 virtual thunk::PPB_FileIO_API* AsPPB_FileIO_API() OVERRIDE;
36
37 // PPB_FileIO_API implementation.
38 virtual int32_t Open(PP_Resource file_ref,
39 int32_t open_flags,
40 scoped_refptr<TrackedCallback> callback) OVERRIDE;
41 virtual int32_t Query(PP_FileInfo* info,
42 scoped_refptr<TrackedCallback> callback) OVERRIDE;
43 virtual int32_t Touch(PP_Time last_access_time,
44 PP_Time last_modified_time,
45 scoped_refptr<TrackedCallback> callback) OVERRIDE;
46 virtual int32_t Read(int64_t offset,
47 char* buffer,
48 int32_t bytes_to_read,
49 scoped_refptr<TrackedCallback> callback) OVERRIDE;
50 virtual int32_t ReadToArray(int64_t offset,
51 int32_t max_read_length,
52 PP_ArrayOutput* array_output,
53 scoped_refptr<TrackedCallback> callback) OVERRIDE;
54 virtual int32_t Write(int64_t offset,
55 const char* buffer,
56 int32_t bytes_to_write,
57 scoped_refptr<TrackedCallback> callback) OVERRIDE;
58 virtual int32_t SetLength(int64_t length,
59 scoped_refptr<TrackedCallback> callback) OVERRIDE;
60 virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE;
61 virtual void Close() OVERRIDE;
[email protected]8f96cef2013-04-01 16:51:1362 virtual int32_t RequestOSFileHandle(
63 PP_FileHandle* handle,
64 scoped_refptr<TrackedCallback> callback) OVERRIDE;
[email protected]c77144722013-01-19 04:16:3665
66 private:
[email protected]d35d3f42013-10-02 19:52:2067 // FileHandleHolder is used to guarantee that file operations will have a
68 // valid FD to operate on, even if they're in a different thread.
69 // If instead we just passed the raw FD, the FD could be closed before the
70 // file operation has a chance to run. It could interact with an invalid FD,
71 // or worse, the FD value could be reused if another file is opened quickly
72 // (POSIX is required to provide the lowest available value when opening a
73 // file). This could result in strange problems such as writing data to the
74 // wrong file.
75 //
76 // Operations that run on a background thread should hold one of these to
77 // ensure they have a valid file descriptor. The file handle is only closed
78 // when the last reference to the FileHandleHolder is removed, so we are
79 // guaranteed to operate on the correct file descriptor. It *is* still
80 // possible that the FileIOResource will be destroyed and "Abort" callbacks
81 // just before the operation does its task (e.g., Reading). In that case, we
82 // might for example Read from a file even though the FileIO has been
83 // destroyed and the plugin's callback got a PP_ERROR_ABORTED result. In the
84 // case of a write, we could write some data to the file despite the plugin
85 // receiving a PP_ERROR_ABORTED instead of a successful result.
86 class FileHandleHolder : public base::RefCountedThreadSafe<FileHandleHolder> {
87 public:
88 explicit FileHandleHolder(PP_FileHandle file_handle_);
89 PP_FileHandle raw_handle() {
90 return raw_handle_;
91 }
92 static bool IsValid(
93 const scoped_refptr<FileIOResource::FileHandleHolder>& handle);
94 private:
95 friend class base::RefCountedThreadSafe<FileHandleHolder>;
96 ~FileHandleHolder();
97 PP_FileHandle raw_handle_;
98 };
99
[email protected]914a4ba92013-08-10 13:38:48100 // Class to perform file query operations across multiple threads.
101 class QueryOp : public base::RefCountedThreadSafe<QueryOp> {
102 public:
[email protected]d35d3f42013-10-02 19:52:20103 explicit QueryOp(scoped_refptr<FileHandleHolder> file_handle);
[email protected]914a4ba92013-08-10 13:38:48104
105 // Queries the file. Called on the file thread (non-blocking) or the plugin
106 // thread (blocking). This should not be called when we hold the proxy lock.
107 int32_t DoWork();
108
109 const base::PlatformFileInfo& file_info() const { return file_info_; }
110
111 private:
112 friend class base::RefCountedThreadSafe<QueryOp>;
113 ~QueryOp();
114
[email protected]d35d3f42013-10-02 19:52:20115 scoped_refptr<FileHandleHolder> file_handle_;
[email protected]914a4ba92013-08-10 13:38:48116 base::PlatformFileInfo file_info_;
117 };
118
119 // Class to perform file read operations across multiple threads.
120 class ReadOp : public base::RefCountedThreadSafe<ReadOp> {
121 public:
[email protected]d35d3f42013-10-02 19:52:20122 ReadOp(scoped_refptr<FileHandleHolder> file_handle,
123 int64_t offset,
124 int32_t bytes_to_read);
[email protected]914a4ba92013-08-10 13:38:48125
126 // Reads the file. Called on the file thread (non-blocking) or the plugin
127 // thread (blocking). This should not be called when we hold the proxy lock.
128 int32_t DoWork();
129
130 char* buffer() const { return buffer_.get(); }
131
132 private:
133 friend class base::RefCountedThreadSafe<ReadOp>;
134 ~ReadOp();
135
[email protected]d35d3f42013-10-02 19:52:20136 scoped_refptr<FileHandleHolder> file_handle_;
[email protected]914a4ba92013-08-10 13:38:48137 int64_t offset_;
138 int32_t bytes_to_read_;
139 scoped_ptr<char[]> buffer_;
140 };
141
[email protected]c77144722013-01-19 04:16:36142 int32_t ReadValidated(int64_t offset,
143 int32_t bytes_to_read,
144 const PP_ArrayOutput& array_output,
145 scoped_refptr<TrackedCallback> callback);
146
[email protected]914a4ba92013-08-10 13:38:48147 // Completion tasks for file operations that are done in the plugin.
148 int32_t OnQueryComplete(scoped_refptr<QueryOp> query_op,
149 PP_FileInfo* info,
150 int32_t result);
151 int32_t OnReadComplete(scoped_refptr<ReadOp> read_op,
152 PP_ArrayOutput array_output,
153 int32_t result);
154
[email protected]d45f29b2013-08-09 04:18:06155 // Reply message handlers for operations that are done in the host.
[email protected]c77144722013-01-19 04:16:36156 void OnPluginMsgGeneralComplete(scoped_refptr<TrackedCallback> callback,
157 const ResourceMessageReplyParams& params);
158 void OnPluginMsgOpenFileComplete(scoped_refptr<TrackedCallback> callback,
159 const ResourceMessageReplyParams& params);
[email protected]8f96cef2013-04-01 16:51:13160 void OnPluginMsgRequestOSFileHandleComplete(
161 scoped_refptr<TrackedCallback> callback,
162 PP_FileHandle* output_handle,
163 const ResourceMessageReplyParams& params);
[email protected]c77144722013-01-19 04:16:36164
[email protected]d35d3f42013-10-02 19:52:20165 scoped_refptr<FileHandleHolder> file_handle_;
[email protected]d45f29b2013-08-09 04:18:06166 PP_FileSystemType file_system_type_;
[email protected]4837a982013-11-25 18:11:13167 ScopedPPResource file_system_resource_;
[email protected]c77144722013-01-19 04:16:36168 FileIOStateManager state_manager_;
169
[email protected]c6420f082013-09-18 22:42:41170 scoped_refptr<Resource> file_ref_;
171
[email protected]c77144722013-01-19 04:16:36172 DISALLOW_COPY_AND_ASSIGN(FileIOResource);
173};
174
175} // namespace proxy
176} // namespace ppapi
177
178#endif // PPAPI_PROXY_FILE_IO_RESOURCE_H_