Files
tubestation/netwerk/base/nsInputStreamPump.h
serge-sans-paille bf3516e81e Bug 1964489 - Avoid duplication in NS_DECLARE_STATIC_IID_ACCESSOR / NS_DEFINE_STATIC_IID_ACCESSOR r=nika,necko-reviewers,media-playback-reviewers,places-reviewers,win-reviewers,dom-storage-reviewers,xpcom-reviewers,gstoll,janv,emilio,padenot,valentin,asuth
In modern C++, static constexpr member variables are automatically
inline (aka weak) so the template trick is not needed. This also avoid
duplication and reduces the amount of parsed code. No impact on
generated binary (actually: smaller debuginfo, close to identical
binary).

Differential Revision: https://phabricator.services.mozilla.com/D247825
2025-05-08 08:05:51 +00:00

124 lines
4.9 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsInputStreamPump_h__
#define nsInputStreamPump_h__
#include "nsIInputStreamPump.h"
#include "nsIAsyncInputStream.h"
#include "nsIThreadRetargetableRequest.h"
#include "nsCOMPtr.h"
#include "mozilla/Attributes.h"
#include "mozilla/RecursiveMutex.h"
#ifdef DEBUG
# include "MainThreadUtils.h"
# include "nsISerialEventTarget.h"
#endif
class nsIInputStream;
class nsILoadGroup;
class nsIStreamListener;
#define NS_INPUT_STREAM_PUMP_IID \
{0x42f1cc9b, 0xdf5f, 0x4c9b, {0xbd, 0x71, 0x8d, 0x4a, 0xe2, 0x27, 0xc1, 0x8a}}
class nsInputStreamPump final : public nsIInputStreamPump,
public nsIInputStreamCallback,
public nsIThreadRetargetableRequest {
~nsInputStreamPump() = default;
public:
using RecursiveMutexAutoLock = mozilla::RecursiveMutexAutoLock;
using RecursiveMutexAutoUnlock = mozilla::RecursiveMutexAutoUnlock;
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSIINPUTSTREAMPUMP
NS_DECL_NSIINPUTSTREAMCALLBACK
NS_DECL_NSITHREADRETARGETABLEREQUEST
NS_INLINE_DECL_STATIC_IID(NS_INPUT_STREAM_PUMP_IID)
nsInputStreamPump();
static nsresult Create(nsInputStreamPump** result, nsIInputStream* stream,
uint32_t segsize = 0, uint32_t segcount = 0,
bool closeWhenDone = false,
nsISerialEventTarget* mainThreadTarget = nullptr);
using PeekSegmentFun = void (*)(void*, const uint8_t*, uint32_t);
/**
* Peek into the first chunk of data that's in the stream. Note that this
* method will not call the callback when there is no data in the stream.
* The callback will be called at most once.
*
* The data from the stream will not be consumed, i.e. the pump's listener
* can still read all the data
*
* Do not call before asyncRead. Do not call after onStopRequest.
*/
nsresult PeekStream(PeekSegmentFun callback, void* closure);
/**
* Dispatched (to the main thread) by OnStateStop if it's called off main
* thread. Updates mState based on return value of OnStateStop.
*/
nsresult CallOnStateStop();
protected:
enum { STATE_IDLE, STATE_START, STATE_TRANSFER, STATE_STOP, STATE_DEAD };
nsresult EnsureWaiting();
uint32_t OnStateStart();
uint32_t OnStateTransfer();
uint32_t OnStateStop();
nsresult CreateBufferedStreamIfNeeded() MOZ_REQUIRES(mMutex);
// This should optimize away in non-DEBUG builds
MOZ_ALWAYS_INLINE void AssertOnThread() const MOZ_REQUIRES(mMutex) {
if (mOffMainThread) {
MOZ_ASSERT(mTargetThread->IsOnCurrentThread());
} else {
MOZ_ASSERT(NS_IsMainThread());
}
}
uint32_t mState MOZ_GUARDED_BY(mMutex){STATE_IDLE};
nsCOMPtr<nsILoadGroup> mLoadGroup MOZ_GUARDED_BY(mMutex);
// mListener is written on a single thread (either MainThread or an
// off-MainThread thread), read from that thread and perhaps others (in
// RetargetDeliveryTo)
nsCOMPtr<nsIStreamListener> mListener MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsISerialEventTarget> mTargetThread MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsISerialEventTarget> mLabeledMainThreadTarget
MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsIInputStream> mStream MOZ_GUARDED_BY(mMutex);
// mAsyncStream is written on a single thread (either MainThread or an
// off-MainThread thread), and lives from AsyncRead() to OnStateStop().
nsCOMPtr<nsIAsyncInputStream> mAsyncStream MOZ_GUARDED_BY(mMutex);
uint64_t mStreamOffset MOZ_GUARDED_BY(mMutex){0};
uint64_t mStreamLength MOZ_GUARDED_BY(mMutex){0};
uint32_t mSegSize MOZ_GUARDED_BY(mMutex){0};
uint32_t mSegCount MOZ_GUARDED_BY(mMutex){0};
nsresult mStatus MOZ_GUARDED_BY(mMutex){NS_OK};
uint32_t mSuspendCount MOZ_GUARDED_BY(mMutex){0};
uint32_t mLoadFlags MOZ_GUARDED_BY(mMutex){LOAD_NORMAL};
bool mIsPending MOZ_GUARDED_BY(mMutex){false};
// True while in OnInputStreamReady, calling OnStateStart, OnStateTransfer
// and OnStateStop. Used to prevent calls to AsyncWait during callbacks.
bool mProcessingCallbacks MOZ_GUARDED_BY(mMutex){false};
// True if waiting on the "input stream ready" callback.
bool mWaitingForInputStreamReady MOZ_GUARDED_BY(mMutex){false};
bool mCloseWhenDone MOZ_GUARDED_BY(mMutex){false};
bool mRetargeting MOZ_GUARDED_BY(mMutex){false};
bool mAsyncStreamIsBuffered MOZ_GUARDED_BY(mMutex){false};
// Indicate whether nsInputStreamPump is used completely off main thread.
// If true, OnStateStop() is executed off main thread. Set at creation.
const bool mOffMainThread;
// Protects state/member var accesses across multiple threads.
mozilla::RecursiveMutex mMutex{"nsInputStreamPump"};
};
#endif // !nsInputStreamChannel_h__