mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 06:51:26 +12:00
Fix sys_io thread deadlock
Co-Authored-By: Megamouse <23019877+Megamouse@users.noreply.github.com>
This commit is contained in:
parent
4d5897d519
commit
29b0298f1e
2 changed files with 37 additions and 9 deletions
|
@ -75,25 +75,35 @@ void pad_info::save(utils::serial& ar)
|
||||||
|
|
||||||
extern void send_sys_io_connect_event(usz index, u32 state);
|
extern void send_sys_io_connect_event(usz index, u32 state);
|
||||||
|
|
||||||
void cellPad_NotifyStateChange(usz index, u64 /*state*/, bool locked)
|
bool cellPad_NotifyStateChange(usz index, u64 /*state*/, bool locked, bool is_blocking = true)
|
||||||
{
|
{
|
||||||
auto info = g_fxo->try_get<pad_info>();
|
auto info = g_fxo->try_get<pad_info>();
|
||||||
|
|
||||||
if (!info)
|
if (!info)
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock lock(pad::g_pad_mutex, std::defer_lock);
|
std::unique_lock lock(pad::g_pad_mutex, std::defer_lock);
|
||||||
|
|
||||||
if (locked)
|
if (locked)
|
||||||
{
|
{
|
||||||
lock.lock();
|
if (is_blocking)
|
||||||
|
{
|
||||||
|
lock.lock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!lock.try_lock())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index >= info->get_max_connect())
|
if (index >= info->get_max_connect())
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto handler = pad::get_current_handler();
|
const auto handler = pad::get_current_handler();
|
||||||
|
@ -102,7 +112,7 @@ void cellPad_NotifyStateChange(usz index, u64 /*state*/, bool locked)
|
||||||
|
|
||||||
if (pad->is_fake_pad)
|
if (pad->is_fake_pad)
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pad_data_internal& reported_info = info->reported_info[index];
|
pad_data_internal& reported_info = info->reported_info[index];
|
||||||
|
@ -117,7 +127,7 @@ void cellPad_NotifyStateChange(usz index, u64 /*state*/, bool locked)
|
||||||
if (~(old_status ^ new_status) & CELL_PAD_STATUS_CONNECTED)
|
if (~(old_status ^ new_status) & CELL_PAD_STATUS_CONNECTED)
|
||||||
{
|
{
|
||||||
// old and new have the same connection status
|
// old and new have the same connection status
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
reported_info.port_status = new_status | CELL_PAD_STATUS_ASSIGN_CHANGES;
|
reported_info.port_status = new_status | CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||||
|
@ -139,6 +149,8 @@ void cellPad_NotifyStateChange(usz index, u64 /*state*/, bool locked)
|
||||||
reported_info.vendor_id = pad->m_vendor_id;
|
reported_info.vendor_id = pad->m_vendor_id;
|
||||||
reported_info.product_id = pad->m_product_id;
|
reported_info.product_id = pad->m_product_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void pad_state_notify_state_change(usz index, u32 state)
|
extern void pad_state_notify_state_change(usz index, u32 state)
|
||||||
|
|
|
@ -36,10 +36,12 @@ extern void sys_io_serialize(utils::serial& ar)
|
||||||
ensure(g_fxo->try_get<libio_sys_config>())->save_or_load(ar);
|
ensure(g_fxo->try_get<libio_sys_config>())->save_or_load(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void cellPad_NotifyStateChange(usz index, u64 state, bool lock = true);
|
extern bool cellPad_NotifyStateChange(usz index, u64 state, bool lock = true, bool is_blocking = true);
|
||||||
|
|
||||||
void config_event_entry(ppu_thread& ppu)
|
void config_event_entry(ppu_thread& ppu)
|
||||||
{
|
{
|
||||||
|
ppu.state += cpu_flag::wait;
|
||||||
|
|
||||||
auto& cfg = *ensure(g_fxo->try_get<libio_sys_config>());
|
auto& cfg = *ensure(g_fxo->try_get<libio_sys_config>());
|
||||||
|
|
||||||
if (!ppu.loaded_from_savestate)
|
if (!ppu.loaded_from_savestate)
|
||||||
|
@ -48,7 +50,10 @@ void config_event_entry(ppu_thread& ppu)
|
||||||
ppu.check_state();
|
ppu.check_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!sys_event_queue_receive(ppu, cfg.queue_id, vm::null, 0))
|
const u32 queue_id = cfg.queue_id;
|
||||||
|
auto queue = idm::get<lv2_obj, lv2_event_queue>(queue_id);
|
||||||
|
|
||||||
|
while (queue && sys_event_queue_receive(ppu, queue_id, vm::null, 0) == CELL_OK)
|
||||||
{
|
{
|
||||||
if (ppu.is_stopped())
|
if (ppu.is_stopped())
|
||||||
{
|
{
|
||||||
|
@ -61,6 +66,7 @@ void config_event_entry(ppu_thread& ppu)
|
||||||
|
|
||||||
// Wakeup
|
// Wakeup
|
||||||
ppu.check_state();
|
ppu.check_state();
|
||||||
|
ppu.state += cpu_flag::wait;
|
||||||
|
|
||||||
const u64 arg1 = ppu.gpr[5];
|
const u64 arg1 = ppu.gpr[5];
|
||||||
const u64 arg2 = ppu.gpr[6];
|
const u64 arg2 = ppu.gpr[6];
|
||||||
|
@ -70,7 +76,17 @@ void config_event_entry(ppu_thread& ppu)
|
||||||
|
|
||||||
if (arg1 == 1)
|
if (arg1 == 1)
|
||||||
{
|
{
|
||||||
cellPad_NotifyStateChange(arg2, arg3);
|
while (!cellPad_NotifyStateChange(arg2, arg3, false))
|
||||||
|
{
|
||||||
|
if (!queue->exists)
|
||||||
|
{
|
||||||
|
// Exit condition
|
||||||
|
queue = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_ctrl::wait_for(100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue