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