mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-19 09:55:26 +00:00
dawn_wire: Return early in callbacks after the server is destroyed
After the server is destroyed, the server's can't do anything like forward callbacks to the client. Track this with a weak_ptr and return early if it has expired. It also updates device destruction in dawn_native so the lost callback is always called, even on graceful destruction. This is consistent with the rest of WebGPU where all callbacks are guaranteed to be called in finite time. Bug: chromium:1147416, chromium:1161943 Change-Id: Ib80dea36517401a2b8eafb01ded255ebbe757aef Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/35840 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
committed by
Commit Bot service account
parent
e3fd026108
commit
200941c797
@@ -16,50 +16,6 @@
|
||||
|
||||
namespace dawn_wire { namespace server {
|
||||
|
||||
void Server::ForwardUncapturedError(WGPUErrorType type, const char* message, void* userdata) {
|
||||
auto server = static_cast<Server*>(userdata);
|
||||
server->OnUncapturedError(type, message);
|
||||
}
|
||||
|
||||
void Server::ForwardDeviceLost(const char* message, void* userdata) {
|
||||
auto server = static_cast<Server*>(userdata);
|
||||
server->OnDeviceLost(message);
|
||||
}
|
||||
|
||||
void Server::ForwardCreateReadyComputePipeline(WGPUCreateReadyPipelineStatus status,
|
||||
WGPUComputePipeline pipeline,
|
||||
const char* message,
|
||||
void* userdata) {
|
||||
std::unique_ptr<CreateReadyPipelineUserData> createReadyPipelineUserData(
|
||||
static_cast<CreateReadyPipelineUserData*>(userdata));
|
||||
|
||||
// We need to ensure createReadyPipelineUserData->server is still pointing to a valid
|
||||
// object before doing any operations on it.
|
||||
if (createReadyPipelineUserData->isServerAlive.expired()) {
|
||||
return;
|
||||
}
|
||||
|
||||
createReadyPipelineUserData->server->OnCreateReadyComputePipelineCallback(
|
||||
status, pipeline, message, createReadyPipelineUserData.release());
|
||||
}
|
||||
|
||||
void Server::ForwardCreateReadyRenderPipeline(WGPUCreateReadyPipelineStatus status,
|
||||
WGPURenderPipeline pipeline,
|
||||
const char* message,
|
||||
void* userdata) {
|
||||
std::unique_ptr<CreateReadyPipelineUserData> createReadyPipelineUserData(
|
||||
static_cast<CreateReadyPipelineUserData*>(userdata));
|
||||
|
||||
// We need to ensure createReadyPipelineUserData->server is still pointing to a valid
|
||||
// object before doing any operations on it.
|
||||
if (createReadyPipelineUserData->isServerAlive.expired()) {
|
||||
return;
|
||||
}
|
||||
|
||||
createReadyPipelineUserData->server->OnCreateReadyRenderPipelineCallback(
|
||||
status, pipeline, message, createReadyPipelineUserData.release());
|
||||
}
|
||||
|
||||
void Server::OnUncapturedError(WGPUErrorType type, const char* message) {
|
||||
ReturnDeviceUncapturedErrorCallbackCmd cmd;
|
||||
cmd.type = type;
|
||||
@@ -76,17 +32,32 @@ namespace dawn_wire { namespace server {
|
||||
}
|
||||
|
||||
bool Server::DoDevicePopErrorScope(WGPUDevice cDevice, uint64_t requestSerial) {
|
||||
ErrorScopeUserdata* userdata = new ErrorScopeUserdata;
|
||||
userdata->server = this;
|
||||
auto userdata = MakeUserdata<ErrorScopeUserdata>();
|
||||
userdata->requestSerial = requestSerial;
|
||||
|
||||
bool success = mProcs.devicePopErrorScope(cDevice, ForwardPopErrorScope, userdata);
|
||||
ErrorScopeUserdata* unownedUserdata = userdata.release();
|
||||
bool success = mProcs.devicePopErrorScope(
|
||||
cDevice,
|
||||
ForwardToServer<decltype(
|
||||
&Server::OnDevicePopErrorScope)>::Func<&Server::OnDevicePopErrorScope>(),
|
||||
unownedUserdata);
|
||||
if (!success) {
|
||||
delete userdata;
|
||||
delete unownedUserdata;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void Server::OnDevicePopErrorScope(WGPUErrorType type,
|
||||
const char* message,
|
||||
ErrorScopeUserdata* userdata) {
|
||||
ReturnDevicePopErrorScopeCallbackCmd cmd;
|
||||
cmd.requestSerial = userdata->requestSerial;
|
||||
cmd.type = type;
|
||||
cmd.message = message;
|
||||
|
||||
SerializeCommand(cmd);
|
||||
}
|
||||
|
||||
bool Server::DoDeviceCreateReadyComputePipeline(
|
||||
WGPUDevice cDevice,
|
||||
uint64_t requestSerial,
|
||||
@@ -99,24 +70,22 @@ namespace dawn_wire { namespace server {
|
||||
|
||||
resultData->generation = pipelineObjectHandle.generation;
|
||||
|
||||
std::unique_ptr<CreateReadyPipelineUserData> userdata =
|
||||
std::make_unique<CreateReadyPipelineUserData>();
|
||||
userdata->isServerAlive = mIsAlive;
|
||||
userdata->server = this;
|
||||
auto userdata = MakeUserdata<CreateReadyPipelineUserData>();
|
||||
userdata->requestSerial = requestSerial;
|
||||
userdata->pipelineObjectID = pipelineObjectHandle.id;
|
||||
|
||||
mProcs.deviceCreateReadyComputePipeline(
|
||||
cDevice, descriptor, ForwardCreateReadyComputePipeline, userdata.release());
|
||||
cDevice, descriptor,
|
||||
ForwardToServer<decltype(&Server::OnCreateReadyComputePipelineCallback)>::Func<
|
||||
&Server::OnCreateReadyComputePipelineCallback>(),
|
||||
userdata.release());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Server::OnCreateReadyComputePipelineCallback(WGPUCreateReadyPipelineStatus status,
|
||||
WGPUComputePipeline pipeline,
|
||||
const char* message,
|
||||
CreateReadyPipelineUserData* userdata) {
|
||||
std::unique_ptr<CreateReadyPipelineUserData> data(userdata);
|
||||
|
||||
CreateReadyPipelineUserData* data) {
|
||||
auto* computePipelineObject = ComputePipelineObjects().Get(data->pipelineObjectID);
|
||||
ASSERT(computePipelineObject != nullptr);
|
||||
|
||||
@@ -158,24 +127,22 @@ namespace dawn_wire { namespace server {
|
||||
|
||||
resultData->generation = pipelineObjectHandle.generation;
|
||||
|
||||
std::unique_ptr<CreateReadyPipelineUserData> userdata =
|
||||
std::make_unique<CreateReadyPipelineUserData>();
|
||||
userdata->isServerAlive = mIsAlive;
|
||||
userdata->server = this;
|
||||
auto userdata = MakeUserdata<CreateReadyPipelineUserData>();
|
||||
userdata->requestSerial = requestSerial;
|
||||
userdata->pipelineObjectID = pipelineObjectHandle.id;
|
||||
|
||||
mProcs.deviceCreateReadyRenderPipeline(
|
||||
cDevice, descriptor, ForwardCreateReadyRenderPipeline, userdata.release());
|
||||
cDevice, descriptor,
|
||||
ForwardToServer<decltype(&Server::OnCreateReadyRenderPipelineCallback)>::Func<
|
||||
&Server::OnCreateReadyRenderPipelineCallback>(),
|
||||
userdata.release());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Server::OnCreateReadyRenderPipelineCallback(WGPUCreateReadyPipelineStatus status,
|
||||
WGPURenderPipeline pipeline,
|
||||
const char* message,
|
||||
CreateReadyPipelineUserData* userdata) {
|
||||
std::unique_ptr<CreateReadyPipelineUserData> data(userdata);
|
||||
|
||||
CreateReadyPipelineUserData* data) {
|
||||
auto* renderPipelineObject = RenderPipelineObjects().Get(data->pipelineObjectID);
|
||||
ASSERT(renderPipelineObject != nullptr);
|
||||
|
||||
@@ -206,23 +173,4 @@ namespace dawn_wire { namespace server {
|
||||
SerializeCommand(cmd);
|
||||
}
|
||||
|
||||
// static
|
||||
void Server::ForwardPopErrorScope(WGPUErrorType type, const char* message, void* userdata) {
|
||||
auto* data = reinterpret_cast<ErrorScopeUserdata*>(userdata);
|
||||
data->server->OnDevicePopErrorScope(type, message, data);
|
||||
}
|
||||
|
||||
void Server::OnDevicePopErrorScope(WGPUErrorType type,
|
||||
const char* message,
|
||||
ErrorScopeUserdata* userdata) {
|
||||
std::unique_ptr<ErrorScopeUserdata> data{userdata};
|
||||
|
||||
ReturnDevicePopErrorScopeCallbackCmd cmd;
|
||||
cmd.requestSerial = data->requestSerial;
|
||||
cmd.type = type;
|
||||
cmd.message = message;
|
||||
|
||||
SerializeCommand(cmd);
|
||||
}
|
||||
|
||||
}} // namespace dawn_wire::server
|
||||
|
||||
Reference in New Issue
Block a user