mirror of https://github.com/microsoft/WSL
WSLA: Invoke WSLAContainer callbacks without the callback lock held
This commit is contained in:
parent
68a6c4869d
commit
8546224401
|
|
@ -112,16 +112,26 @@ void ContainerEventTracker::OnEvent(const std::string& event)
|
|||
auto containerIdIt = innerEvent.find("container_id");
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, containerIdIt == innerEvent.end(), "Failed to parse json: %hs", innerEventJson.c_str());
|
||||
|
||||
std::lock_guard lock{m_lock};
|
||||
|
||||
std::string containerId = containerIdIt->get<std::string>();
|
||||
for (const auto& e : m_callbacks)
|
||||
|
||||
// Copy callbacks to invoke outside the lock to avoid deadlock if callback tries to register/unregister
|
||||
std::vector<ContainerStateChangeCallback> callbacksToInvoke;
|
||||
{
|
||||
if (e.ContainerId == containerId)
|
||||
std::lock_guard lock{m_lock};
|
||||
for (const auto& e : m_callbacks)
|
||||
{
|
||||
e.Callback(it->second);
|
||||
if (e.ContainerId == containerId)
|
||||
{
|
||||
callbacksToInvoke.push_back(e.Callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke callbacks outside the lock
|
||||
for (const auto& callback : callbacksToInvoke)
|
||||
{
|
||||
callback(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerEventTracker::Run(ServiceRunningProcess& process)
|
||||
|
|
|
|||
|
|
@ -163,16 +163,24 @@ CATCH_RETURN();
|
|||
|
||||
WSLA_CONTAINER_STATE WSLAContainer::State() noexcept
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_lock);
|
||||
std::optional<ServiceRunningProcess> processToDestroy;
|
||||
WSLA_CONTAINER_STATE result;
|
||||
|
||||
// If the container is running, refresh the init process state before returning.
|
||||
if (m_state == WslaContainerStateRunning && m_containerProcess->State() != WSLAProcessStateRunning)
|
||||
{
|
||||
m_state = WslaContainerStateExited;
|
||||
m_containerProcess.reset();
|
||||
std::lock_guard<std::recursive_mutex> lock(m_lock);
|
||||
|
||||
// If the container is running, refresh the init process state before returning.
|
||||
if (m_state == WslaContainerStateRunning && m_containerProcess->State() != WSLAProcessStateRunning)
|
||||
{
|
||||
m_state = WslaContainerStateExited;
|
||||
processToDestroy = std::move(m_containerProcess);
|
||||
}
|
||||
|
||||
result = m_state;
|
||||
}
|
||||
|
||||
return m_state;
|
||||
// Destructor runs outside the lock to avoid potential deadlock
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT WSLAContainer::GetState(WSLA_CONTAINER_STATE* Result)
|
||||
|
|
|
|||
Loading…
Reference in New Issue