mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
182 lines
6.5 KiB
C
182 lines
6.5 KiB
C
|
/* -*- 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 https://mozilla.org/MPL/2.0/. */
|
||
|
|
||
|
#ifndef mozilla_ipc_DataPipe_h
|
||
|
#define mozilla_ipc_DataPipe_h
|
||
|
|
||
|
#include "mozilla/ipc/SharedMemoryBasic.h"
|
||
|
#include "mozilla/ipc/NodeController.h"
|
||
|
#include "nsIAsyncInputStream.h"
|
||
|
#include "nsIAsyncOutputStream.h"
|
||
|
#include "nsIIPCSerializableInputStream.h"
|
||
|
#include "nsISupports.h"
|
||
|
|
||
|
namespace mozilla {
|
||
|
namespace ipc {
|
||
|
|
||
|
namespace data_pipe_detail {
|
||
|
|
||
|
class DataPipeAutoLock;
|
||
|
class DataPipeLink;
|
||
|
|
||
|
class DataPipeBase {
|
||
|
public:
|
||
|
DataPipeBase(const DataPipeBase&) = delete;
|
||
|
DataPipeBase& operator=(const DataPipeBase&) = delete;
|
||
|
|
||
|
protected:
|
||
|
explicit DataPipeBase(bool aReceiverSide, nsresult aError);
|
||
|
DataPipeBase(bool aReceiverSide, ScopedPort aPort, SharedMemory* aShmem,
|
||
|
uint32_t aCapacity, nsresult aPeerStatus, uint32_t aOffset,
|
||
|
uint32_t aAvailable);
|
||
|
|
||
|
void CloseInternal(DataPipeAutoLock&, nsresult aStatus);
|
||
|
|
||
|
void AsyncWaitInternal(already_AddRefed<nsIRunnable> aCallback,
|
||
|
already_AddRefed<nsIEventTarget> aTarget,
|
||
|
bool aClosureOnly);
|
||
|
|
||
|
// Like `nsWriteSegmentFun` or `nsReadSegmentFun`.
|
||
|
using ProcessSegmentFun =
|
||
|
FunctionRef<nsresult(Span<char> aSpan, uint32_t aProcessedThisCall,
|
||
|
uint32_t* aProcessedCount)>;
|
||
|
nsresult ProcessSegmentsInternal(uint32_t aCount,
|
||
|
ProcessSegmentFun aProcessSegment,
|
||
|
uint32_t* aProcessedCount);
|
||
|
|
||
|
nsresult CheckStatus(DataPipeAutoLock&);
|
||
|
|
||
|
nsCString Describe(DataPipeAutoLock&);
|
||
|
|
||
|
virtual ~DataPipeBase();
|
||
|
|
||
|
const std::shared_ptr<Mutex> mMutex;
|
||
|
nsresult mStatus = NS_OK;
|
||
|
RefPtr<DataPipeLink> mLink;
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
void DataPipeWrite(IPC::Message* aMsg, T* aParam);
|
||
|
|
||
|
template <typename T>
|
||
|
bool DataPipeRead(const IPC::Message* aMsg, PickleIterator* aIter,
|
||
|
RefPtr<T>* aResult);
|
||
|
|
||
|
} // namespace data_pipe_detail
|
||
|
|
||
|
class DataPipeSender;
|
||
|
class DataPipeReceiver;
|
||
|
|
||
|
#define NS_DATAPIPESENDER_IID \
|
||
|
{ \
|
||
|
0x6698ed77, 0x9fff, 0x425d, { \
|
||
|
0xb0, 0xa6, 0x1d, 0x30, 0x66, 0xee, 0xb8, 0x16 \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
// Helper class for streaming data to another process.
|
||
|
class DataPipeSender final : public nsIAsyncOutputStream,
|
||
|
public data_pipe_detail::DataPipeBase {
|
||
|
public:
|
||
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATAPIPESENDER_IID)
|
||
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||
|
NS_DECL_NSIOUTPUTSTREAM
|
||
|
NS_DECL_NSIASYNCOUTPUTSTREAM
|
||
|
|
||
|
private:
|
||
|
friend nsresult NewDataPipe(uint32_t, DataPipeSender**, DataPipeReceiver**);
|
||
|
friend void data_pipe_detail::DataPipeWrite<DataPipeSender>(
|
||
|
IPC::Message* aMsg, DataPipeSender* aParam);
|
||
|
friend bool data_pipe_detail::DataPipeRead<DataPipeSender>(
|
||
|
const IPC::Message* aMsg, PickleIterator* aIter,
|
||
|
RefPtr<DataPipeSender>* aResult);
|
||
|
|
||
|
explicit DataPipeSender(nsresult aError)
|
||
|
: data_pipe_detail::DataPipeBase(/* aReceiverSide */ false, aError) {}
|
||
|
DataPipeSender(ScopedPort aPort, SharedMemory* aShmem, uint32_t aCapacity,
|
||
|
nsresult aPeerStatus, uint32_t aOffset, uint32_t aAvailable)
|
||
|
: data_pipe_detail::DataPipeBase(/* aReceiverSide */ false,
|
||
|
std::move(aPort), aShmem, aCapacity,
|
||
|
aPeerStatus, aOffset, aAvailable) {}
|
||
|
|
||
|
~DataPipeSender() = default;
|
||
|
};
|
||
|
|
||
|
NS_DEFINE_STATIC_IID_ACCESSOR(DataPipeSender, NS_DATAPIPESENDER_IID)
|
||
|
|
||
|
#define NS_DATAPIPERECEIVER_IID \
|
||
|
{ \
|
||
|
0x0a185f83, 0x499e, 0x450c, { \
|
||
|
0x95, 0x82, 0x27, 0x67, 0xad, 0x6d, 0x64, 0xb5 \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
// Helper class for streaming data from another process.
|
||
|
class DataPipeReceiver final : public nsIAsyncInputStream,
|
||
|
public nsIIPCSerializableInputStream,
|
||
|
public data_pipe_detail::DataPipeBase {
|
||
|
public:
|
||
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATAPIPERECEIVER_IID)
|
||
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||
|
NS_DECL_NSIINPUTSTREAM
|
||
|
NS_DECL_NSIASYNCINPUTSTREAM
|
||
|
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||
|
|
||
|
private:
|
||
|
friend nsresult NewDataPipe(uint32_t, DataPipeSender**, DataPipeReceiver**);
|
||
|
friend void data_pipe_detail::DataPipeWrite<DataPipeReceiver>(
|
||
|
IPC::Message* aMsg, DataPipeReceiver* aParam);
|
||
|
friend bool data_pipe_detail::DataPipeRead<DataPipeReceiver>(
|
||
|
const IPC::Message* aMsg, PickleIterator* aIter,
|
||
|
RefPtr<DataPipeReceiver>* aResult);
|
||
|
|
||
|
explicit DataPipeReceiver(nsresult aError)
|
||
|
: data_pipe_detail::DataPipeBase(/* aReceiverSide */ true, aError) {}
|
||
|
DataPipeReceiver(ScopedPort aPort, SharedMemory* aShmem, uint32_t aCapacity,
|
||
|
nsresult aPeerStatus, uint32_t aOffset, uint32_t aAvailable)
|
||
|
: data_pipe_detail::DataPipeBase(/* aReceiverSide */ true,
|
||
|
std::move(aPort), aShmem, aCapacity,
|
||
|
aPeerStatus, aOffset, aAvailable) {}
|
||
|
|
||
|
~DataPipeReceiver() = default;
|
||
|
};
|
||
|
|
||
|
NS_DEFINE_STATIC_IID_ACCESSOR(DataPipeReceiver, NS_DATAPIPERECEIVER_IID)
|
||
|
|
||
|
constexpr uint32_t kDefaultDataPipeCapacity = 64 * 1024;
|
||
|
|
||
|
/**
|
||
|
* Create a new DataPipe pair. The sender and receiver ends of the pipe may be
|
||
|
* used to transfer data between processes. |aCapacity| is the capacity of the
|
||
|
* underlying ring buffer. If `0` is passed, `kDefaultDataPipeCapacity` will be
|
||
|
* used.
|
||
|
*/
|
||
|
nsresult NewDataPipe(uint32_t aCapacity, DataPipeSender** aSender,
|
||
|
DataPipeReceiver** aReceiver);
|
||
|
|
||
|
} // namespace ipc
|
||
|
} // namespace mozilla
|
||
|
|
||
|
namespace IPC {
|
||
|
|
||
|
template <>
|
||
|
struct ParamTraits<mozilla::ipc::DataPipeSender*> {
|
||
|
static void Write(Message* aMsg, mozilla::ipc::DataPipeSender* aParam);
|
||
|
static bool Read(const Message* aMsg, PickleIterator* aIter,
|
||
|
RefPtr<mozilla::ipc::DataPipeSender>* aResult);
|
||
|
};
|
||
|
|
||
|
template <>
|
||
|
struct ParamTraits<mozilla::ipc::DataPipeReceiver*> {
|
||
|
static void Write(Message* aMsg, mozilla::ipc::DataPipeReceiver* aParam);
|
||
|
static bool Read(const Message* aMsg, PickleIterator* aIter,
|
||
|
RefPtr<mozilla::ipc::DataPipeReceiver>* aResult);
|
||
|
};
|
||
|
|
||
|
} // namespace IPC
|
||
|
|
||
|
#endif // mozilla_ipc_DataPipe_h
|