summaryrefslogtreecommitdiff
path: root/netwerk/base/nsInputStreamPump.h
blob: c9b7bd64cca223aac7f8dbf47c0863d90c7c892c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/ReentrantMonitor.h"

class nsIInputStream;
class nsILoadGroup;
class nsIStreamListener;

class nsInputStreamPump final : public nsIInputStreamPump
                              , public nsIInputStreamCallback
                              , public nsIThreadRetargetableRequest
{
    ~nsInputStreamPump();

public:
    typedef mozilla::ReentrantMonitorAutoEnter ReentrantMonitorAutoEnter;
    NS_DECL_THREADSAFE_ISUPPORTS
    NS_DECL_NSIREQUEST
    NS_DECL_NSIINPUTSTREAMPUMP
    NS_DECL_NSIINPUTSTREAMCALLBACK
    NS_DECL_NSITHREADRETARGETABLEREQUEST

    nsInputStreamPump(); 

    static nsresult
                      Create(nsInputStreamPump  **result,
                             nsIInputStream      *stream,
                             int64_t              streamPos = -1,
                             int64_t              streamLen = -1,
                             uint32_t             segsize = 0,
                             uint32_t             segcount = 0,
                             bool                 closeWhenDone = false);

    typedef void (*PeekSegmentFun)(void *closure, const uint8_t *buf,
                                   uint32_t bufLen);
    /**
     * 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
    };

    nsresult EnsureWaiting();
    uint32_t OnStateStart();
    uint32_t OnStateTransfer();
    uint32_t OnStateStop();

    uint32_t                      mState;
    nsCOMPtr<nsILoadGroup>        mLoadGroup;
    nsCOMPtr<nsIStreamListener>   mListener;
    nsCOMPtr<nsISupports>         mListenerContext;
    nsCOMPtr<nsIEventTarget>      mTargetThread;
    nsCOMPtr<nsIInputStream>      mStream;
    nsCOMPtr<nsIAsyncInputStream> mAsyncStream;
    uint64_t                      mStreamOffset;
    uint64_t                      mStreamLength;
    uint32_t                      mSegSize;
    uint32_t                      mSegCount;
    nsresult                      mStatus;
    uint32_t                      mSuspendCount;
    uint32_t                      mLoadFlags;
    bool                          mIsPending;
    // True while in OnInputStreamReady, calling OnStateStart, OnStateTransfer
    // and OnStateStop. Used to prevent calls to AsyncWait during callbacks.
    bool                          mProcessingCallbacks;
    // True if waiting on the "input stream ready" callback.
    bool                          mWaitingForInputStreamReady;
    bool                          mCloseWhenDone;
    bool                          mRetargeting;
    // Protects state/member var accesses across multiple threads.
    mozilla::ReentrantMonitor     mMonitor;
};

#endif // !nsInputStreamChannel_h__