mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-19 11:43:56 +00:00
Fix thread deletion and small timer progress (#344)
This commit is contained in:
@@ -58,6 +58,10 @@ namespace
|
||||
return !e || e->try_lock(current_thread_id);
|
||||
}
|
||||
|
||||
case handle_types::timer: {
|
||||
return true; // TODO
|
||||
}
|
||||
|
||||
case handle_types::semaphore: {
|
||||
auto* s = c.semaphores.get(h);
|
||||
if (s)
|
||||
|
||||
@@ -210,6 +210,11 @@ class emulator_thread : public ref_counted_object
|
||||
this->marker.mark_as_moved();
|
||||
}
|
||||
|
||||
static bool deleter(emulator_thread& t)
|
||||
{
|
||||
return ref_counted_object::deleter(t) && t.is_terminated();
|
||||
}
|
||||
|
||||
private:
|
||||
void setup_registers(x86_64_emulator& emu, const process_context& context) const;
|
||||
|
||||
|
||||
@@ -136,6 +136,11 @@ class ref_counted_object
|
||||
|
||||
static bool deleter(ref_counted_object& e)
|
||||
{
|
||||
if (e.ref_count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return --e.ref_count == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -361,6 +361,8 @@ namespace syscalls
|
||||
NTSTATUS handle_NtCreateTimer2(const syscall_context& c, emulator_object<handle> timer_handle, uint64_t reserved,
|
||||
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
|
||||
ULONG attributes, ACCESS_MASK desired_access);
|
||||
NTSTATUS handle_NtSetTimerEx(const syscall_context& c, handle timer_handle, uint32_t timer_set_info_class,
|
||||
uint64_t timer_set_information, ULONG timer_set_information_length);
|
||||
|
||||
// syscalls/token.cpp:
|
||||
NTSTATUS
|
||||
@@ -1104,6 +1106,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtUserSetCursor);
|
||||
add_handler(NtOpenMutant);
|
||||
add_handler(NtCreateTimer2);
|
||||
add_handler(NtSetTimerEx);
|
||||
|
||||
#undef add_handler
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace syscalls
|
||||
if (h.value.type == handle_types::thread)
|
||||
{
|
||||
const auto* t = c.proc.threads.get(h);
|
||||
if (t == c.proc.active_thread && t->ref_count == 1)
|
||||
if (t && t->ref_count == 1)
|
||||
{
|
||||
// TODO: Better handle ref counting
|
||||
return STATUS_SUCCESS;
|
||||
@@ -119,6 +119,7 @@ namespace syscalls
|
||||
return h.value.type == handle_types::thread //
|
||||
|| h.value.type == handle_types::mutant //
|
||||
|| h.value.type == handle_types::semaphore //
|
||||
|| h.value.type == handle_types::timer //
|
||||
|| h.value.type == handle_types::event;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,4 +69,10 @@ namespace syscalls
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtSetTimerEx(const syscall_context& /*c*/, handle /*timer_handle*/,
|
||||
uint32_t /*timer_set_info_class*/, uint64_t /*timer_set_information*/,
|
||||
ULONG /*timer_set_information_length*/)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,27 @@ namespace
|
||||
|
||||
void perform_context_switch_work(windows_emulator& win_emu)
|
||||
{
|
||||
auto& threads = win_emu.process.threads;
|
||||
|
||||
for (auto it = threads.begin(); it != threads.end();)
|
||||
{
|
||||
if (!it->second.is_terminated() || it->second.ref_count > 0)
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto [new_it, deleted] = threads.erase(it);
|
||||
if (!deleted)
|
||||
{
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = new_it;
|
||||
}
|
||||
}
|
||||
|
||||
auto& devices = win_emu.process.devices;
|
||||
|
||||
// Crappy mechanism to prevent mutation while iterating.
|
||||
|
||||
Reference in New Issue
Block a user