tor-browser

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

GetFilesHelper.h (4955B)


      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_GetFilesHelper_h
      8 #define mozilla_dom_GetFilesHelper_h
      9 
     10 #include "mozilla/MozPromise.h"
     11 #include "mozilla/Mutex.h"
     12 #include "mozilla/RefPtr.h"
     13 #include "nsCycleCollectionTraversalCallback.h"
     14 #include "nsTArray.h"
     15 #include "nsThreadUtils.h"
     16 
     17 class nsIGlobalObject;
     18 
     19 namespace mozilla {
     20 class ErrorResult;
     21 
     22 namespace dom {
     23 
     24 class BlobImpl;
     25 class ContentParent;
     26 class File;
     27 class GetFilesHelperParent;
     28 class OwningFileOrDirectory;
     29 class Promise;
     30 
     31 class GetFilesCallback {
     32 public:
     33  NS_INLINE_DECL_REFCOUNTING(GetFilesCallback);
     34 
     35  // This is called once per directory scan and is passed an array of all
     36  // of the files found.
     37  virtual void Callback(nsresult aStatus,
     38                        const FallibleTArray<RefPtr<BlobImpl>>& aBlobImpls) = 0;
     39 
     40 protected:
     41  virtual ~GetFilesCallback() = default;
     42 };
     43 
     44 class GetFilesHelperBase {
     45 protected:
     46  explicit GetFilesHelperBase(bool aRecursiveFlag)
     47      : mRecursiveFlag(aRecursiveFlag) {}
     48 
     49  virtual ~GetFilesHelperBase() = default;
     50 
     51  virtual bool IsCanceled() { return false; }
     52 
     53  nsresult ExploreDirectory(const nsAString& aDOMPath, nsIFile* aFile);
     54 
     55  bool mRecursiveFlag;
     56 
     57  // We populate this array in the I/O thread with the BlobImpl.
     58  FallibleTArray<RefPtr<BlobImpl>> mTargetBlobImplArray;
     59 };
     60 
     61 // Retrieving the list of files can be very time/IO consuming. We use this
     62 // helper class to do it just once.
     63 class GetFilesHelper : public Runnable, public GetFilesHelperBase {
     64  friend class GetFilesHelperParent;
     65  class ReleaseRunnable;
     66 
     67 public:
     68  static already_AddRefed<GetFilesHelper> Create(
     69      const nsTArray<OwningFileOrDirectory>& aFilesOrDirectory,
     70      bool aRecursiveFlag, ErrorResult& aRv);
     71 
     72  void AddPromise(Promise* aPromise);
     73 
     74  void AddCallback(GetFilesCallback* aCallback);
     75 
     76  using MozPromiseType =
     77      MozPromise<nsTArray<RefPtr<File>>, nsresult, true>::Private;
     78  void AddMozPromise(MozPromiseType* aPromise, nsIGlobalObject* aGlobal);
     79 
     80  // CC methods
     81  void Unlink();
     82  void Traverse(nsCycleCollectionTraversalCallback& cb);
     83 
     84 protected:
     85  explicit GetFilesHelper(bool aRecursiveFlag);
     86 
     87  virtual ~GetFilesHelper();
     88 
     89  void SetDirectoryPaths(nsTArray<nsString>&& aDirectoryPaths) {
     90    mDirectoryPaths = std::move(aDirectoryPaths);
     91  }
     92 
     93  virtual bool IsCanceled() override {
     94    MutexAutoLock lock(mMutex);
     95    return mCanceled;
     96  }
     97 
     98  virtual void Work(ErrorResult& aRv);
     99 
    100  virtual void Cancel() {};
    101 
    102  NS_IMETHOD
    103  Run() override;
    104 
    105  void RunIO();
    106 
    107  void OperationCompleted();
    108 
    109  struct MozPromiseAndGlobal {
    110    RefPtr<MozPromiseType> mMozPromise;
    111    RefPtr<nsIGlobalObject> mGlobal;
    112  };
    113 
    114  class PromiseAdapter {
    115   public:
    116    explicit PromiseAdapter(MozPromiseAndGlobal&& aMozPromise);
    117    explicit PromiseAdapter(Promise* aDomPromise);
    118    ~PromiseAdapter();
    119 
    120    void Clear();
    121    void Traverse(nsCycleCollectionTraversalCallback& cb);
    122 
    123    nsIGlobalObject* GetGlobalObject();
    124    void Resolve(nsTArray<RefPtr<File>>&& aFiles);
    125    void Reject(nsresult aError);
    126 
    127   private:
    128    using PromiseVariant = Variant<RefPtr<Promise>, MozPromiseAndGlobal>;
    129    PromiseVariant mPromise;
    130  };
    131 
    132  void AddPromiseInternal(PromiseAdapter&& aPromise);
    133  void ResolveOrRejectPromise(PromiseAdapter&& aPromise);
    134 
    135  void RunCallback(GetFilesCallback* aCallback);
    136 
    137  bool mListingCompleted;
    138  nsTArray<nsString> mDirectoryPaths;
    139 
    140  // Error code to propagate.
    141  nsresult mErrorResult;
    142 
    143  nsTArray<PromiseAdapter> mPromises;
    144 
    145  nsTArray<RefPtr<GetFilesCallback>> mCallbacks;
    146 
    147  Mutex mMutex MOZ_UNANNOTATED;
    148 
    149  // This variable is protected by mutex.
    150  bool mCanceled;
    151 };
    152 
    153 class GetFilesHelperChild final : public GetFilesHelper {
    154 public:
    155  explicit GetFilesHelperChild(bool aRecursiveFlag)
    156      : GetFilesHelper(aRecursiveFlag), mPendingOperation(false) {}
    157 
    158  virtual void Work(ErrorResult& aRv) override;
    159 
    160  virtual void Cancel() override;
    161 
    162  bool AppendBlobImpl(BlobImpl* aBlobImpl);
    163 
    164  void Finished(nsresult aResult);
    165 
    166 private:
    167  nsID mUUID;
    168  bool mPendingOperation;
    169 };
    170 
    171 class GetFilesHelperParentCallback;
    172 
    173 class GetFilesHelperParent final : public GetFilesHelper {
    174  friend class GetFilesHelperParentCallback;
    175 
    176 public:
    177  static already_AddRefed<GetFilesHelperParent> Create(
    178      const nsID& aUUID, nsTArray<nsString>&& aDirectoryPaths,
    179      bool aRecursiveFlag, ContentParent* aContentParent, ErrorResult& aRv);
    180 
    181 private:
    182  GetFilesHelperParent(const nsID& aUUID, ContentParent* aContentParent,
    183                       bool aRecursiveFlag);
    184 
    185  ~GetFilesHelperParent();
    186 
    187  RefPtr<ContentParent> mContentParent;
    188  nsID mUUID;
    189 };
    190 
    191 }  // namespace dom
    192 }  // namespace mozilla
    193 
    194 #endif  // mozilla_dom_GetFilesHelper_h