mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-25 18:07:31 +09:00
Support readable stream transfer to workers
This commit is contained in:
parent
f9e1af95c2
commit
7d8bf841ed
2 changed files with 354 additions and 0 deletions
|
|
@ -152,6 +152,11 @@ struct SameThreadStreamTransferData
|
|||
JS::PersistentRootedObject mRecord;
|
||||
};
|
||||
|
||||
struct MessagePortStreamTransferData
|
||||
{
|
||||
MessagePortIdentifier mIdentifier;
|
||||
};
|
||||
|
||||
bool
|
||||
CallStreamTransferHelper(JSContext* aCx,
|
||||
const char* aHelperName,
|
||||
|
|
@ -227,6 +232,50 @@ TryWriteSameThreadStreamTransfer(JSContext* aCx,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TryWriteReadableStreamPortTransfer(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
uint32_t* aTag,
|
||||
JS::TransferableOwnership* aOwnership,
|
||||
void** aContent,
|
||||
uint64_t* aExtraData,
|
||||
bool* aHandled)
|
||||
{
|
||||
*aHandled = false;
|
||||
|
||||
JS::Rooted<JS::Value> argument(aCx, JS::ObjectValue(*aObj));
|
||||
JS::Rooted<JS::Value> transferPortValue(aCx);
|
||||
if (!CallStreamTransferHelper(aCx, "__uxpTransferReadableStreamPort",
|
||||
argument, &transferPortValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (transferPortValue.isUndefined()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!transferPortValue.isObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> transferPortObj(aCx, &transferPortValue.toObject());
|
||||
MessagePort* port = nullptr;
|
||||
nsresult rv = UNWRAP_OBJECT(MessagePort, &transferPortObj, port);
|
||||
if (NS_FAILED(rv) || !port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MessagePortStreamTransferData* data = new MessagePortStreamTransferData();
|
||||
port->CloneAndDisentangle(data->mIdentifier);
|
||||
|
||||
*aTag = SCTAG_DOM_TRANSFERRED_READABLESTREAM;
|
||||
*aOwnership = JS::SCTAG_TMO_CUSTOM;
|
||||
*aContent = data;
|
||||
*aExtraData = 0;
|
||||
*aHandled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReadSameThreadStreamTransfer(JSContext* aCx,
|
||||
void* aContent,
|
||||
|
|
@ -252,6 +301,48 @@ ReadSameThreadStreamTransfer(JSContext* aCx,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReadReadableStreamPortTransfer(JSContext* aCx,
|
||||
nsISupports* aParent,
|
||||
void* aContent,
|
||||
JS::MutableHandleObject aReturnObject)
|
||||
{
|
||||
MOZ_ASSERT(aContent);
|
||||
MessagePortStreamTransferData* data =
|
||||
static_cast<MessagePortStreamTransferData*>(aContent);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aParent);
|
||||
|
||||
ErrorResult rv;
|
||||
RefPtr<MessagePort> port =
|
||||
MessagePort::Create(global, data->mIdentifier, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> portValue(aCx);
|
||||
if (!GetOrCreateDOMReflector(aCx, port, &portValue)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> result(aCx);
|
||||
if (!CallStreamTransferHelper(aCx,
|
||||
"__uxpReceiveReadableStreamTransferFromPort",
|
||||
portValue, &result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!result.isObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aReturnObject.set(&result.toObject());
|
||||
delete data;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
const JSStructuredCloneCallbacks StructuredCloneHolder::sCallbacks = {
|
||||
|
|
@ -1503,6 +1594,12 @@ StructuredCloneHolder::CustomReadTransferHandler(JSContext* aCx,
|
|||
}
|
||||
}
|
||||
|
||||
if (mStructuredCloneScope == StructuredCloneScope::SameProcessDifferentThread &&
|
||||
aTag == SCTAG_DOM_TRANSFERRED_READABLESTREAM) {
|
||||
return ReadReadableStreamPortTransfer(aCx, mParent, aContent,
|
||||
aReturnObject);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1596,6 +1693,17 @@ StructuredCloneHolder::CustomWriteTransferHandler(JSContext* aCx,
|
|||
}
|
||||
}
|
||||
|
||||
if (mStructuredCloneScope == StructuredCloneScope::SameProcessDifferentThread) {
|
||||
bool handled = false;
|
||||
if (!TryWriteReadableStreamPortTransfer(aCx, obj, aTag, aOwnership,
|
||||
aContent, aExtraData, &handled)) {
|
||||
return false;
|
||||
}
|
||||
if (handled) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1643,6 +1751,16 @@ StructuredCloneHolder::CustomFreeTransferHandler(uint32_t aTag,
|
|||
delete data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTag == SCTAG_DOM_TRANSFERRED_READABLESTREAM &&
|
||||
mStructuredCloneScope == StructuredCloneScope::SameProcessDifferentThread) {
|
||||
MOZ_ASSERT(aContent);
|
||||
MessagePortStreamTransferData* data =
|
||||
static_cast<MessagePortStreamTransferData*>(aContent);
|
||||
MessagePort::ForceClose(data->mIdentifier);
|
||||
delete data;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue