Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/base/nsRequestObserverProxy.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/. */
5
6
#include "mozilla/DebugOnly.h"
7
8
#include "nscore.h"
9
#include "nsRequestObserverProxy.h"
10
#include "nsIRequest.h"
11
#include "nsAutoPtr.h"
12
#include "mozilla/Logging.h"
13
#include "mozilla/IntegerPrintfMacros.h"
14
15
namespace mozilla {
16
namespace net {
17
18
static LazyLogModule gRequestObserverProxyLog("nsRequestObserverProxy");
19
20
#undef LOG
21
0
#define LOG(args) MOZ_LOG(gRequestObserverProxyLog, LogLevel::Debug, args)
22
23
//-----------------------------------------------------------------------------
24
// nsARequestObserverEvent internal class...
25
//-----------------------------------------------------------------------------
26
27
nsARequestObserverEvent::nsARequestObserverEvent(nsIRequest* request)
28
  : Runnable("net::nsARequestObserverEvent")
29
  , mRequest(request)
30
0
{
31
0
    MOZ_ASSERT(mRequest, "null pointer");
32
0
}
33
34
//-----------------------------------------------------------------------------
35
// nsOnStartRequestEvent internal class...
36
//-----------------------------------------------------------------------------
37
38
class nsOnStartRequestEvent : public nsARequestObserverEvent
39
{
40
    RefPtr<nsRequestObserverProxy> mProxy;
41
public:
42
    nsOnStartRequestEvent(nsRequestObserverProxy *proxy,
43
                          nsIRequest *request)
44
        : nsARequestObserverEvent(request)
45
        , mProxy(proxy)
46
0
    {
47
0
        MOZ_ASSERT(mProxy, "null pointer");
48
0
    }
49
50
0
    virtual ~nsOnStartRequestEvent() = default;
51
52
    NS_IMETHOD Run() override
53
0
    {
54
0
        LOG(("nsOnStartRequestEvent::HandleEvent [req=%p]\n", mRequest.get()));
55
0
56
0
        if (!mProxy->mObserver) {
57
0
            MOZ_ASSERT_UNREACHABLE("already handled onStopRequest event "
58
0
                                   "(observer is null)");
59
0
            return NS_OK;
60
0
        }
61
0
62
0
        LOG(("handle startevent=%p\n", this));
63
0
        nsresult rv = mProxy->mObserver->OnStartRequest(mRequest, mProxy->mContext);
64
0
        if (NS_FAILED(rv)) {
65
0
            LOG(("OnStartRequest failed [rv=%" PRIx32 "] canceling request!\n",
66
0
                 static_cast<uint32_t>(rv)));
67
0
            rv = mRequest->Cancel(rv);
68
0
            NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed for request!");
69
0
        }
70
0
71
0
        return NS_OK;
72
0
    }
73
};
74
75
//-----------------------------------------------------------------------------
76
// nsOnStopRequestEvent internal class...
77
//-----------------------------------------------------------------------------
78
79
class nsOnStopRequestEvent : public nsARequestObserverEvent
80
{
81
    RefPtr<nsRequestObserverProxy> mProxy;
82
public:
83
    nsOnStopRequestEvent(nsRequestObserverProxy *proxy,
84
                         nsIRequest *request)
85
        : nsARequestObserverEvent(request)
86
        , mProxy(proxy)
87
0
    {
88
0
        MOZ_ASSERT(mProxy, "null pointer");
89
0
    }
90
91
0
    virtual ~nsOnStopRequestEvent() = default;
92
93
    NS_IMETHOD Run() override
94
0
    {
95
0
        LOG(("nsOnStopRequestEvent::HandleEvent [req=%p]\n", mRequest.get()));
96
0
97
0
        nsMainThreadPtrHandle<nsIRequestObserver> observer = mProxy->mObserver;
98
0
        if (!observer) {
99
0
            MOZ_ASSERT_UNREACHABLE("already handled onStopRequest event "
100
0
                                   "(observer is null)");
101
0
            return NS_OK;
102
0
        }
103
0
        // Do not allow any more events to be handled after OnStopRequest
104
0
        mProxy->mObserver = nullptr;
105
0
106
0
        nsresult status = NS_OK;
107
0
        DebugOnly<nsresult> rv = mRequest->GetStatus(&status);
108
0
        NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed for request!");
109
0
110
0
        LOG(("handle stopevent=%p\n", this));
111
0
        (void) observer->OnStopRequest(mRequest, mProxy->mContext, status);
112
0
113
0
        return NS_OK;
114
0
    }
115
};
116
117
//-----------------------------------------------------------------------------
118
// nsRequestObserverProxy::nsISupports implementation...
119
//-----------------------------------------------------------------------------
120
121
NS_IMPL_ISUPPORTS(nsRequestObserverProxy,
122
                  nsIRequestObserver,
123
                  nsIRequestObserverProxy)
124
125
//-----------------------------------------------------------------------------
126
// nsRequestObserverProxy::nsIRequestObserver implementation...
127
//-----------------------------------------------------------------------------
128
129
NS_IMETHODIMP
130
nsRequestObserverProxy::OnStartRequest(nsIRequest *request,
131
                                       nsISupports *context)
132
0
{
133
0
    MOZ_ASSERT(!context || context == mContext);
134
0
    LOG(("nsRequestObserverProxy::OnStartRequest [this=%p req=%p]\n", this, request));
135
0
136
0
    nsOnStartRequestEvent *ev =
137
0
        new nsOnStartRequestEvent(this, request);
138
0
    if (!ev)
139
0
        return NS_ERROR_OUT_OF_MEMORY;
140
0
141
0
    LOG(("post startevent=%p\n", ev));
142
0
    nsresult rv = FireEvent(ev);
143
0
    if (NS_FAILED(rv))
144
0
        delete ev;
145
0
    return rv;
146
0
}
147
148
NS_IMETHODIMP
149
nsRequestObserverProxy::OnStopRequest(nsIRequest *request,
150
                                      nsISupports *context,
151
                                      nsresult status)
152
0
{
153
0
    MOZ_ASSERT(!context || context == mContext);
154
0
    LOG(("nsRequestObserverProxy: OnStopRequest [this=%p req=%p status=%" PRIx32 "]\n",
155
0
         this, request, static_cast<uint32_t>(status)));
156
0
157
0
    // The status argument is ignored because, by the time the OnStopRequestEvent
158
0
    // is actually processed, the status of the request may have changed :-(
159
0
    // To make sure that an accurate status code is always used, GetStatus() is
160
0
    // called when the OnStopRequestEvent is actually processed (see above).
161
0
162
0
    nsOnStopRequestEvent *ev =
163
0
        new nsOnStopRequestEvent(this, request);
164
0
    if (!ev)
165
0
        return NS_ERROR_OUT_OF_MEMORY;
166
0
167
0
    LOG(("post stopevent=%p\n", ev));
168
0
    nsresult rv = FireEvent(ev);
169
0
    if (NS_FAILED(rv))
170
0
        delete ev;
171
0
    return rv;
172
0
}
173
174
//-----------------------------------------------------------------------------
175
// nsRequestObserverProxy::nsIRequestObserverProxy implementation...
176
//-----------------------------------------------------------------------------
177
178
NS_IMETHODIMP
179
nsRequestObserverProxy::Init(nsIRequestObserver *observer, nsISupports *context)
180
0
{
181
0
    NS_ENSURE_ARG_POINTER(observer);
182
0
    mObserver = new nsMainThreadPtrHolder<nsIRequestObserver>(
183
0
      "nsRequestObserverProxy::mObserver", observer);
184
0
    mContext = new nsMainThreadPtrHolder<nsISupports>(
185
0
      "nsRequestObserverProxy::mContext", context);
186
0
187
0
    return NS_OK;
188
0
}
189
190
//-----------------------------------------------------------------------------
191
// nsRequestObserverProxy implementation...
192
//-----------------------------------------------------------------------------
193
194
nsresult
195
nsRequestObserverProxy::FireEvent(nsARequestObserverEvent *event)
196
0
{
197
0
    nsCOMPtr<nsIEventTarget> mainThread(GetMainThreadEventTarget());
198
0
    return mainThread->Dispatch(event, NS_DISPATCH_NORMAL);
199
0
}
200
201
} // namespace net
202
} // namespace mozilla