mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-11 01:08:39 +12:00
idm: Fix minor race in cellVdecClose, sys_raw_spu_destroy...
Because of racing removal of IDs vs the shared pointer owned object
This commit is contained in:
parent
efe6e1eb0a
commit
c16124f0d9
6 changed files with 33 additions and 20 deletions
|
@ -833,7 +833,12 @@ error_code cellAdecClose(u32 handle)
|
||||||
thread_ctrl::wait_for(1000); // hack
|
thread_ctrl::wait_for(1000); // hack
|
||||||
}
|
}
|
||||||
|
|
||||||
idm::remove<ppu_thread>(handle);
|
if (!idm::remove_verify<ppu_thread>(handle, std::move(adec)))
|
||||||
|
{
|
||||||
|
// Removed by other thread beforehead
|
||||||
|
return CELL_ADEC_ERROR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -693,7 +693,13 @@ error_code cellVdecClose(ppu_thread& ppu, u32 handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
ppu_execute<&sys_interrupt_thread_disestablish>(ppu, vdec->ppu_tid);
|
ppu_execute<&sys_interrupt_thread_disestablish>(ppu, vdec->ppu_tid);
|
||||||
idm::remove<vdec_context>(handle);
|
|
||||||
|
if (!idm::remove_verify<vdec_context>(handle, std::move(vdec)))
|
||||||
|
{
|
||||||
|
// Other thread removed it beforehead
|
||||||
|
return CELL_VDEC_ERROR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,15 +117,11 @@ error_code sceNpSnsFbDestroyHandle(u32 handle)
|
||||||
return SCE_NP_SNS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_SNS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto sfh = idm::get<sns_fb_handle_t>(handle);
|
if (!idm::remove<sns_fb_handle_t>(handle))
|
||||||
|
|
||||||
if (!sfh)
|
|
||||||
{
|
{
|
||||||
return SCE_NP_SNS_FB_ERROR_UNKNOWN_HANDLE;
|
return SCE_NP_SNS_FB_ERROR_UNKNOWN_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
idm::remove<sns_fb_handle_t>(handle);
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ void sys_mempool_destroy(ppu_thread& ppu, sys_mempool_t mempool)
|
||||||
u32 mutexid = memory_pool->mutexid;
|
u32 mutexid = memory_pool->mutexid;
|
||||||
|
|
||||||
sys_mutex_lock(ppu, memory_pool->mutexid, 0);
|
sys_mutex_lock(ppu, memory_pool->mutexid, 0);
|
||||||
idm::remove<memory_pool_t>(mempool);
|
idm::remove_verify<memory_pool_t>(mempool, std::move(memory_pool));
|
||||||
sys_mutex_unlock(ppu, mutexid);
|
sys_mutex_unlock(ppu, mutexid);
|
||||||
sys_mutex_destroy(ppu, mutexid);
|
sys_mutex_destroy(ppu, mutexid);
|
||||||
sys_cond_destroy(ppu, condid);
|
sys_cond_destroy(ppu, condid);
|
||||||
|
|
|
@ -39,7 +39,7 @@ void lv2_int_serv::join()
|
||||||
thread_ctrl::notify(*thread);
|
thread_ctrl::notify(*thread);
|
||||||
(*thread)();
|
(*thread)();
|
||||||
|
|
||||||
idm::remove<named_thread<ppu_thread>>(thread->id);
|
idm::remove_verify<named_thread<ppu_thread>>(thread->id, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sys_interrupt_tag_destroy(ppu_thread& ppu, u32 intrtag)
|
error_code sys_interrupt_tag_destroy(ppu_thread& ppu, u32 intrtag)
|
||||||
|
|
|
@ -1703,32 +1703,33 @@ error_code sys_raw_spu_destroy(ppu_thread& ppu, u32 id)
|
||||||
thread->state += cpu_flag::stop;
|
thread->state += cpu_flag::stop;
|
||||||
|
|
||||||
// Kernel objects which must be removed
|
// Kernel objects which must be removed
|
||||||
std::unordered_map<lv2_obj*, u32, pointer_hash<lv2_obj, alignof(void*)>> to_remove;
|
std::vector<std::pair<std::shared_ptr<lv2_obj>, u32>> to_remove;
|
||||||
|
|
||||||
// Clear interrupt handlers
|
// Clear interrupt handlers
|
||||||
for (auto& intr : thread->int_ctrl)
|
for (auto& intr : thread->int_ctrl)
|
||||||
{
|
{
|
||||||
if (const auto tag = intr.tag.lock())
|
if (auto tag = intr.tag.lock())
|
||||||
{
|
{
|
||||||
if (auto handler = tag->handler.lock())
|
if (auto handler = tag->handler.lock())
|
||||||
{
|
{
|
||||||
// SLEEP
|
// SLEEP
|
||||||
handler->join();
|
handler->join();
|
||||||
to_remove.emplace(handler.get(), 0);
|
to_remove.emplace_back(std::move(handler), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
to_remove.emplace(tag.get(), 0);
|
to_remove.emplace_back(std::move(tag), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan all kernel objects to determine IDs
|
// Scan all kernel objects to determine IDs
|
||||||
idm::select<lv2_obj>([&](u32 id, lv2_obj& obj)
|
idm::select<lv2_obj>([&](u32 id, lv2_obj& obj)
|
||||||
{
|
{
|
||||||
const auto found = to_remove.find(&obj);
|
for (auto& pair : to_remove)
|
||||||
|
|
||||||
if (found != to_remove.end())
|
|
||||||
{
|
{
|
||||||
found->second = id;
|
if (pair.first.get() == std::addressof(obj))
|
||||||
|
{
|
||||||
|
pair.second = id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1736,12 +1737,17 @@ error_code sys_raw_spu_destroy(ppu_thread& ppu, u32 id)
|
||||||
for (auto&& pair : to_remove)
|
for (auto&& pair : to_remove)
|
||||||
{
|
{
|
||||||
if (pair.second >> 24 == 0xa)
|
if (pair.second >> 24 == 0xa)
|
||||||
idm::remove<lv2_obj, lv2_int_tag>(pair.second);
|
idm::remove_verify<lv2_obj, lv2_int_tag>(pair.second, std::move(pair.first));
|
||||||
if (pair.second >> 24 == 0xb)
|
if (pair.second >> 24 == 0xb)
|
||||||
idm::remove<lv2_obj, lv2_int_serv>(pair.second);
|
idm::remove_verify<lv2_obj, lv2_int_serv>(pair.second, std::move(pair.first));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!idm::remove_verify<named_thread<spu_thread>>(thread->id, std::move(thread)))
|
||||||
|
{
|
||||||
|
// Other thread destroyed beforehead
|
||||||
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
idm::remove<named_thread<spu_thread>>(thread->id);
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue