Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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/. */
7 #include "WMFSourceReaderCallback.h"
8 #include "WMFUtils.h"
10 namespace mozilla {
12 #ifdef PR_LOGGING
13 static PRLogModuleInfo* gWMFSourceReaderCallbackLog = nullptr;
14 #define WMF_CB_LOG(...) PR_LOG(gWMFSourceReaderCallbackLog, PR_LOG_DEBUG, (__VA_ARGS__))
15 #else
16 #define WMF_CB_LOG(...)
17 #endif
19 // IUnknown Methods
20 STDMETHODIMP
21 WMFSourceReaderCallback::QueryInterface(REFIID aIId, void **aInterface)
22 {
23 WMF_CB_LOG("WMFSourceReaderCallback::QueryInterface %s", GetGUIDName(aIId).get());
25 if (aIId == IID_IMFSourceReaderCallback) {
26 return DoGetInterface(static_cast<WMFSourceReaderCallback*>(this), aInterface);
27 }
28 if (aIId == IID_IUnknown) {
29 return DoGetInterface(static_cast<WMFSourceReaderCallback*>(this), aInterface);
30 }
32 *aInterface = nullptr;
33 return E_NOINTERFACE;
34 }
36 NS_IMPL_ADDREF(WMFSourceReaderCallback)
37 NS_IMPL_RELEASE(WMFSourceReaderCallback)
39 WMFSourceReaderCallback::WMFSourceReaderCallback()
40 : mMonitor("WMFSourceReaderCallback")
41 , mResultStatus(S_OK)
42 , mStreamFlags(0)
43 , mTimestamp(0)
44 , mSample(nullptr)
45 , mReadFinished(false)
46 {
47 #ifdef PR_LOGGING
48 if (!gWMFSourceReaderCallbackLog) {
49 gWMFSourceReaderCallbackLog = PR_NewLogModule("WMFSourceReaderCallback");
50 }
51 #endif
52 }
54 HRESULT
55 WMFSourceReaderCallback::NotifyReadComplete(HRESULT aReadStatus,
56 DWORD aStreamIndex,
57 DWORD aStreamFlags,
58 LONGLONG aTimestamp,
59 IMFSample *aSample)
60 {
61 // Note: aSample can be nullptr on success if more data is required!
62 ReentrantMonitorAutoEnter mon(mMonitor);
64 if (mSample) {
65 // The WMFReader should have called Wait() to retrieve the last
66 // sample returned by the last ReadSample() call, but if we're
67 // aborting the read before Wait() is called the sample ref
68 // can be non-null.
69 mSample->Release();
70 mSample = nullptr;
71 }
73 if (SUCCEEDED(aReadStatus)) {
74 if (aSample) {
75 mTimestamp = aTimestamp;
76 mSample = aSample;
77 mSample->AddRef();
78 }
79 }
81 mResultStatus = aReadStatus;
82 mStreamFlags = aStreamFlags;
84 // Set the sentinal value and notify the monitor, so that threads waiting
85 // in Wait() are awoken.
86 mReadFinished = true;
87 mon.NotifyAll();
89 return S_OK;
90 }
92 STDMETHODIMP
93 WMFSourceReaderCallback::OnReadSample(HRESULT aReadStatus,
94 DWORD aStreamIndex,
95 DWORD aStreamFlags,
96 LONGLONG aTimestamp,
97 IMFSample *aSample)
98 {
99 WMF_CB_LOG("WMFSourceReaderCallback::OnReadSample() hr=0x%x flags=0x%x time=%lld sample=%p",
100 aReadStatus, aStreamFlags, aTimestamp, aSample);
101 return NotifyReadComplete(aReadStatus,
102 aStreamIndex,
103 aStreamFlags,
104 aTimestamp,
105 aSample);
106 }
108 HRESULT
109 WMFSourceReaderCallback::Cancel()
110 {
111 WMF_CB_LOG("WMFSourceReaderCallback::Cancel()");
112 return NotifyReadComplete(E_ABORT,
113 0,
114 0,
115 0,
116 nullptr);
117 }
119 STDMETHODIMP
120 WMFSourceReaderCallback::OnEvent(DWORD, IMFMediaEvent *)
121 {
122 return S_OK;
123 }
125 STDMETHODIMP
126 WMFSourceReaderCallback::OnFlush(DWORD)
127 {
128 return S_OK;
129 }
131 HRESULT
132 WMFSourceReaderCallback::Wait(DWORD* aStreamFlags,
133 LONGLONG* aTimeStamp,
134 IMFSample** aSample)
135 {
136 ReentrantMonitorAutoEnter mon(mMonitor);
137 WMF_CB_LOG("WMFSourceReaderCallback::Wait() starting wait");
138 while (!mReadFinished) {
139 mon.Wait();
140 }
141 mReadFinished = false;
142 WMF_CB_LOG("WMFSourceReaderCallback::Wait() done waiting");
144 *aStreamFlags = mStreamFlags;
145 *aTimeStamp = mTimestamp;
146 *aSample = mSample;
147 HRESULT hr = mResultStatus;
149 mSample = nullptr;
150 mTimestamp = 0;
151 mStreamFlags = 0;
152 mResultStatus = S_OK;
154 return hr;
155 }
157 } // namespace mozilla