PS_Win_BLE: fix crash on disconnect - use TWeakObjectPtr in all async dispatches
All Dispatch* functions now capture UPS_BLE_Device via TWeakObjectPtr instead of a raw pointer, preventing an access violation when the UObject is garbage collected before the GameThread lambda executes (EXCEPTION_ACCESS_VIOLATION @ 0x60). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
10ca1e19c7
commit
aa8df59af2
@ -664,10 +664,12 @@ void UPS_BLE_Module::DispatchDeviceConnected(UPS_BLE_Device* Dev)
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncTask(ENamedThreads::GameThread, [Dev]()
|
||||
TWeakObjectPtr<UPS_BLE_Device> WeakDev(Dev);
|
||||
AsyncTask(ENamedThreads::GameThread, [WeakDev]()
|
||||
{
|
||||
Dev->RefToManager->JustConnectedDevice(Dev);
|
||||
Dev->OnConnect.Broadcast(Dev, Dev->ActiveServices);
|
||||
if (!WeakDev.IsValid()) return;
|
||||
WeakDev->RefToManager->JustConnectedDevice(WeakDev.Get());
|
||||
WeakDev->OnConnect.Broadcast(WeakDev.Get(), WeakDev->ActiveServices);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -682,10 +684,12 @@ void UPS_BLE_Module::DispatchDeviceDisconnected(UPS_BLE_Device* Dev)
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncTask(ENamedThreads::GameThread, [Dev]()
|
||||
TWeakObjectPtr<UPS_BLE_Device> WeakDev(Dev);
|
||||
AsyncTask(ENamedThreads::GameThread, [WeakDev]()
|
||||
{
|
||||
Dev->RefToManager->JustDisconnectedDevice(Dev);
|
||||
Dev->OnDisconnect.Broadcast(Dev);
|
||||
if (!WeakDev.IsValid()) return;
|
||||
WeakDev->RefToManager->JustDisconnectedDevice(WeakDev.Get());
|
||||
WeakDev->OnDisconnect.Broadcast(WeakDev.Get());
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -700,10 +704,12 @@ void UPS_BLE_Module::DispatchServicesDiscovered(UPS_BLE_Device* Dev)
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncTask(ENamedThreads::GameThread, [Dev]()
|
||||
TWeakObjectPtr<UPS_BLE_Device> WeakDev(Dev);
|
||||
AsyncTask(ENamedThreads::GameThread, [WeakDev]()
|
||||
{
|
||||
Dev->RefToManager->JustDiscoveredServices(Dev);
|
||||
Dev->OnServicesDiscovered.Broadcast(Dev, Dev->ActiveServices);
|
||||
if (!WeakDev.IsValid()) return;
|
||||
WeakDev->RefToManager->JustDiscoveredServices(WeakDev.Get());
|
||||
WeakDev->OnServicesDiscovered.Broadcast(WeakDev.Get(), WeakDev->ActiveServices);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -719,11 +725,13 @@ void UPS_BLE_Module::DispatchRead(UPS_BLE_Device* Dev, uint8 SI, uint8 CI, EPS_G
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncTask(ENamedThreads::GameThread, [Dev, SI, CI, Status, Data]()
|
||||
TWeakObjectPtr<UPS_BLE_Device> WeakDev(Dev);
|
||||
AsyncTask(ENamedThreads::GameThread, [WeakDev, SI, CI, Status, Data]()
|
||||
{
|
||||
if (SI < Dev->ActiveServices.Num() && CI < Dev->ActiveServices[SI].Characteristics.Num())
|
||||
Dev->OnRead.Broadcast(Status, Dev, Dev->ActiveServices[SI].ServiceUUID,
|
||||
Dev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID, Data);
|
||||
if (!WeakDev.IsValid()) return;
|
||||
if (SI < WeakDev->ActiveServices.Num() && CI < WeakDev->ActiveServices[SI].Characteristics.Num())
|
||||
WeakDev->OnRead.Broadcast(Status, WeakDev.Get(), WeakDev->ActiveServices[SI].ServiceUUID,
|
||||
WeakDev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID, Data);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -739,11 +747,13 @@ void UPS_BLE_Module::DispatchNotify(UPS_BLE_Device* Dev, uint8 SI, uint8 CI, EPS
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncTask(ENamedThreads::GameThread, [Dev, SI, CI, Status, Data]()
|
||||
TWeakObjectPtr<UPS_BLE_Device> WeakDev(Dev);
|
||||
AsyncTask(ENamedThreads::GameThread, [WeakDev, SI, CI, Status, Data]()
|
||||
{
|
||||
if (SI < Dev->ActiveServices.Num() && CI < Dev->ActiveServices[SI].Characteristics.Num())
|
||||
Dev->OnNotify.Broadcast(Status, Dev, Dev->ActiveServices[SI].ServiceUUID,
|
||||
Dev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID, Data);
|
||||
if (!WeakDev.IsValid()) return;
|
||||
if (SI < WeakDev->ActiveServices.Num() && CI < WeakDev->ActiveServices[SI].Characteristics.Num())
|
||||
WeakDev->OnNotify.Broadcast(Status, WeakDev.Get(), WeakDev->ActiveServices[SI].ServiceUUID,
|
||||
WeakDev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID, Data);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -751,11 +761,13 @@ void UPS_BLE_Module::DispatchNotify(UPS_BLE_Device* Dev, uint8 SI, uint8 CI, EPS
|
||||
void UPS_BLE_Module::DispatchWrite(UPS_BLE_Device* Dev, uint8 SI, uint8 CI, EPS_GATTStatus Status)
|
||||
{
|
||||
if (!Dev) return;
|
||||
auto Fire = [Dev, SI, CI, Status]()
|
||||
TWeakObjectPtr<UPS_BLE_Device> WeakDev(Dev);
|
||||
auto Fire = [WeakDev, SI, CI, Status]()
|
||||
{
|
||||
if (SI < Dev->ActiveServices.Num() && CI < Dev->ActiveServices[SI].Characteristics.Num())
|
||||
Dev->OnWrite.Broadcast(Status, Dev, Dev->ActiveServices[SI].ServiceUUID,
|
||||
Dev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID);
|
||||
if (!WeakDev.IsValid()) return;
|
||||
if (SI < WeakDev->ActiveServices.Num() && CI < WeakDev->ActiveServices[SI].Characteristics.Num())
|
||||
WeakDev->OnWrite.Broadcast(Status, WeakDev.Get(), WeakDev->ActiveServices[SI].ServiceUUID,
|
||||
WeakDev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID);
|
||||
};
|
||||
if (IsInGameThread()) Fire();
|
||||
else AsyncTask(ENamedThreads::GameThread, Fire);
|
||||
@ -764,13 +776,15 @@ void UPS_BLE_Module::DispatchWrite(UPS_BLE_Device* Dev, uint8 SI, uint8 CI, EPS_
|
||||
void UPS_BLE_Module::DispatchSubscribe(UPS_BLE_Device* Dev, uint8 SI, uint8 CI, EPS_GATTStatus Status)
|
||||
{
|
||||
if (!Dev) return;
|
||||
auto Fire = [Dev, SI, CI, Status]()
|
||||
TWeakObjectPtr<UPS_BLE_Device> WeakDev(Dev);
|
||||
auto Fire = [WeakDev, SI, CI, Status]()
|
||||
{
|
||||
if (SI < Dev->ActiveServices.Num() && CI < Dev->ActiveServices[SI].Characteristics.Num())
|
||||
if (!WeakDev.IsValid()) return;
|
||||
if (SI < WeakDev->ActiveServices.Num() && CI < WeakDev->ActiveServices[SI].Characteristics.Num())
|
||||
{
|
||||
Dev->ActiveServices[SI].Characteristics[CI].subscribed = true;
|
||||
Dev->OnSubscribe.Broadcast(Status, Dev, Dev->ActiveServices[SI].ServiceUUID,
|
||||
Dev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID);
|
||||
WeakDev->ActiveServices[SI].Characteristics[CI].subscribed = true;
|
||||
WeakDev->OnSubscribe.Broadcast(Status, WeakDev.Get(), WeakDev->ActiveServices[SI].ServiceUUID,
|
||||
WeakDev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID);
|
||||
}
|
||||
};
|
||||
if (IsInGameThread()) Fire();
|
||||
@ -780,13 +794,15 @@ void UPS_BLE_Module::DispatchSubscribe(UPS_BLE_Device* Dev, uint8 SI, uint8 CI,
|
||||
void UPS_BLE_Module::DispatchUnsubscribe(UPS_BLE_Device* Dev, uint8 SI, uint8 CI, EPS_GATTStatus Status)
|
||||
{
|
||||
if (!Dev) return;
|
||||
auto Fire = [Dev, SI, CI, Status]()
|
||||
TWeakObjectPtr<UPS_BLE_Device> WeakDev(Dev);
|
||||
auto Fire = [WeakDev, SI, CI, Status]()
|
||||
{
|
||||
if (SI < Dev->ActiveServices.Num() && CI < Dev->ActiveServices[SI].Characteristics.Num())
|
||||
if (!WeakDev.IsValid()) return;
|
||||
if (SI < WeakDev->ActiveServices.Num() && CI < WeakDev->ActiveServices[SI].Characteristics.Num())
|
||||
{
|
||||
Dev->ActiveServices[SI].Characteristics[CI].subscribed = false;
|
||||
Dev->OnUnsubscribe.Broadcast(Status, Dev, Dev->ActiveServices[SI].ServiceUUID,
|
||||
Dev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID);
|
||||
WeakDev->ActiveServices[SI].Characteristics[CI].subscribed = false;
|
||||
WeakDev->OnUnsubscribe.Broadcast(Status, WeakDev.Get(), WeakDev->ActiveServices[SI].ServiceUUID,
|
||||
WeakDev->ActiveServices[SI].Characteristics[CI].CharacteristicUUID);
|
||||
}
|
||||
};
|
||||
if (IsInGameThread()) Fire();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user