forked from mozilla/gecko-dev
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Blob.h
220 lines (176 loc) · 5.95 KB
/
Blob.h
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=4 ts=8 et tw=80 : */
/* 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 mozilla_dom_ipc_Blob_h
#define mozilla_dom_ipc_Blob_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/PBlobChild.h"
#include "mozilla/dom/PBlobParent.h"
#include "mozilla/dom/PBlobStreamChild.h"
#include "mozilla/dom/PBlobStreamParent.h"
#include "mozilla/dom/PContent.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
class nsIDOMBlob;
class nsIIPCSerializableInputStream;
class nsIInputStream;
namespace mozilla {
namespace dom {
namespace ipc {
enum ActorFlavorEnum
{
Parent = 0,
Child
};
template <ActorFlavorEnum>
struct BlobTraits
{ };
template <>
struct BlobTraits<Parent>
{
typedef mozilla::dom::PBlobParent ProtocolType;
typedef mozilla::dom::PBlobStreamParent StreamType;
// BaseType on the parent side is a bit more complicated than for the child
// side. In the case of nsIInputStreams backed by files we need to ensure that
// the files are actually opened and closed on a background thread before we
// can send their file handles across to the child. The child process could
// crash during this process so we need to make sure we cancel the intended
// response in such a case. We do that by holding an array of
// nsRevocableEventPtr. If the child crashes then this actor will be destroyed
// and the nsRevocableEventPtr destructor will cancel any stream events that
// are currently in flight.
class BaseType : public ProtocolType
{
protected:
BaseType()
{ }
virtual ~BaseType()
{ }
// Each instance of this class will be dispatched to the network stream
// thread pool to run the first time where it will open the file input
// stream. It will then dispatch itself back to the main thread to send the
// child process its response (assuming that the child has not crashed). The
// runnable will then dispatch itself to the thread pool again in order to
// close the file input stream.
class OpenStreamRunnable : public nsRunnable
{
friend class nsRevocableEventPtr<OpenStreamRunnable>;
public:
NS_DECL_NSIRUNNABLE
OpenStreamRunnable(BaseType* aOwner, StreamType* aActor,
nsIInputStream* aStream,
nsIIPCSerializableInputStream* aSerializable,
nsIEventTarget* aTarget);
private:
#ifdef DEBUG
void
Revoke();
#else
void
Revoke()
{
mRevoked = true;
}
#endif
// Only safe to access these two pointers if mRevoked is false!
BaseType* mOwner;
StreamType* mActor;
nsCOMPtr<nsIInputStream> mStream;
nsCOMPtr<nsIIPCSerializableInputStream> mSerializable;
nsCOMPtr<nsIEventTarget> mTarget;
bool mRevoked;
bool mClosing;
};
friend class OpenStreamRunnable;
void
NoteRunnableCompleted(OpenStreamRunnable* aRunnable);
nsTArray<nsRevocableEventPtr<OpenStreamRunnable> > mOpenStreamRunnables;
};
};
template <>
struct BlobTraits<Child>
{
typedef mozilla::dom::PBlobChild ProtocolType;
typedef mozilla::dom::PBlobStreamChild StreamType;
class BaseType : public ProtocolType
{
protected:
BaseType()
{ }
virtual ~BaseType()
{ }
};
};
template <ActorFlavorEnum>
class RemoteBlob;
template <ActorFlavorEnum ActorFlavor>
class Blob : public BlobTraits<ActorFlavor>::BaseType
{
friend class RemoteBlob<ActorFlavor>;
public:
typedef typename BlobTraits<ActorFlavor>::ProtocolType ProtocolType;
typedef typename BlobTraits<ActorFlavor>::StreamType StreamType;
typedef typename BlobTraits<ActorFlavor>::BaseType BaseType;
typedef RemoteBlob<ActorFlavor> RemoteBlobType;
typedef mozilla::ipc::IProtocolManager<
mozilla::ipc::RPCChannel::RPCListener>::ActorDestroyReason
ActorDestroyReason;
typedef mozilla::dom::BlobConstructorParams BlobConstructorParams;
protected:
nsIDOMBlob* mBlob;
RemoteBlobType* mRemoteBlob;
bool mOwnsBlob;
bool mBlobIsFile;
public:
// This create function is called on the sending side.
static Blob*
Create(nsIDOMBlob* aBlob)
{
return new Blob(aBlob);
}
// This create function is called on the receiving side.
static Blob*
Create(const BlobConstructorParams& aParams);
// Get the blob associated with this actor. This may always be called on the
// sending side. It may also be called on the receiving side unless this is a
// "mystery" blob that has not yet received a SetMysteryBlobInfo() call.
already_AddRefed<nsIDOMBlob>
GetBlob();
// Use this for files.
bool
SetMysteryBlobInfo(const nsString& aName, const nsString& aContentType,
uint64_t aLength);
// Use this for non-file blobs.
bool
SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength);
private:
// This constructor is called on the sending side.
Blob(nsIDOMBlob* aBlob);
// This constructor is called on the receiving side.
Blob(const BlobConstructorParams& aParams);
void
SetRemoteBlob(nsRefPtr<RemoteBlobType>& aRemoteBlob);
void
NoteDyingRemoteBlob();
// These methods are only called by the IPDL message machinery.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool
RecvResolveMystery(const ResolveMysteryParams& aParams) MOZ_OVERRIDE;
virtual bool
RecvPBlobStreamConstructor(StreamType* aActor) MOZ_OVERRIDE;
virtual StreamType*
AllocPBlobStream() MOZ_OVERRIDE;
virtual bool
DeallocPBlobStream(StreamType* aActor) MOZ_OVERRIDE;
};
} // namespace ipc
typedef mozilla::dom::ipc::Blob<mozilla::dom::ipc::Child> BlobChild;
typedef mozilla::dom::ipc::Blob<mozilla::dom::ipc::Parent> BlobParent;
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_Blob_h