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
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_RemoteLazyInputStreamChild_h
8 #define mozilla_RemoteLazyInputStreamChild_h
9 
10 #include "mozilla/PRemoteLazyInputStreamChild.h"
11 #include "mozilla/RemoteLazyInputStream.h"
12 #include "mozilla/Mutex.h"
13 #include "mozilla/UniquePtr.h"
14 #include "nsTArray.h"
15 
16 namespace mozilla {
17 
18 class RemoteLazyInputStream;
19 
20 namespace dom {
21 class ThreadSafeWorkerRef;
22 }
23 
24 class RemoteLazyInputStreamChild final : public PRemoteLazyInputStreamChild {
25  public:
26   enum ActorState {
27     // The actor is connected via IPDL to the parent.
28     eActive,
29 
30     // The actor is disconnected.
31     eInactive,
32 
33     // The actor is waiting to be disconnected. Once it has been disconnected,
34     // it will be reactivated on the DOM-File thread.
35     eActiveMigrating,
36 
37     // The actor has been disconnected and it's waiting to be connected on the
38     // DOM-File thread.
39     eInactiveMigrating,
40   };
41 
42   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteLazyInputStreamChild, final)
43 
44   RemoteLazyInputStreamChild(const nsID& aID, uint64_t aSize);
45 
46   void ActorDestroy(IProtocol::ActorDestroyReason aReason) override;
47 
48   ActorState State();
49 
50   already_AddRefed<RemoteLazyInputStream> CreateStream();
51 
52   void ForgetStream(RemoteLazyInputStream* aStream);
53 
ID()54   const nsID& ID() const { return mID; }
55 
Size()56   uint64_t Size() const { return mSize; }
57 
58   void StreamNeeded(RemoteLazyInputStream* aStream,
59                     nsIEventTarget* aEventTarget);
60 
61   mozilla::ipc::IPCResult RecvStreamReady(const Maybe<IPCStream>& aStream);
62 
63   void LengthNeeded(RemoteLazyInputStream* aStream,
64                     nsIEventTarget* aEventTarget);
65 
66   mozilla::ipc::IPCResult RecvLengthReady(const int64_t& aLength);
67 
68   void Shutdown();
69 
70   void Migrated();
71 
72  private:
73   ~RemoteLazyInputStreamChild();
74 
75   // Raw pointers because these streams keep this actor alive. When the last
76   // stream is unregister, the actor will be deleted. This list is protected by
77   // mutex.
78   nsTArray<RemoteLazyInputStream*> mStreams;
79 
80   // This mutex protects mStreams because that can be touched in any thread.
81   Mutex mMutex;
82 
83   const nsID mID;
84   const uint64_t mSize;
85 
86   ActorState mState;
87 
88   // This struct and the array are used for creating streams when needed.
89   struct PendingOperation {
90     RefPtr<RemoteLazyInputStream> mStream;
91     nsCOMPtr<nsIEventTarget> mEventTarget;
92     enum {
93       eStreamNeeded,
94       eLengthNeeded,
95     } mOp;
96   };
97   nsTArray<PendingOperation> mPendingOperations;
98 
99   nsCOMPtr<nsISerialEventTarget> mOwningEventTarget;
100 
101   RefPtr<dom::ThreadSafeWorkerRef> mWorkerRef;
102 };
103 
104 }  // namespace mozilla
105 
106 #endif  // mozilla_RemoteLazyInputStreamChild_h
107