tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FileSystemTaskBase.h (11701B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_FileSystemTaskBase_h
      8 #define mozilla_dom_FileSystemTaskBase_h
      9 
     10 #include "mozilla/dom/FileSystemRequestParent.h"
     11 #include "mozilla/dom/PFileSystemRequestChild.h"
     12 #include "nsIGlobalObject.h"
     13 #include "nsThreadUtils.h"
     14 
     15 namespace mozilla {
     16 class ErrorResult;
     17 
     18 namespace dom {
     19 
     20 class BlobImpl;
     21 class FileSystemBase;
     22 class FileSystemParams;
     23 
     24 /*
     25 * The base class to implement a Task class.
     26 * The file system operations can only be performed in the parent process. In
     27 * order to avoid duplicated code, we used PBackground for child-parent and
     28 * parent-parent communications.
     29 *
     30 * The following diagram illustrates the how a API call from the content page
     31 * starts a task and gets call back results.
     32 *
     33 * The left block is the call sequence inside any process loading content, while
     34 * the right block is the call sequence only inside the parent process.
     35 *
     36 *       Page
     37 *        |
     38 *        | (1)
     39 *  ______|_________________________     |    _________________________________
     40 * |      |                          |   |   |                                 |
     41 * |      |                          |   |   |                                 |
     42 * |      V                          |  IPC  | PBackground thread on           |
     43 * | [new FileSystemTaskChildBase()] |   |   | the parent process              |
     44 * |         |                       |   |   |                                 |
     45 * |         | (2)                   |       |                                 |
     46 * |         V                       |  (3)  |                                 |
     47 * |    [GetRequestParams]------------------->[new FileSystemTaskParentBase()] |
     48 * |                                 |       |          |                      |
     49 * |                                 |   |   |          | (4)   _____________  |
     50 * |                                 |   |   |          |      |             | |
     51 * |                                 |   |   |          |      | I/O Thread  | |
     52 * |                                 |   |   |          |      |             | |
     53 * |                                 |   |   |          ---------> [IOWork]  | |
     54 * |                                 |  IPC  |                 |     |       | |
     55 * |                                 |   |   |                 |     | (5)   | |
     56 * |                                 |   |   |          -------------*       | |
     57 * |                                 |   |   |          |      |_____|_______| |
     58 * |                                 |   |   |          |  __________|_______  |
     59 * |                                 |   |   |          | |          |       | |
     60 * |                                 |   |   |          | | Main     |       | |
     61 * |                                 |   |   |          | | Thread   |       | |
     62 * |                                 |   |   |          | |          V       | |
     63 * |                                 |   |   |          | | [MainThreadWork] | |
     64 * |                                 |  IPC  |          | |   (5.1)  |       | |
     65 * |                                 |   |   |          | |          |       | |
     66 * |                                 |   |   |          |<------------       | |
     67 * |                                 |   |   |          | |__________________| |
     68 * |                                 |   |   |          V                      |
     69 * |                                 |   |   |     [HandleResult]              |
     70 * |                                 |   |   |          |                      |
     71 * |                                 |       |          | (6)                  |
     72 * |                                 |  (7)  |          V                      |
     73 * |   [SetRequestResult]<---------------------[GetRequestResult]              |
     74 * |       |                         |       |                                 |
     75 * |       | (8)                     |   |   |                                 |
     76 * |       V                         |   |   |                                 |
     77 * |[HandlerCallback]                |  IPC  |                                 |
     78 * |_______|_________________________|   |   |_________________________________|
     79 *         |                             |
     80 *         V
     81 *        Page
     82 *
     83 * 1. From the process that is handling the request
     84 * Child/Parent (it can be in any process):
     85 *   (1) Call FileSystem API from content page with JS. Create a task and run.
     86 *   The base constructor [FileSystemTaskChildBase()] of the task should be
     87 *   called.
     88 *   (2) Forward the task to the parent process through the IPC and call
     89 *   [GetRequestParams] to prepare the parameters of the IPC.
     90 * Parent:
     91 *   (3) The parent process receives IPC and handle it in
     92 *   FileystemRequestParent. Get the IPC parameters and create a task to run the
     93 *   IPC task.
     94 *   (4) The task operation will be performed in the member function of
     95 * [IOWork]. A I/O  thread will be created to run that function. If error occurs
     96 *   during the operation, call [SetError] to record the error and then abort.
     97 *   (5) After finishing the task operation, call [HandleResult] to send the
     98 *   result back to the child process though the IPC.
     99 *   (5.1) Optional, we need to run some code in the main-thread.
    100 *   (6) Call [GetRequestResult] request result to prepare the parameters of the
    101 *   IPC. Because the formats of the error result for different task are the
    102 *   same, FileSystemTaskChildBase can handle the error message without
    103 *   interfering.
    104 *   Each task only needs to implement its specific success result preparation
    105 *   function -[GetSuccessRequestResult].
    106 * Child/Parent:
    107 *   (7) The process receives IPC and calls [SetRequestResult] to get the
    108 *   task result. Each task needs to implement its specific success result
    109 *   parsing function [SetSuccessRequestResult] to get the success result.
    110 *   (8) Call [HandlerCallback] to send the task result to the content page.
    111 */
    112 class FileSystemTaskChildBase : public PFileSystemRequestChild {
    113  friend class PFileSystemRequestChild;
    114 
    115 public:
    116  NS_INLINE_DECL_REFCOUNTING(FileSystemTaskChildBase, final)
    117 
    118  /*
    119   * Start the task. It will dispatch all the information to the parent process,
    120   * PBackground thread. This method must be called from the owning thread.
    121   */
    122  void Start();
    123 
    124  /*
    125   * The error codes are defined in xpcom/base/ErrorList.h and their
    126   * corresponding error name and message are defined in dom/base/domerr.msg.
    127   */
    128  void SetError(const nsresult& aErrorCode);
    129 
    130  FileSystemBase* GetFileSystem() const;
    131 
    132  /*
    133   * After the task is completed, this function will be called to pass the task
    134   * result to the content page. This method is called in the owning thread.
    135   * Override this function to handle the call back to the content page.
    136   */
    137  virtual void HandlerCallback() = 0;
    138 
    139  bool HasError() const { return NS_FAILED(mErrorValue); }
    140 
    141 protected:
    142  /*
    143   * To create a task to handle the page content request.
    144   */
    145  FileSystemTaskChildBase(nsIGlobalObject* aGlobalObject,
    146                          FileSystemBase* aFileSystem);
    147 
    148  virtual ~FileSystemTaskChildBase();
    149 
    150  /*
    151   * Wrap the task parameter to FileSystemParams for sending it through IPC.
    152   * It will be called when we need to forward a task from the child process to
    153   * the parent process. This method runs in the owning thread.
    154   * @param filesystem The string representation of the file system.
    155   */
    156  virtual FileSystemParams GetRequestParams(const nsString& aSerializedDOMPath,
    157                                            ErrorResult& aRv) const = 0;
    158 
    159  /*
    160   * Unwrap the IPC message to get the task success result.
    161   * It will be called when the task is completed successfully and an IPC
    162   * message is received in the child process and we want to get the task
    163   * success result. This method runs in the owning thread.
    164   */
    165  virtual void SetSuccessRequestResult(const FileSystemResponseValue& aValue,
    166                                       ErrorResult& aRv) = 0;
    167 
    168  // Overrides PFileSystemRequestChild
    169  virtual mozilla::ipc::IPCResult Recv__delete__(
    170      const FileSystemResponseValue& value) final;
    171 
    172  nsresult mErrorValue;
    173  RefPtr<FileSystemBase> mFileSystem;
    174  nsCOMPtr<nsIGlobalObject> mGlobalObject;
    175 
    176 private:
    177  /*
    178   * Unwrap the IPC message to get the task result.
    179   * It will be called when the task is completed and an IPC message is received
    180   * in the content process and we want to get the task result. This runs on the
    181   * owning thread.
    182   */
    183  void SetRequestResult(const FileSystemResponseValue& aValue);
    184 };
    185 
    186 // This class is the 'alter ego' of FileSystemTaskChildBase in the PBackground
    187 // world.
    188 class FileSystemTaskParentBase : public Runnable {
    189 public:
    190  FileSystemTaskParentBase()
    191      : Runnable("FileSystemTaskParentBase"),
    192        mErrorValue(NS_ERROR_NOT_INITIALIZED) {}
    193 
    194  /*
    195   * Start the task. This must be called from the PBackground thread only.
    196   */
    197  void Start();
    198 
    199  /*
    200   * The error codes are defined in xpcom/base/ErrorList.h and their
    201   * corresponding error name and message are defined in dom/base/domerr.msg.
    202   */
    203  void SetError(const nsresult& aErrorCode);
    204 
    205  /*
    206   * The function to perform task operation. It will be run on the I/O
    207   * thread of the parent process.
    208   * Overrides this function to define the task operation for individual task.
    209   */
    210  virtual nsresult IOWork() = 0;
    211 
    212  // In case `MainThreadNeeded()` returns true, the following method is called.
    213  virtual nsresult MainThreadWork() {
    214    MOZ_CRASH("This method should be implemented");
    215    return NS_OK;
    216  }
    217 
    218  // If this returns true, after I/O work, we schedule a runnable to the
    219  // main-thread before resolving the task on the PBackground one.
    220  virtual bool MainThreadNeeded() const { return false; };
    221 
    222  /*
    223   * Wrap the task success result to FileSystemResponseValue for sending it
    224   * through IPC. This method runs in the PBackground thread.
    225   * It will be called when the task is completed successfully and we need to
    226   * send the task success result back to the child process.
    227   */
    228  virtual FileSystemResponseValue GetSuccessRequestResult(
    229      ErrorResult& aRv) const = 0;
    230 
    231  /*
    232   * After finishing the task operation, handle the task result.
    233   * If it is an IPC task, send back the IPC result. It runs on the PBackground
    234   * thread.
    235   */
    236  void HandleResult();
    237 
    238  bool HasError() const { return NS_FAILED(mErrorValue); }
    239 
    240  NS_IMETHOD
    241  Run() override;
    242 
    243  virtual nsresult GetTargetPath(nsAString& aPath) const = 0;
    244 
    245 private:
    246  /*
    247   * Wrap the task result to FileSystemResponseValue for sending it through IPC.
    248   * It will be called when the task is completed and we need to
    249   * send the task result back to the content. This runs on the PBackground
    250   * thread.
    251   */
    252  FileSystemResponseValue GetRequestResult() const;
    253 
    254 protected:
    255  /*
    256   * To create a parent process task delivered from the child process through
    257   * IPC.
    258   */
    259  FileSystemTaskParentBase(FileSystemBase* aFileSystem,
    260                           const FileSystemParams& aParam,
    261                           FileSystemRequestParent* aParent);
    262 
    263  virtual ~FileSystemTaskParentBase();
    264 
    265  nsresult mErrorValue;
    266  RefPtr<FileSystemBase> mFileSystem;
    267  RefPtr<FileSystemRequestParent> mRequestParent;
    268  nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
    269 };
    270 
    271 }  // namespace dom
    272 }  // namespace mozilla
    273 
    274 #endif  // mozilla_dom_FileSystemTaskBase_h