This repository was archived by the owner on Jul 9, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Expand file tree
/
Copy pathIPCStreamSource.h
More file actions
141 lines (107 loc) · 4.79 KB
/
Copy pathIPCStreamSource.h
File metadata and controls
141 lines (107 loc) · 4.79 KB
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
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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_ipc_IPCStreamSource_h
#define mozilla_ipc_IPCStreamSource_h
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/dom/WorkerRef.h"
class nsIAsyncInputStream;
namespace mozilla {
namespace dom {
class ContentChild;
class ContentParent;
} // namespace dom
namespace wr {
struct ByteBuffer;
} // namespace wr
namespace ipc {
class PBackgroundChild;
class PBackgroundParent;
class PChildToParentStreamChild;
class PParentToChildStreamParent;
// The IPCStream IPC actor is designed to push an nsIInputStream from child to
// parent or parent to child incrementally. This is mainly needed for streams
// such as nsPipe that may not yet have all their data available when the
// stream must be sent across an IPC boundary. While many streams are handled
// by SerializeInputStream(), these streams cannot be serialized and must be
// sent using this actor.
//
// The IPCStream actor only support async, non-blocking streams because they
// must be read inline on the main thread and Worker threads.
//
// In general, the creation and handling of the IPCStream actor cannot be
// abstracted away behind SerializeInputStream() because the actor must be
// carefully managed. Specifically:
//
// 1) The data flow must be explicitly initiated by calling
// IPCStreamSource{Child,Parent}::Start() after the actor has been sent to
// the other-side actor.
// 2) If the actor is never sent to the other-side, then this code must
// call IPCStreamSource{Child,Parent}::StartDestroy() to avoid memory leaks.
// 3) The IPCStreamSource actor can only be used on threads that can be
// guaranteed to stay alive as long as the actor is alive. Right now
// this limits IPCStream to the main thread and Worker threads.
//
// In general you should probably use the AutoIPCStreamSource RAII class
// defined in InputStreamUtils.h instead of using IPCStreamSource directly.
class IPCStreamSource {
public:
// Create a IPCStreamSource using a PContent IPC manager on the
// main thread. This can return nullptr if the provided stream is
// blocking.
static PChildToParentStreamChild* Create(nsIAsyncInputStream* aInputStream,
dom::ContentChild* aManager);
// Create a IPCStreamSource using a PBackground IPC manager on the
// main thread or a Worker thread. This can return nullptr if the provided
// stream is blocking or if the Worker thread is already shutting down.
static PChildToParentStreamChild* Create(nsIAsyncInputStream* aInputStream,
PBackgroundChild* aManager);
// Create a IPCStreamSource using a PContent IPC manager on the
// main thread. This can return nullptr if the provided stream is
// blocking.
static PParentToChildStreamParent* Create(nsIAsyncInputStream* aInputStream,
dom::ContentParent* aManager);
// Create a IPCStreamSource using a PBackground IPC manager on the
// main thread or a Worker thread. This can return nullptr if the provided
// stream is blocking or if the Worker thread is already shutting down.
static PParentToChildStreamParent* Create(nsIAsyncInputStream* aInputStream,
PBackgroundParent* aManager);
static IPCStreamSource* Cast(PChildToParentStreamChild* aActor);
static IPCStreamSource* Cast(PParentToChildStreamParent* aActor);
// Start reading data from the nsIAsyncInputStream used to create the actor.
// This must be called after the actor is passed to the parent. If you
// use AutoIPCStream this is handled automatically.
void Start();
// Start cleaning up the actor. This must be called if the actor is never
// sent to the other side. If you use AutoIPCStream this is handled
// automatically.
void StartDestroy();
protected:
IPCStreamSource(nsIAsyncInputStream* aInputStream);
virtual ~IPCStreamSource();
bool Initialize();
void ActorDestroyed();
void OnEnd(nsresult aRv);
virtual void Close(nsresult aRv) = 0;
virtual void SendData(const wr::ByteBuffer& aBuffer) = 0;
void ActorConstructed();
private:
class Callback;
void DoRead();
void Wait();
void OnStreamReady(Callback* aCallback);
nsCOMPtr<nsIAsyncInputStream> mStream;
RefPtr<Callback> mCallback;
RefPtr<dom::StrongWorkerRef> mWorkerRef;
#ifdef DEBUG
protected:
#endif
enum { ePending, eActorConstructed, eClosed } mState;
private:
NS_DECL_OWNINGTHREAD
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_IPCStreamSource_h