Merge mozilla-central to autoland. CLOSED TREE
[gecko.git] / netwerk / base / nsInputStreamPump.h
blob21e75c027666e3483f506f297e93cf14fd9eb265
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsInputStreamPump_h__
7 #define nsInputStreamPump_h__
9 #include "nsIInputStreamPump.h"
10 #include "nsIAsyncInputStream.h"
11 #include "nsIThreadRetargetableRequest.h"
12 #include "nsCOMPtr.h"
13 #include "mozilla/Attributes.h"
14 #include "mozilla/RecursiveMutex.h"
16 #ifdef DEBUG
17 # include "MainThreadUtils.h"
18 # include "nsISerialEventTarget.h"
19 #endif
21 class nsIInputStream;
22 class nsILoadGroup;
23 class nsIStreamListener;
25 #define NS_INPUT_STREAM_PUMP_IID \
26 { \
27 0x42f1cc9b, 0xdf5f, 0x4c9b, { \
28 0xbd, 0x71, 0x8d, 0x4a, 0xe2, 0x27, 0xc1, 0x8a \
29 } \
32 class nsInputStreamPump final : public nsIInputStreamPump,
33 public nsIInputStreamCallback,
34 public nsIThreadRetargetableRequest {
35 ~nsInputStreamPump() = default;
37 public:
38 using RecursiveMutexAutoLock = mozilla::RecursiveMutexAutoLock;
39 using RecursiveMutexAutoUnlock = mozilla::RecursiveMutexAutoUnlock;
40 NS_DECL_THREADSAFE_ISUPPORTS
41 NS_DECL_NSIREQUEST
42 NS_DECL_NSIINPUTSTREAMPUMP
43 NS_DECL_NSIINPUTSTREAMCALLBACK
44 NS_DECL_NSITHREADRETARGETABLEREQUEST
45 NS_DECLARE_STATIC_IID_ACCESSOR(NS_INPUT_STREAM_PUMP_IID)
47 nsInputStreamPump();
49 static nsresult Create(nsInputStreamPump** result, nsIInputStream* stream,
50 uint32_t segsize = 0, uint32_t segcount = 0,
51 bool closeWhenDone = false,
52 nsISerialEventTarget* mainThreadTarget = nullptr);
54 using PeekSegmentFun = void (*)(void*, const uint8_t*, uint32_t);
55 /**
56 * Peek into the first chunk of data that's in the stream. Note that this
57 * method will not call the callback when there is no data in the stream.
58 * The callback will be called at most once.
60 * The data from the stream will not be consumed, i.e. the pump's listener
61 * can still read all the data
63 * Do not call before asyncRead. Do not call after onStopRequest.
65 nsresult PeekStream(PeekSegmentFun callback, void* closure);
67 /**
68 * Dispatched (to the main thread) by OnStateStop if it's called off main
69 * thread. Updates mState based on return value of OnStateStop.
71 nsresult CallOnStateStop();
73 protected:
74 enum { STATE_IDLE, STATE_START, STATE_TRANSFER, STATE_STOP, STATE_DEAD };
76 nsresult EnsureWaiting();
77 uint32_t OnStateStart();
78 uint32_t OnStateTransfer();
79 uint32_t OnStateStop();
80 nsresult CreateBufferedStreamIfNeeded() MOZ_REQUIRES(mMutex);
82 // This should optimize away in non-DEBUG builds
83 MOZ_ALWAYS_INLINE void AssertOnThread() const MOZ_REQUIRES(mMutex) {
84 if (mOffMainThread) {
85 MOZ_ASSERT(mTargetThread->IsOnCurrentThread());
86 } else {
87 MOZ_ASSERT(NS_IsMainThread());
91 uint32_t mState MOZ_GUARDED_BY(mMutex){STATE_IDLE};
92 nsCOMPtr<nsILoadGroup> mLoadGroup MOZ_GUARDED_BY(mMutex);
93 // mListener is written on a single thread (either MainThread or an
94 // off-MainThread thread), read from that thread and perhaps others (in
95 // RetargetDeliveryTo)
96 nsCOMPtr<nsIStreamListener> mListener MOZ_GUARDED_BY(mMutex);
97 nsCOMPtr<nsISerialEventTarget> mTargetThread MOZ_GUARDED_BY(mMutex);
98 nsCOMPtr<nsISerialEventTarget> mLabeledMainThreadTarget
99 MOZ_GUARDED_BY(mMutex);
100 nsCOMPtr<nsIInputStream> mStream MOZ_GUARDED_BY(mMutex);
101 // mAsyncStream is written on a single thread (either MainThread or an
102 // off-MainThread thread), and lives from AsyncRead() to OnStateStop().
103 nsCOMPtr<nsIAsyncInputStream> mAsyncStream MOZ_GUARDED_BY(mMutex);
104 uint64_t mStreamOffset MOZ_GUARDED_BY(mMutex){0};
105 uint64_t mStreamLength MOZ_GUARDED_BY(mMutex){0};
106 uint32_t mSegSize MOZ_GUARDED_BY(mMutex){0};
107 uint32_t mSegCount MOZ_GUARDED_BY(mMutex){0};
108 nsresult mStatus MOZ_GUARDED_BY(mMutex){NS_OK};
109 uint32_t mSuspendCount MOZ_GUARDED_BY(mMutex){0};
110 uint32_t mLoadFlags MOZ_GUARDED_BY(mMutex){LOAD_NORMAL};
111 bool mIsPending MOZ_GUARDED_BY(mMutex){false};
112 // True while in OnInputStreamReady, calling OnStateStart, OnStateTransfer
113 // and OnStateStop. Used to prevent calls to AsyncWait during callbacks.
114 bool mProcessingCallbacks MOZ_GUARDED_BY(mMutex){false};
115 // True if waiting on the "input stream ready" callback.
116 bool mWaitingForInputStreamReady MOZ_GUARDED_BY(mMutex){false};
117 bool mCloseWhenDone MOZ_GUARDED_BY(mMutex){false};
118 bool mRetargeting MOZ_GUARDED_BY(mMutex){false};
119 bool mAsyncStreamIsBuffered MOZ_GUARDED_BY(mMutex){false};
120 // Indicate whether nsInputStreamPump is used completely off main thread.
121 // If true, OnStateStop() is executed off main thread. Set at creation.
122 const bool mOffMainThread;
123 // Protects state/member var accesses across multiple threads.
124 mozilla::RecursiveMutex mMutex{"nsInputStreamPump"};
127 NS_DEFINE_STATIC_IID_ACCESSOR(nsInputStreamPump, NS_INPUT_STREAM_PUMP_IID)
129 #endif // !nsInputStreamChannel_h__