mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00: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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -693,7 +693,13 @@ error_code cellVdecClose(ppu_thread& ppu, u32 handle)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,15 +117,11 @@ error_code sceNpSnsFbDestroyHandle(u32 handle)
|
|||
return SCE_NP_SNS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
const auto sfh = idm::get<sns_fb_handle_t>(handle);
|
||||
|
||||
if (!sfh)
|
||||
if (!idm::remove<sns_fb_handle_t>(handle))
|
||||
{
|
||||
return SCE_NP_SNS_FB_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
idm::remove<sns_fb_handle_t>(handle);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ void sys_mempool_destroy(ppu_thread& ppu, sys_mempool_t mempool)
|
|||
u32 mutexid = memory_pool->mutexid;
|
||||
|
||||
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_destroy(ppu, mutexid);
|
||||
sys_cond_destroy(ppu, condid);
|
||||
|
|
|
@ -39,7 +39,7 @@ void lv2_int_serv::join()
|
|||
thread_ctrl::notify(*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)
|
||||
|
|
|
@ -1703,32 +1703,33 @@ error_code sys_raw_spu_destroy(ppu_thread& ppu, u32 id)
|
|||
thread->state += cpu_flag::stop;
|
||||
|
||||
// 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
|
||||
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())
|
||||
{
|
||||
// SLEEP
|
||||
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
|
||||
idm::select<lv2_obj>([&](u32 id, lv2_obj& obj)
|
||||
{
|
||||
const auto found = to_remove.find(&obj);
|
||||
|
||||
if (found != to_remove.end())
|
||||
for (auto& pair : to_remove)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue