OLD | NEW |
| (Empty) |
1 // Copyright 2013 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 CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_ | |
6 #define CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_ | |
7 | |
8 #include <map> | |
9 | |
10 #include "base/callback_forward.h" | |
11 #include "base/memory/singleton.h" | |
12 #include "base/memory/weak_ptr.h" | |
13 #include "base/threading/thread_checker.h" | |
14 #include "chrome/browser/nacl_host/nacl_file_host.h" | |
15 #include "components/nacl/common/pnacl_types.h" | |
16 #include "ipc/ipc_platform_file.h" | |
17 | |
18 namespace net { | |
19 class DrainableIOBuffer; | |
20 } | |
21 | |
22 namespace pnacl { | |
23 class PnaclHostTest; | |
24 class PnaclTranslationCache; | |
25 } | |
26 | |
27 // Shared state (translation cache) and common utilities (temp file creation) | |
28 // for all PNaCl translations. Unless otherwise specified, all methods should be | |
29 // called on the IO thread. | |
30 class PnaclHost { | |
31 public: | |
32 typedef base::Callback<void(base::PlatformFile)> TempFileCallback; | |
33 typedef base::Callback<void(base::PlatformFile, bool is_hit)> NexeFdCallback; | |
34 | |
35 static PnaclHost* GetInstance(); | |
36 | |
37 PnaclHost(); | |
38 ~PnaclHost(); | |
39 | |
40 // Initialize cache backend. GetNexeFd will also initialize the backend if | |
41 // necessary, but calling Init ahead of time will minimize the latency. | |
42 void Init(); | |
43 | |
44 // Creates a temporary file that will be deleted when the last handle | |
45 // is closed, or earlier. Returns a PlatformFile handle. | |
46 void CreateTemporaryFile(TempFileCallback cb); | |
47 | |
48 // Create a temporary file, which will be deleted by the time the last | |
49 // handle is closed (or earlier on POSIX systems), to use for the nexe | |
50 // with the cache information given in |cache_info|. The specific instance | |
51 // is identified by the combination of |render_process_id| and |pp_instance|. | |
52 // Returns by calling |cb| with a PlatformFile handle. | |
53 // If the nexe is already present | |
54 // in the cache, |is_hit| is set to true and the contents of the nexe | |
55 // have been copied into the temporary file. Otherwise |is_hit| is set to | |
56 // false and the temporary file will be writeable. | |
57 // Currently the implementation is a stub, which always sets is_hit to false | |
58 // and calls the implementation of CreateTemporaryFile. | |
59 // If the cache request was a miss, the caller is expected to call | |
60 // TranslationFinished after it finishes translation to allow the nexe to be | |
61 // stored in the cache. | |
62 // The returned temp fd may be closed at any time by PnaclHost, so it should | |
63 // be duplicated (e.g. with IPC::GetFileHandleForProcess) before the callback | |
64 // returns. | |
65 // If |is_incognito| is true, the nexe will not be stored | |
66 // in the cache, but the renderer is still expected to call | |
67 // TranslationFinished. | |
68 void GetNexeFd(int render_process_id, | |
69 int render_view_id, | |
70 int pp_instance, | |
71 bool is_incognito, | |
72 const nacl::PnaclCacheInfo& cache_info, | |
73 const NexeFdCallback& cb); | |
74 | |
75 // Called after the translation of a pexe instance identified by | |
76 // |render_process_id| and |pp_instance| finishes. If |success| is true, | |
77 // store the nexe translated for the instance in the cache. | |
78 void TranslationFinished(int render_process_id, | |
79 int pp_instance, | |
80 bool success); | |
81 | |
82 // Called when the renderer identified by |render_process_id| is closing. | |
83 // Clean up any outstanding translations for that renderer. If there are no | |
84 // more pending translations, the backend is freed, allowing it to flush. | |
85 void RendererClosing(int render_process_id); | |
86 | |
87 // Doom all entries between |initial_time| and |end_time|. Like disk_cache_, | |
88 // PnaclHost supports supports unbounded deletes in either direction by using | |
89 // null Time values for either argument. |callback| will be called on the UI | |
90 // thread when finished. | |
91 void ClearTranslationCacheEntriesBetween(base::Time initial_time, | |
92 base::Time end_time, | |
93 const base::Closure& callback); | |
94 | |
95 // Return the number of tracked translations or FD requests currently pending. | |
96 size_t pending_translations() { return pending_translations_.size(); } | |
97 | |
98 private: | |
99 // PnaclHost is a singleton because there is only one translation cache, and | |
100 // so that the BrowsingDataRemover can clear it even if no translation has | |
101 // ever been started. | |
102 friend struct DefaultSingletonTraits<PnaclHost>; | |
103 friend class pnacl::PnaclHostTest; | |
104 enum CacheState { | |
105 CacheUninitialized, | |
106 CacheInitializing, | |
107 CacheReady | |
108 }; | |
109 class PendingTranslation { | |
110 public: | |
111 PendingTranslation(); | |
112 ~PendingTranslation(); | |
113 base::ProcessHandle process_handle; | |
114 int render_view_id; | |
115 base::PlatformFile nexe_fd; | |
116 bool got_nexe_fd; | |
117 bool got_cache_reply; | |
118 bool got_cache_hit; | |
119 bool is_incognito; | |
120 scoped_refptr<net::DrainableIOBuffer> nexe_read_buffer; | |
121 NexeFdCallback callback; | |
122 std::string cache_key; | |
123 nacl::PnaclCacheInfo cache_info; | |
124 }; | |
125 | |
126 typedef std::pair<int, int> TranslationID; | |
127 typedef std::map<TranslationID, PendingTranslation> PendingTranslationMap; | |
128 static bool TranslationMayBeCached( | |
129 const PendingTranslationMap::iterator& entry); | |
130 | |
131 void InitForTest(base::FilePath temp_dir); | |
132 void OnCacheInitialized(int net_error); | |
133 | |
134 static void DoCreateTemporaryFile(base::FilePath temp_dir_, | |
135 TempFileCallback cb); | |
136 | |
137 // GetNexeFd common steps | |
138 void SendCacheQueryAndTempFileRequest(const std::string& key, | |
139 const TranslationID& id); | |
140 void OnCacheQueryReturn(const TranslationID& id, | |
141 int net_error, | |
142 scoped_refptr<net::DrainableIOBuffer> buffer); | |
143 void OnTempFileReturn(const TranslationID& id, base::PlatformFile fd); | |
144 void CheckCacheQueryReady(const PendingTranslationMap::iterator& entry); | |
145 | |
146 // GetNexeFd miss path | |
147 void ReturnMiss(const PendingTranslationMap::iterator& entry); | |
148 static scoped_refptr<net::DrainableIOBuffer> CopyFileToBuffer( | |
149 base::PlatformFile fd); | |
150 void StoreTranslatedNexe(TranslationID id, | |
151 scoped_refptr<net::DrainableIOBuffer>); | |
152 void OnTranslatedNexeStored(const TranslationID& id, int net_error); | |
153 void RequeryMatchingTranslations(const std::string& key); | |
154 | |
155 // GetNexeFd hit path | |
156 static int CopyBufferToFile(base::PlatformFile fd, | |
157 scoped_refptr<net::DrainableIOBuffer> buffer); | |
158 void OnBufferCopiedToTempFile(const TranslationID& id, int file_error); | |
159 | |
160 void OnEntriesDoomed(const base::Closure& callback, int net_error); | |
161 | |
162 void DeInitIfSafe(); | |
163 | |
164 // Operations which are pending with the cache backend, which we should | |
165 // wait for before destroying it (see comment on DeInitIfSafe). | |
166 int pending_backend_operations_; | |
167 CacheState cache_state_; | |
168 base::FilePath temp_dir_; | |
169 scoped_ptr<pnacl::PnaclTranslationCache> disk_cache_; | |
170 PendingTranslationMap pending_translations_; | |
171 base::ThreadChecker thread_checker_; | |
172 base::WeakPtrFactory<PnaclHost> weak_factory_; | |
173 DISALLOW_COPY_AND_ASSIGN(PnaclHost); | |
174 }; | |
175 | |
176 #endif // CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_ | |
OLD | NEW |