Modified: trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp (284222 => 284223)
--- trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp 2021-10-15 01:24:15 UTC (rev 284222)
+++ trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp 2021-10-15 01:44:56 UTC (rev 284223)
@@ -112,6 +112,8 @@
: m_streamConnection { connection, bufferSize }
{ }
+ void setWakeUpSemaphore(JSIPCSemaphore& jsSemaphore) { m_streamConnection.setWakeUpSemaphore(jsSemaphore.exchange()); }
+
static JSClassRef wrapperClass();
static JSIPCStreamClientConnection* unwrap(JSObjectRef);
static void initialize(JSContextRef, JSObjectRef);
@@ -119,6 +121,7 @@
static const JSStaticFunction* staticFunctions();
static JSValueRef streamBuffer(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+ static JSValueRef setWakeUpSemaphore(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
IPC::StreamClientConnection m_streamConnection;
};
@@ -241,6 +244,7 @@
static JSValueRef sendMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
static JSValueRef sendSyncMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+ static JSValueRef waitForMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
static JSValueRef createStreamClientConnection(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
static JSValueRef createSemaphore(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
@@ -392,6 +396,7 @@
{
static const JSStaticFunction functions[] = {
{ "streamBuffer", streamBuffer, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "setWakeUpSemaphore", setWakeUpSemaphore, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ 0, 0, 0 }
};
return functions;
@@ -399,6 +404,8 @@
JSValueRef JSIPCStreamClientConnection::streamBuffer(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
RefPtr jsStreamConnection = toWrapped(context, thisObject);
if (!jsStreamConnection) {
*exception = createTypeError(context, "Wrong type"_s);
@@ -408,6 +415,31 @@
return JSIPCStreamConnectionBuffer::create(*jsStreamConnection)->createJSWrapper(context);
}
+JSValueRef JSIPCStreamClientConnection::setWakeUpSemaphore(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+ RefPtr jsStreamConnection = toWrapped(context, thisObject);
+ if (!jsStreamConnection) {
+ *exception = createTypeError(context, "Wrong type"_s);
+ return JSValueMakeUndefined(context);
+ }
+
+ if (argumentCount < 1) {
+ *exception = createTypeError(context, "Must specify an IPC semaphore as the first argument"_s);
+ return JSValueMakeUndefined(context);
+ }
+
+ RefPtr jsSemaphore = JSIPCSemaphore::toWrapped(context, arguments[0]);
+ if (!jsSemaphore) {
+ *exception = createTypeError(context, "Wrong type (expected Semaphore)"_s);
+ return JSValueMakeUndefined(context);
+ }
+
+ jsStreamConnection->setWakeUpSemaphore(*jsSemaphore);
+ return JSValueMakeUndefined(context);
+}
+
JSObjectRef JSIPCStreamConnectionBuffer::createJSWrapper(JSContextRef context)
{
auto* globalObject = toJS(context);
@@ -760,6 +792,7 @@
{ "addOutgoingMessageListener", addOutgoingMessageListener, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "sendMessage", sendMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "sendSyncMessage", sendSyncMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "waitForMessage", waitForMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "createStreamClientConnection", createStreamClientConnection, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "createSemaphore", createSemaphore, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
{ "createSharedMemory", createSharedMemory, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
@@ -1315,7 +1348,7 @@
}
if (argumentCount < 3) {
- *exception = createTypeError(context, "Must specify the target process, desination ID, and message ID as the first three arguments"_s);
+ *exception = createTypeError(context, "Must specify the target process, destination ID, and message ID as the first three arguments"_s);
return JSValueMakeUndefined(context);
}
@@ -1386,48 +1419,94 @@
return returnValue;
}
-JSValueRef JSIPC::sendSyncMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+struct SyncIPCMessageInfo {
+ Ref<IPC::Connection> connection;
+ uint64_t destinationID;
+ IPC::MessageName messageName;
+ IPC::Timeout timeout;
+};
+
+static std::optional<SyncIPCMessageInfo> extractSyncIPCMessageInfo(JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
- auto* globalObject = toJS(context);
- JSC::JSLockHolder lock(globalObject->vm());
- RefPtr jsIPC = toWrapped(context, thisObject);
- if (!jsIPC) {
- *exception = createTypeError(context, "Wrong type"_s);
- return JSValueMakeUndefined(context);
- }
-
if (argumentCount < 4) {
- *exception = createTypeError(context, "Must specify the target process, desination ID, and message ID as the first three arguments"_s);
- return JSValueMakeUndefined(context);
+ *exception = createTypeError(context, "Must specify the target process, destination ID, and message ID as the first three arguments"_s);
+ return std::nullopt;
}
+ auto* globalObject = toJS(context);
auto connection = processTargetFromArgument(globalObject, arguments[0], exception);
if (!connection)
- return JSValueMakeUndefined(context);
+ return std::nullopt;
auto destinationID = destinationIDFromArgument(globalObject, arguments[1], exception);
if (!destinationID)
- return JSValueMakeUndefined(context);
+ return std::nullopt;
auto messageID = messageIDFromArgument(globalObject, arguments[2], exception);
if (!messageID)
- return JSValueMakeUndefined(context);
+ return std::nullopt;
- Seconds timeout;
+ Seconds timeoutDuration;
{
auto jsValue = toJS(globalObject, arguments[3]);
if (!jsValue.isNumber()) {
*exception = createTypeError(context, "Timeout must be a number"_s);
+ return std::nullopt;
+ }
+ timeoutDuration = Seconds { jsValue.asNumber() };
+ }
+
+ return { { connection.releaseNonNull(), *destinationID, static_cast<IPC::MessageName>(*messageID), { timeoutDuration } } };
+}
+
+JSValueRef JSIPC::waitForMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+ RefPtr jsIPC = toWrapped(context, thisObject);
+ if (!jsIPC) {
+ *exception = createTypeError(context, "Wrong type"_s);
+ return JSValueMakeUndefined(context);
+ }
+
+ auto info = extractSyncIPCMessageInfo(context, argumentCount, arguments, exception);
+ if (!info)
+ return JSValueMakeUndefined(context);
+
+ auto [connection, destinationID, messageName, timeout] = *info;
+ if (auto decoder = connection->waitForMessage(messageName, destinationID, timeout, { })) {
+ auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
+ auto jsResult = jsValueForArguments(globalObject, messageName, *decoder);
+ if (scope.exception()) {
+ *exception = toRef(globalObject, scope.exception());
+ scope.clearException();
return JSValueMakeUndefined(context);
}
- timeout = Seconds { jsValue.asNumber() };
+ return jsResult ? toRef(globalObject, *jsResult) : JSValueMakeUndefined(context);
}
+ return JSValueMakeUndefined(context);
+}
+JSValueRef JSIPC::sendSyncMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+ RefPtr jsIPC = toWrapped(context, thisObject);
+ if (!jsIPC) {
+ *exception = createTypeError(context, "Wrong type"_s);
+ return JSValueMakeUndefined(context);
+ }
+
+ auto info = extractSyncIPCMessageInfo(context, argumentCount, arguments, exception);
+ if (!info)
+ return JSValueMakeUndefined(context);
+
+ auto [connection, destinationID, messageName, timeout] = *info;
+
// FIXME: Support the options.
IPC::Connection::SyncRequestID syncRequestID;
- auto messageName = static_cast<IPC::MessageName>(*messageID);
- auto encoder = connection->createSyncMessageEncoder(messageName, *destinationID, syncRequestID);
+ auto encoder = connection->createSyncMessageEncoder(messageName, destinationID, syncRequestID);
if (argumentCount > 4) {
if (!encodeArgument(encoder.get(), *jsIPC, context, arguments[4], exception))
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm (284222 => 284223)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm 2021-10-15 01:24:15 UTC (rev 284222)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm 2021-10-15 01:44:56 UTC (rev 284223)
@@ -299,9 +299,8 @@
" { type: 'RemoteRenderingBackendCreationParameters', 'identifier': 123, 'pageProxyID': IPC.webPageProxyID, 'pageID': IPC.pageID },"
" { type: 'StreamConnectionBuffer', value: streamConnection.streamBuffer() },"
"]);"
- "const result = IPC.sendSyncMessage('GPU', 123, IPC.messages.RemoteRenderingBackend_SemaphoreForGetPixelBuffer.name, 100, []);"
- "semaphore.signal();"
- "alert(result.arguments.length + ':' + result.arguments[0].type + ':' + result.arguments[0].value.waitFor(100));"
+ "const arguments = IPC.waitForMessage('GPU', 123, IPC.messages.RemoteRenderingBackendProxy_DidCreateWakeUpSemaphoreForDisplayListStream.name, 100);"
+ "alert(arguments.length + ':' + arguments[0].type + ':' + arguments[0].value.waitFor(100));"
"</script>";
[webView synchronouslyLoadHTMLString:html];
TestWebKitAPI::Util::run(&done);
@@ -324,6 +323,8 @@
" { type: 'RemoteRenderingBackendCreationParameters', 'identifier': 123, 'pageProxyID': IPC.webPageProxyID, 'pageID': IPC.pageID },"
" { type: 'StreamConnectionBuffer', value: streamConnection.streamBuffer() },"
"]);"
+ "const arguments = IPC.waitForMessage('GPU', 123, IPC.messages.RemoteRenderingBackendProxy_DidCreateWakeUpSemaphoreForDisplayListStream.name, 100);"
+ "streamConnection.setWakeUpSemaphore(arguments[0].value);"
"const result = IPC.sendSyncMessage('GPU', 123, IPC.messages.RemoteRenderingBackend_UpdateSharedMemoryForGetPixelBuffer.name, 100, [{type: 'uint32_t', value: 8}]);"
"alert(result.arguments.length);"
"</script>";