Bug 1621762 - Part 1: Basic refactoring of ProducerConsumerQueue & CommandQueue r=jgilbert

A lot of simple changes to prepare for later patches in the series:

* PcqCommand -> QueueCommand, PcqStatus -> QueueStatus, PcqParamTraits -> QueueParamTraits
* Consolidate BasicSink/Source into CommandSink/Source
* SyncCommandSource::mConsumer -> mResponseSink, SyncCommandSink::mProducer -> mResponseSource, CommandSource::mProducer -> mSource, CommandSink::mConsumer -> mSink
* Rename WebGLPcqParamTraits.h to WebGLQueueParamTraits.h
* ProducerConsumerQueue struct -> class.
* ProducerConsumerQueue::mProducer/mConsumer access -> ProducerConsumerQueue::TakeProducer/TakeConsumer
* Rename QueueStatus enum elements to follow style convention.
* Rename Status() to GetStatus() in ProducerView and ConsumerView to appease Linux.
* Rename CommandResult enum values to fit convention (and avoid Linux conflict with Success).

Differential Revision: https://phabricator.services.mozilla.com/D68256
This commit is contained in:
David Parks 2020-04-30 22:21:45 +00:00
Родитель 16a940c040
Коммит ac84c81927
8 изменённых файлов: 440 добавлений и 458 удалений

Просмотреть файл

@ -737,9 +737,9 @@ bool ClientWebGLContext::CreateHostContext(const uvec2& requestedSize) {
}
outOfProcess.mCommandSource = MakeUnique<ClientWebGLCommandSource>(
std::move(commandPcq->mProducer), std::move(responsePcq->mConsumer));
auto sink = MakeUnique<HostWebGLCommandSink>(
std::move(commandPcq->mConsumer), std::move(responsePcq->mProducer));
commandPcq->TakeProducer(), responsePcq->TakeConsumer());
auto sink = MakeUnique<HostWebGLCommandSink>(commandPcq->TakeConsumer(),
responsePcq->TakeProducer());
// Use the error/warning and command queues to construct a
// ClientWebGLContext in this process and a HostWebGLContext

Просмотреть файл

@ -2081,9 +2081,9 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
template <size_t command, typename... Args>
void DispatchAsync(Args&&... aArgs) const {
const auto& oop = *mNotLost->outOfProcess;
PcqStatus status = oop.mCommandSource->RunAsyncCommand(command, aArgs...);
if (!IsSuccess(status)) {
if (status == PcqStatus::PcqOOMError) {
QueueStatus status = oop.mCommandSource->RunAsyncCommand(command,
aArgs...);
if (!IsSuccess(status)) { if (status == QueueStatus::kOOMError) {
JsWarning("Ran out-of-memory during WebGL IPC.");
}
// Not much to do but shut down. Since this was a Pcq failure and
@ -2098,11 +2098,11 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
ReturnType DispatchSync(Args&&... aArgs) const {
const auto& oop = *mNotLost->outOfProcess;
ReturnType returnValue;
PcqStatus status =
QueueStatus status =
oop.mCommandSource->RunSyncCommand(command, returnValue, aArgs...);
if (!IsSuccess(status)) {
if (status == PcqStatus::PcqOOMError) {
if (status == QueueStatus::kOOMError) {
JsWarning("Ran out-of-memory during WebGL IPC.");
}
// Not much to do but shut down. Since this was a Pcq failure and
@ -2120,7 +2120,7 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
const auto status =
oop.mCommandSource->RunVoidSyncCommand(command, aArgs...);
if (!IsSuccess(status)) {
if (status == PcqStatus::PcqOOMError) {
if (status == QueueStatus::kOOMError) {
JsWarning("Ran out-of-memory during WebGL IPC.");
}
// Not much to do but shut down. Since this was a Pcq failure and

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -22,49 +22,17 @@ namespace mozilla {
using mozilla::ipc::IPDLParamTraits;
using mozilla::webgl::Consumer;
using mozilla::webgl::PcqStatus;
using mozilla::webgl::Producer;
using mozilla::webgl::ProducerConsumerQueue;
using mozilla::webgl::QueueStatus;
template <typename Derived, typename SinkType>
struct MethodDispatcher;
enum CommandResult { Success, TimeExpired, QueueEmpty, Error };
enum CommandResult { kSuccess, kTimeExpired, kQueueEmpty, kError };
enum CommandSyncType { ASYNC, SYNC };
class BasicSource {
public:
explicit BasicSource(UniquePtr<Producer>&& aProducer)
: mProducer(std::move(aProducer)) {
MOZ_ASSERT(mProducer);
}
virtual ~BasicSource() = default;
// For IPDL:
BasicSource() = default;
friend struct mozilla::ipc::IPDLParamTraits<BasicSource>;
protected:
UniquePtr<Producer> mProducer;
};
class BasicSink {
public:
explicit BasicSink(UniquePtr<Consumer>&& aConsumer)
: mConsumer(std::move(aConsumer)) {
MOZ_ASSERT(mConsumer);
}
virtual ~BasicSink() = default;
// For IPDL:
BasicSink() = default;
friend struct mozilla::ipc::IPDLParamTraits<BasicSink>;
protected:
UniquePtr<Consumer> mConsumer;
};
/**
* A CommandSource is obtained from a CommandQueue. Use it by inserting a
* command (represented by type Command) using InsertCommand, which also
@ -73,29 +41,35 @@ class BasicSink {
* to execute it.
*/
template <typename Command>
class CommandSource : public BasicSource {
class CommandSource {
public:
explicit CommandSource(UniquePtr<Producer>&& aProducer)
: BasicSource(std::move(aProducer)) {}
template <typename... Args>
PcqStatus InsertCommand(Command aCommand, Args&&... aArgs) {
return this->mProducer->TryWaitInsert(Nothing() /* wait forever */,
aCommand, aArgs...);
}
PcqStatus InsertCommand(Command aCommand) {
return this->mProducer->TryWaitInsert(Nothing() /* wait forever */,
aCommand);
explicit CommandSource(UniquePtr<Producer>&& aSource)
: mSource(std::move(aSource)) {
MOZ_ASSERT(mSource);
}
template <typename... Args>
PcqStatus RunCommand(Command aCommand, Args&&... aArgs) {
QueueStatus InsertCommand(Command aCommand, Args&&... aArgs) {
return this->mSource->TryWaitInsert(Nothing() /* wait forever */, aCommand,
aArgs...);
}
QueueStatus InsertCommand(Command aCommand) {
return this->mSource->TryWaitInsert(Nothing() /* wait forever */, aCommand);
}
template <typename... Args>
QueueStatus RunCommand(Command aCommand, Args&&... aArgs) {
return InsertCommand(aCommand, std::forward<Args>(aArgs)...);
}
// For IPDL:
CommandSource() = default;
protected:
friend struct IPDLParamTraits<mozilla::CommandSource<Command>>;
UniquePtr<Producer> mSource;
};
/**
@ -109,35 +83,36 @@ class CommandSource : public BasicSource {
* queue by calling the Dispatch methods in this class.
*/
template <typename Command>
class CommandSink : public BasicSink {
class CommandSink {
public:
explicit CommandSink(UniquePtr<Consumer>&& aConsumer)
: BasicSink(std::move(aConsumer)) {}
explicit CommandSink(UniquePtr<Consumer>&& aSink) : mSink(std::move(aSink)) {
MOZ_ASSERT(mSink);
}
/**
* Attempts to process the next command in the queue, if one is available.
*/
CommandResult ProcessOne(const Maybe<TimeDuration>& aTimeout) {
Command command;
PcqStatus status = (aTimeout.isNothing() || aTimeout.value())
? this->mConsumer->TryWaitRemove(aTimeout, command)
: this->mConsumer->TryRemove(command);
QueueStatus status = (aTimeout.isNothing() || aTimeout.value())
? this->mSink->TryWaitRemove(aTimeout, command)
: this->mSink->TryRemove(command);
if (status == PcqStatus::Success) {
if (status == QueueStatus::kSuccess) {
if (DispatchCommand(command)) {
return CommandResult::Success;
return CommandResult::kSuccess;
}
return CommandResult::Error;
return CommandResult::kError;
}
if (status == PcqStatus::PcqNotReady) {
return CommandResult::QueueEmpty;
if (status == QueueStatus::kNotReady) {
return CommandResult::kQueueEmpty;
}
if (status == PcqStatus::PcqOOMError) {
if (status == QueueStatus::kOOMError) {
ReportOOM();
}
return CommandResult::Error;
return CommandResult::kError;
}
CommandResult ProcessOneNow() { return ProcessOne(Some(TimeDuration(0))); }
@ -152,7 +127,7 @@ class CommandSink : public BasicSink {
CommandResult result;
do {
result = ProcessOneNow();
} while (result == CommandResult::Success);
} while (result == CommandResult::kSuccess);
return result;
}
@ -169,7 +144,8 @@ class CommandSink : public BasicSink {
do {
result = ProcessOne(Some(aDuration - (now - start)));
now = TimeStamp::Now();
} while ((result == CommandResult::Success) && ((now - start) < aDuration));
} while ((result == CommandResult::kSuccess) &&
((now - start) < aDuration));
return result;
}
@ -224,6 +200,8 @@ class CommandSink : public BasicSink {
}
protected:
friend struct IPDLParamTraits<mozilla::CommandSink<Command>>;
/**
* Implementations will usually be something like a big switch statement
* that calls one of the Dispatch methods in this class.
@ -237,19 +215,19 @@ class CommandSink : public BasicSink {
virtual void ReportOOM() {}
template <typename... Args, size_t... Indices>
PcqStatus CallTryRemove(std::tuple<Args...>& aArgs,
std::index_sequence<Indices...>) {
PcqStatus status = mConsumer->TryRemove(std::get<Indices>(aArgs)...);
QueueStatus CallTryRemove(std::tuple<Args...>& aArgs,
std::index_sequence<Indices...>) {
QueueStatus status = mSink->TryRemove(std::get<Indices>(aArgs)...);
// The CommandQueue inserts the command and the args together as an atomic
// operation. We already read the command so the args must also be
// available.
MOZ_ASSERT(status != PcqStatus::PcqNotReady);
MOZ_ASSERT(status != QueueStatus::kNotReady);
return status;
}
PcqStatus CallTryRemove(std::tuple<>& aArgs,
std::make_integer_sequence<size_t, 0>) {
return PcqStatus::Success;
QueueStatus CallTryRemove(std::tuple<>& aArgs,
std::make_integer_sequence<size_t, 0>) {
return QueueStatus::kSuccess;
}
template <typename T, typename MethodType, typename... Args,
@ -269,9 +247,12 @@ class CommandSink : public BasicSink {
template <typename... Args>
bool ReadArgs(std::tuple<Args...>& aArgs) {
PcqStatus status = CallTryRemove(aArgs, std::index_sequence_for<Args...>{});
QueueStatus status =
CallTryRemove(aArgs, std::index_sequence_for<Args...>{});
return IsSuccess(status);
}
UniquePtr<Consumer> mSink;
};
enum SyncResponse : uint8_t { RESPONSE_NAK, RESPONSE_ACK };
@ -289,23 +270,24 @@ class SyncCommandSource : public CommandSource<Command> {
SyncCommandSource(UniquePtr<Producer>&& aProducer,
UniquePtr<Consumer>&& aResponseConsumer)
: CommandSource<Command>(std::move(aProducer)),
mConsumer(std::move(aResponseConsumer)) {}
mResponseSink(std::move(aResponseConsumer)) {}
template <typename... Args>
PcqStatus RunAsyncCommand(Command aCommand, Args&&... aArgs) {
QueueStatus RunAsyncCommand(Command aCommand, Args&&... aArgs) {
return this->RunCommand(aCommand, std::forward<Args>(aArgs)...);
}
template <typename... Args>
PcqStatus RunVoidSyncCommand(Command aCommand, Args&&... aArgs) {
PcqStatus status = RunAsyncCommand(aCommand, std::forward<Args>(aArgs)...);
QueueStatus RunVoidSyncCommand(Command aCommand, Args&&... aArgs) {
QueueStatus status =
RunAsyncCommand(aCommand, std::forward<Args>(aArgs)...);
return IsSuccess(status) ? this->ReadSyncResponse() : status;
}
template <typename ResultType, typename... Args>
PcqStatus RunSyncCommand(Command aCommand, ResultType& aReturn,
Args&&... aArgs) {
PcqStatus status =
QueueStatus RunSyncCommand(Command aCommand, ResultType& aReturn,
Args&&... aArgs) {
QueueStatus status =
RunVoidSyncCommand(aCommand, std::forward<Args>(aArgs)...);
return IsSuccess(status) ? this->ReadResult(aReturn) : status;
}
@ -315,28 +297,28 @@ class SyncCommandSource : public CommandSource<Command> {
friend struct mozilla::ipc::IPDLParamTraits<SyncCommandSource<Command>>;
protected:
PcqStatus ReadSyncResponse() {
QueueStatus ReadSyncResponse() {
SyncResponse response;
PcqStatus status =
mConsumer->TryWaitRemove(Nothing() /* wait forever */, response);
MOZ_ASSERT(status != PcqStatus::PcqNotReady);
QueueStatus status =
mResponseSink->TryWaitRemove(Nothing() /* wait forever */, response);
MOZ_ASSERT(status != QueueStatus::kNotReady);
if (IsSuccess(status) && response != RESPONSE_ACK) {
return PcqStatus::PcqFatalError;
return QueueStatus::kFatalError;
}
return status;
}
template <typename T>
PcqStatus ReadResult(T& aResult) {
PcqStatus status = mConsumer->TryRemove(aResult);
QueueStatus ReadResult(T& aResult) {
QueueStatus status = mResponseSink->TryRemove(aResult);
// The Sink posts the response code and result as an atomic transaction. We
// already read the response code so the result must be available.
MOZ_ASSERT(status != PcqStatus::PcqNotReady);
MOZ_ASSERT(status != QueueStatus::kNotReady);
return status;
}
UniquePtr<Consumer> mConsumer;
UniquePtr<Consumer> mResponseSink;
};
/**
@ -352,9 +334,9 @@ class SyncCommandSink : public CommandSink<Command> {
public:
SyncCommandSink(UniquePtr<Consumer>&& aConsumer,
UniquePtr<Producer>&& aResponseProducer)
UniquePtr<Producer>&& aResponseSource)
: CommandSink<Command>(std::move(aConsumer)),
mProducer(std::move(aResponseProducer)) {}
mResponseSource(std::move(aResponseSource)) {}
// for IPDL:
SyncCommandSink() = default;
@ -491,7 +473,7 @@ class SyncCommandSink : public CommandSink<Command> {
protected:
template <typename... Args>
bool WriteArgs(const Args&... aArgs) {
return IsSuccess(mProducer->TryInsert(aArgs...));
return IsSuccess(mResponseSource->TryInsert(aArgs...));
}
template <typename... Args>
@ -505,7 +487,7 @@ class SyncCommandSink : public CommandSink<Command> {
return WriteArgs(nak);
}
UniquePtr<Producer> mProducer;
UniquePtr<Producer> mResponseSource;
};
/**
@ -536,27 +518,30 @@ struct MethodDispatcher {
using SinkType = _SinkType;
template <CommandSyncType syncType>
struct DispatchMethod;
/*
// Specialization for dispatching asynchronous methods
template <CommandSyncType SyncType>
struct DispatchMethod {
template <typename MethodType, typename ObjectType>
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType mMethod,
ObjectType& aObj) {
return aSink.DispatchMethod<SyncType>(aObj, mMethod);
}
};
};
// Specialization for dispatching synchronous methods
template <>
struct DispatchMethod<CommandSyncType::SYNC> {
template <typename MethodType, typename ObjectType>
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType aMethod,
ObjectType& aObj) {
return aSink.DispatchSyncMethod(aObj, aMethod);
}
};
*/
// Specialization for dispatching asynchronous methods
template <typename Derived, typename _SinkType>
template <>
struct MethodDispatcher<Derived,
_SinkType>::DispatchMethod<CommandSyncType::ASYNC> {
template <typename MethodType, typename ObjectType>
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType mMethod,
ObjectType& aObj) {
return aSink.DispatchAsyncMethod(aObj, mMethod);
}
};
// Specialization for dispatching synchronous methods
template <typename Derived, typename _SinkType>
template <>
struct MethodDispatcher<Derived,
_SinkType>::DispatchMethod<CommandSyncType::SYNC> {
template <typename MethodType, typename ObjectType>
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType aMethod,
ObjectType& aObj) {
return aSink.DispatchSyncMethod(aObj, aMethod);
}
};
// Declares a MethodDispatcher with the given name and CommandSink type.
@ -612,60 +597,46 @@ namespace ipc {
template <typename T>
struct IPDLParamTraits;
template <>
struct IPDLParamTraits<mozilla::BasicSource> {
template <typename Command>
struct IPDLParamTraits<mozilla::CommandSource<Command>> {
public:
typedef mozilla::BasicSource paramType;
typedef mozilla::CommandSource<Command> paramType;
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const paramType& aParam) {
MOZ_ASSERT(aParam.mProducer);
WriteIPDLParam(aMsg, aActor, *aParam.mProducer.get());
MOZ_ASSERT(aParam.mSource);
WriteIPDLParam(aMsg, aActor, *aParam.mSource.get());
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, paramType* aResult) {
Producer* producer = new Producer;
bool ret = ReadIPDLParam(aMsg, aIter, aActor, producer);
aResult->mProducer.reset(producer);
aResult->mSource.reset(producer);
return ret;
}
};
template <>
struct IPDLParamTraits<mozilla::BasicSink> {
template <typename Command>
struct IPDLParamTraits<mozilla::CommandSink<Command>> {
public:
typedef mozilla::BasicSink paramType;
typedef mozilla::CommandSink<Command> paramType;
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const paramType& aParam) {
MOZ_ASSERT(aParam.mConsumer);
WriteIPDLParam(aMsg, aActor, *aParam.mConsumer.get());
MOZ_ASSERT(aParam.mSink);
WriteIPDLParam(aMsg, aActor, *aParam.mSink.get());
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, paramType* aResult) {
Consumer* consumer = new Consumer;
bool ret = ReadIPDLParam(aMsg, aIter, aActor, consumer);
aResult->mConsumer.reset(consumer);
aResult->mSink.reset(consumer);
return ret;
}
};
template <typename Command>
struct IPDLParamTraits<mozilla::CommandSource<Command>>
: public IPDLParamTraits<mozilla::BasicSource> {
public:
typedef mozilla::CommandSource<Command> paramType;
};
template <typename Command>
struct IPDLParamTraits<mozilla::CommandSink<Command>>
: public IPDLParamTraits<mozilla::BasicSink> {
public:
typedef mozilla::CommandSink<Command> paramType;
};
template <typename Command>
struct IPDLParamTraits<mozilla::SyncCommandSource<Command>>
: public IPDLParamTraits<mozilla::CommandSource<Command>> {
@ -676,14 +647,14 @@ struct IPDLParamTraits<mozilla::SyncCommandSource<Command>>
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const paramType& aParam) {
WriteIPDLParam(aMsg, aActor, static_cast<const paramBaseType&>(aParam));
WriteIPDLParam(aMsg, aActor, aParam.mConsumer);
WriteIPDLParam(aMsg, aActor, aParam.mResponseSink);
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, paramType* aParam) {
bool result =
ReadIPDLParam(aMsg, aIter, aActor, static_cast<paramBaseType*>(aParam));
return result && ReadIPDLParam(aMsg, aIter, aActor, &aParam->mConsumer);
return result && ReadIPDLParam(aMsg, aIter, aActor, &aParam->mResponseSink);
}
};
@ -697,14 +668,15 @@ struct IPDLParamTraits<mozilla::SyncCommandSink<Command>>
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const paramType& aParam) {
WriteIPDLParam(aMsg, aActor, static_cast<const paramBaseType&>(aParam));
WriteIPDLParam(aMsg, aActor, aParam.mProducer);
WriteIPDLParam(aMsg, aActor, aParam.mResponseSource);
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, paramType* aParam) {
bool result =
ReadIPDLParam(aMsg, aIter, aActor, static_cast<paramBaseType*>(aParam));
return result && ReadIPDLParam(aMsg, aIter, aActor, &aParam->mProducer);
return result &&
ReadIPDLParam(aMsg, aIter, aActor, &aParam->mResponseSource);
}
};

Просмотреть файл

@ -29,7 +29,7 @@ using ClientWebGLCommandSource = SyncCommandSource<size_t>;
* then uses for executing methods. Add new commands to DispatchCommand using
* the WEBGL_SYNC_COMMAND and WEBGL_ASYNC_COMMAND macros.
*/
class HostWebGLCommandSink : public SyncCommandSink<size_t> {
class HostWebGLCommandSink final : public SyncCommandSink<size_t> {
public:
HostWebGLCommandSink(UniquePtr<Consumer>&& aConsumer,
UniquePtr<Producer>&& aResponseProducer)

Просмотреть файл

@ -9,7 +9,7 @@
#include "TexUnpackBlob.h"
#include "WebGLCrossProcessCommandQueue.h"
#include "HostWebGLContext.h"
#include "WebGLPcqParamTraits.h"
#include "WebGLQueueParamTraits.h"
namespace mozilla {

Просмотреть файл

@ -3,8 +3,8 @@
* 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 WEBGLPCQPARAMTRAITS_H_
#define WEBGLPCQPARAMTRAITS_H_
#ifndef WEBGLQUEUEPARAMTRAITS_H_
#define WEBGLQUEUEPARAMTRAITS_H_
#include <type_traits>
@ -17,7 +17,7 @@ namespace mozilla {
namespace webgl {
template <typename T>
struct PcqParamTraits;
struct QueueParamTraits;
template <>
struct IsTriviallySerializable<FloatOrInt> : std::true_type {};
@ -58,10 +58,10 @@ template <>
struct IsTriviallySerializable<webgl::TexUnpackBlob> : std::true_type {};
/*
template <>
struct PcqParamTraits<WebGLActiveInfo> {
struct QueueParamTraits<WebGLActiveInfo> {
using ParamType = WebGLActiveInfo;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
aProducerView.WriteParam(aArg.mElemCount);
aProducerView.WriteParam(aArg.mElemType);
aProducerView.WriteParam(aArg.mBaseUserName);
@ -71,7 +71,7 @@ struct PcqParamTraits<WebGLActiveInfo> {
return aProducerView.WriteParam(aArg.mBaseType);
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
aConsumerView.ReadParam(aArg ? &aArg->mElemCount : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mElemType : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mBaseUserName : nullptr);
@ -94,21 +94,21 @@ struct PcqParamTraits<WebGLActiveInfo> {
};
*/
template <typename T>
struct PcqParamTraits<RawBuffer<T>> {
struct QueueParamTraits<RawBuffer<T>> {
using ParamType = RawBuffer<T>;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
aProducerView.WriteParam(aArg.mLength);
return (aArg.mLength > 0)
? aProducerView.Write(aArg.mData, aArg.mLength * sizeof(T))
: aProducerView.Status();
: aProducerView.GetStatus();
}
template <
typename ElementType = std::remove_cv_t<typename ParamType::ElementType>>
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
size_t len;
PcqStatus status = aConsumerView.ReadParam(&len);
QueueStatus status = aConsumerView.ReadParam(&len);
if (!status) {
return status;
}
@ -118,7 +118,7 @@ struct PcqParamTraits<RawBuffer<T>> {
aArg->mLength = 0;
aArg->mData = nullptr;
}
return PcqStatus::Success;
return QueueStatus::kSuccess;
}
if (!aArg) {
@ -126,17 +126,17 @@ struct PcqParamTraits<RawBuffer<T>> {
}
struct RawBufferReadMatcher {
PcqStatus operator()(RefPtr<mozilla::ipc::SharedMemoryBasic>& smem) {
QueueStatus operator()(RefPtr<mozilla::ipc::SharedMemoryBasic>& smem) {
if (!smem) {
return PcqStatus::PcqFatalError;
return QueueStatus::kFatalError;
}
mArg->mSmem = smem;
mArg->mData = static_cast<ElementType*>(smem->memory());
mArg->mLength = mLength;
mArg->mOwnsData = false;
return PcqStatus::Success;
return QueueStatus::kSuccess;
}
PcqStatus operator()() {
QueueStatus operator()() {
mArg->mSmem = nullptr;
ElementType* buf = new ElementType[mLength];
mArg->mData = buf;
@ -165,16 +165,16 @@ struct PcqParamTraits<RawBuffer<T>> {
enum TexUnpackTypes : uint8_t { Bytes, Surface, Image, Pbo };
template <>
struct PcqParamTraits<webgl::TexUnpackBytes> {
struct QueueParamTraits<webgl::TexUnpackBytes> {
using ParamType = webgl::TexUnpackBytes;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
// Write TexUnpackBlob base class, then the RawBuffer.
aProducerView.WriteParam(static_cast<const webgl::TexUnpackBlob&>(aArg));
return aProducerView.WriteParam(aArg.mPtr);
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
// Read TexUnpackBlob base class, then the RawBuffer.
aConsumerView.ReadParam(static_cast<webgl::TexUnpackBlob*>(aArg));
return aConsumerView.ReadParam(aArg ? &aArg->mPtr : nullptr);
@ -188,10 +188,10 @@ struct PcqParamTraits<webgl::TexUnpackBytes> {
};
template <>
struct PcqParamTraits<webgl::TexUnpackSurface> {
struct QueueParamTraits<webgl::TexUnpackSurface> {
using ParamType = webgl::TexUnpackSurface;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
aProducerView.WriteParam(static_cast<const webgl::TexUnpackBlob&>(aArg));
aProducerView.WriteParam(aArg.mSize);
aProducerView.WriteParam(aArg.mFormat);
@ -199,7 +199,7 @@ struct PcqParamTraits<webgl::TexUnpackSurface> {
return aProducerView.WriteParam(aArg.mStride);
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
aConsumerView.ReadParam(static_cast<webgl::TexUnpackBlob*>(aArg));
aConsumerView.ReadParam(aArg ? &aArg->mSize : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mFormat : nullptr);
@ -217,28 +217,28 @@ struct PcqParamTraits<webgl::TexUnpackSurface> {
}
};
// Specialization of PcqParamTraits that adapts the TexUnpack type in order to
// Specialization of QueueParamTraits that adapts the TexUnpack type in order to
// efficiently convert types. For example, a TexUnpackSurface may deserialize
// as a TexUnpackBytes.
template <>
struct PcqParamTraits<WebGLTexUnpackVariant> {
struct QueueParamTraits<WebGLTexUnpackVariant> {
using ParamType = WebGLTexUnpackVariant;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
struct TexUnpackWriteMatcher {
PcqStatus operator()(const UniquePtr<webgl::TexUnpackBytes>& x) {
QueueStatus operator()(const UniquePtr<webgl::TexUnpackBytes>& x) {
mProducerView.WriteParam(TexUnpackTypes::Bytes);
return mProducerView.WriteParam(x);
}
PcqStatus operator()(const UniquePtr<webgl::TexUnpackSurface>& x) {
QueueStatus operator()(const UniquePtr<webgl::TexUnpackSurface>& x) {
mProducerView.WriteParam(TexUnpackTypes::Surface);
return mProducerView.WriteParam(x);
}
PcqStatus operator()(const UniquePtr<webgl::TexUnpackImage>& x) {
QueueStatus operator()(const UniquePtr<webgl::TexUnpackImage>& x) {
MOZ_ASSERT_UNREACHABLE("TODO:");
return PcqStatus::PcqFatalError;
return QueueStatus::kFatalError;
}
PcqStatus operator()(const WebGLTexPboOffset& x) {
QueueStatus operator()(const WebGLTexPboOffset& x) {
mProducerView.WriteParam(TexUnpackTypes::Pbo);
return mProducerView.WriteParam(x);
}
@ -247,14 +247,14 @@ struct PcqParamTraits<WebGLTexUnpackVariant> {
return aArg.match(TexUnpackWriteMatcher{aProducerView});
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
if (!aArg) {
// Not a great estimate but we can't do much better.
return aConsumerView.template ReadParam<TexUnpackTypes>();
}
TexUnpackTypes unpackType;
if (!aConsumerView.ReadParam(&unpackType)) {
return aConsumerView.Status();
return aConsumerView.GetStatus();
}
switch (unpackType) {
case TexUnpackTypes::Bytes:
@ -267,13 +267,13 @@ struct PcqParamTraits<WebGLTexUnpackVariant> {
&aArg->as<UniquePtr<webgl::TexUnpackSurface>>());
case TexUnpackTypes::Image:
MOZ_ASSERT_UNREACHABLE("TODO:");
return PcqStatus::PcqFatalError;
return QueueStatus::kFatalError;
case TexUnpackTypes::Pbo:
*aArg = AsVariant(WebGLTexPboOffset());
return aConsumerView.ReadParam(&aArg->as<WebGLTexPboOffset>());
}
MOZ_ASSERT_UNREACHABLE("Illegal texture unpack type");
return PcqStatus::PcqFatalError;
return QueueStatus::kFatalError;
}
template <typename View>
@ -304,20 +304,20 @@ struct PcqParamTraits<WebGLTexUnpackVariant> {
};
*/
template <>
struct PcqParamTraits<webgl::ContextLossReason> {
struct QueueParamTraits<webgl::ContextLossReason> {
using ParamType = webgl::ContextLossReason;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
return aProducerView.WriteParam(static_cast<uint8_t>(aArg));
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
static QueueStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
uint8_t val;
auto status = aConsumerView.ReadParam(&val);
if (!status) return status;
if (!ReadContextLossReason(val, aArg)) {
MOZ_ASSERT_UNREACHABLE("Invalid ContextLossReason");
return PcqStatus::PcqFatalError;
return QueueStatus::kFatalError;
}
return status;
}
@ -329,10 +329,10 @@ struct PcqParamTraits<webgl::ContextLossReason> {
};
template <typename V, typename E>
struct PcqParamTraits<Result<V, E>> {
struct QueueParamTraits<Result<V, E>> {
using T = Result<V, E>;
static PcqStatus Write(ProducerView& aProducerView, const T& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const T& aArg) {
const auto ok = aArg.isOk();
auto status = aProducerView.WriteParam(ok);
if (!status) return status;
@ -344,7 +344,7 @@ struct PcqParamTraits<Result<V, E>> {
return status;
}
static PcqStatus Read(ConsumerView& aConsumerView, T* const aArg) {
static QueueStatus Read(ConsumerView& aConsumerView, T* const aArg) {
bool ok;
auto status = aConsumerView.ReadParam(&ok);
if (!status) return status;
@ -377,24 +377,24 @@ struct PcqParamTraits<Result<V, E>> {
};
template <>
struct PcqParamTraits<std::string> {
struct QueueParamTraits<std::string> {
using T = std::string;
static PcqStatus Write(ProducerView& aProducerView, const T& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const T& aArg) {
auto status = aProducerView.WriteParam(aArg.size());
if (!status) return status;
status = aProducerView.Write(aArg.data(), aArg.size());
return status;
}
static PcqStatus Read(ConsumerView& aConsumerView, T* const aArg) {
static QueueStatus Read(ConsumerView& aConsumerView, T* const aArg) {
size_t size;
auto status = aConsumerView.ReadParam(&size);
if (!status) return status;
const UniqueBuffer temp = malloc(size);
const auto dest = static_cast<char*>(temp.get());
if (!dest) return PcqStatus::PcqFatalError;
if (!dest) return QueueStatus::kFatalError;
status = aConsumerView.Read(dest, size);
if (aArg) {
@ -414,17 +414,17 @@ struct PcqParamTraits<std::string> {
};
template <typename U>
struct PcqParamTraits<std::vector<U>> {
struct QueueParamTraits<std::vector<U>> {
using T = std::string;
static PcqStatus Write(ProducerView& aProducerView, const T& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const T& aArg) {
auto status = aProducerView.WriteParam(aArg.size());
if (!status) return status;
status = aProducerView.Write(aArg.data(), aArg.size());
return status;
}
static PcqStatus Read(ConsumerView& aConsumerView, T* const aArg) {
static QueueStatus Read(ConsumerView& aConsumerView, T* const aArg) {
MOZ_CRASH("no way to fallibly resize vectors without exceptions");
size_t size;
auto status = aConsumerView.ReadParam(&size);
@ -446,21 +446,21 @@ struct PcqParamTraits<std::vector<U>> {
};
template <>
struct PcqParamTraits<WebGLExtensionID> {
struct QueueParamTraits<WebGLExtensionID> {
using T = WebGLExtensionID;
static PcqStatus Write(ProducerView& aProducerView, const T& aArg) {
static QueueStatus Write(ProducerView& aProducerView, const T& aArg) {
return aProducerView.WriteParam(mozilla::EnumValue(aArg));
}
static PcqStatus Read(ConsumerView& aConsumerView, T* const aArg) {
PcqStatus status = PcqStatus::Success;
static QueueStatus Read(ConsumerView& aConsumerView, T* const aArg) {
QueueStatus status = QueueStatus::kSuccess;
if (aArg) {
status = aConsumerView.ReadParam(
reinterpret_cast<typename std::underlying_type<T>::type*>(aArg));
if (*aArg >= WebGLExtensionID::Max) {
MOZ_ASSERT(false);
return PcqStatus::PcqFatalError;
return QueueStatus::kFatalError;
}
}
return status;
@ -475,4 +475,4 @@ struct PcqParamTraits<WebGLExtensionID> {
} // namespace webgl
} // namespace mozilla
#endif // WEBGLPCQPARAMTRAITS_H_
#endif // WEBGLQUEUEPARAMTRAITS_H_

Просмотреть файл

@ -96,7 +96,7 @@ inline auto AutoAssertCast(const From val) {
namespace ipc {
template <typename T>
struct PcqParamTraits;
struct QueueParamTraits;
}
namespace webgl {
@ -733,7 +733,7 @@ class RawBuffer {
// true if we should delete[] the mData on destruction
bool mOwnsData = false;
friend mozilla::ipc::PcqParamTraits<RawBuffer>;
friend mozilla::ipc::QueueParamTraits<RawBuffer>;
public:
using ElementType = T;