Commit b88c4699 authored by Ben Kelly's avatar Ben Kelly
Browse files

Bug 1397128 P3 Add an OpenStreamAction class to open the file stream on the io thread. r=tt

parent 9bbbfca0
Loading
Loading
Loading
Loading
+65 −0
Original line number Diff line number Diff line
@@ -1452,6 +1452,43 @@ private:

// ----------------------------------------------------------------------------

class Manager::OpenStreamAction final : public Manager::BaseAction
{
public:
  OpenStreamAction(Manager* aManager, ListenerId aListenerId,
                   OpenStreamResolver&& aResolver, const nsID& aBodyId)
    : BaseAction(aManager, aListenerId)
    , mResolver(Move(aResolver))
    , mBodyId(aBodyId)
  { }

  virtual nsresult
  RunSyncWithDBOnTarget(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
                        mozIStorageConnection* aConn) override
  {
    nsresult rv = BodyOpen(aQuotaInfo, aDBDir, mBodyId,
                           getter_AddRefs(mBodyStream));
    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
    if (NS_WARN_IF(!mBodyStream)) { return NS_ERROR_FILE_NOT_FOUND; }

    return rv;
  }

  virtual void
  Complete(Listener* aListener, ErrorResult&& aRv) override
  {
    mResolver(Move(mBodyStream));
    mResolver = nullptr;
  }

private:
  OpenStreamResolver mResolver;
  const nsID mBodyId;
  nsCOMPtr<nsIInputStream> mBodyStream;
};

// ----------------------------------------------------------------------------

//static
Manager::ListenerId Manager::sNextListenerId = 0;

@@ -1818,6 +1855,34 @@ Manager::ExecuteStorageOp(Listener* aListener, Namespace aNamespace,
  context->Dispatch(action);
}

void
Manager::ExecuteOpenStream(Listener* aListener, OpenStreamResolver&& aResolver,
                           const nsID& aBodyId)
{
  NS_ASSERT_OWNINGTHREAD(Manager);
  MOZ_DIAGNOSTIC_ASSERT(aListener);
  MOZ_DIAGNOSTIC_ASSERT(aResolver);

  if (NS_WARN_IF(mState == Closing)) {
    aResolver(nullptr);
    return;
  }

  RefPtr<Context> context = mContext;
  MOZ_DIAGNOSTIC_ASSERT(!context->IsCanceled());

  // We save the listener simply to track the existence of the caller here.
  // Our returned value will really be passed to the resolver when the
  // operation completes.  In the future we should remove the Listener
  // mechanism in favor of std::function or MozPromise.
  ListenerId listenerId = SaveListener(aListener);

  RefPtr<Action> action =
    new OpenStreamAction(this, listenerId, Move(aResolver), aBodyId);

  context->Dispatch(action);
}

void
Manager::ExecutePutAll(Listener* aListener, CacheId aCacheId,
                       const nsTArray<CacheRequestResponse>& aPutList,
+10 −0
Original line number Diff line number Diff line
@@ -177,6 +177,14 @@ public:
  void ExecuteStorageOp(Listener* aListener, Namespace aNamespace,
                        const CacheOpArgs& aOpArgs);

  typedef std::function<void(nsCOMPtr<nsIInputStream>&&)> OpenStreamResolver;
  void ExecuteOpenStream(Listener* aListener, OpenStreamResolver&& aResolver,
                         const nsID& aBodyId);

  void
  NoteStreamOpenComplete(const nsID& aBodyId, ErrorResult&& aRv,
                         nsCOMPtr<nsIInputStream>&& aBodyStream);

private:
  class Factory;
  class BaseAction;
@@ -194,6 +202,8 @@ private:
  class StorageDeleteAction;
  class StorageKeysAction;

  class OpenStreamAction;

  typedef uint64_t ListenerId;

  Manager(ManagerId* aManagerId, nsIThread* aIOThread);