diff --git a/AK/IDAllocator.h b/AK/IDAllocator.h new file mode 100644 index 0000000000..406fa1ba87 --- /dev/null +++ b/AK/IDAllocator.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +namespace AK { + +class IDAllocator { + +public: + IDAllocator() {} + ~IDAllocator() {} + + int allocate() + { + int r = rand(); + for (int i = 0; i < 100000; ++i) { + int allocated_id = r + i; + if (!m_allocated_ids.contains(allocated_id)) { + m_allocated_ids.set(allocated_id); + return allocated_id; + } + } + ASSERT_NOT_REACHED(); + } + + void deallocate(int id) + { + m_allocated_ids.remove(id); + } + +private: + HashTable m_allocated_ids; +}; +} + +using AK::IDAllocator; diff --git a/Libraries/LibCore/CEventLoop.cpp b/Libraries/LibCore/CEventLoop.cpp index 5d8c0b4e5b..1dac8af3b2 100644 --- a/Libraries/LibCore/CEventLoop.cpp +++ b/Libraries/LibCore/CEventLoop.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -27,21 +27,19 @@ class RPCClient; static CEventLoop* s_main_event_loop; static Vector* s_event_loop_stack; +static IDAllocator s_id_allocator; HashMap>* CEventLoop::s_timers; HashTable* CEventLoop::s_notifiers; -int CEventLoop::s_next_timer_id = 1; int CEventLoop::s_wake_pipe_fds[2]; RefPtr CEventLoop::s_rpc_server; HashMap> s_rpc_clients; -// FIXME: It's not great if this wraps around. -static int s_next_client_id = 0; class RPCClient : public CObject { C_OBJECT(RPCClient) public: explicit RPCClient(RefPtr socket) : m_socket(move(socket)) - , m_client_id(s_next_client_id++) + , m_client_id(s_id_allocator.allocate()) { s_rpc_clients.set(m_client_id, this); add_child(*m_socket); @@ -125,7 +123,7 @@ public: void shutdown() { - s_rpc_clients.remove(m_client_id); + s_id_allocator.deallocate(m_client_id); } private: @@ -442,8 +440,7 @@ int CEventLoop::register_timer(CObject& object, int milliseconds, bool should_re timer->reload(now); timer->should_reload = should_reload; timer->fire_when_not_visible = fire_when_not_visible; - int timer_id = ++s_next_timer_id; // FIXME: This will eventually wrap around. - ASSERT(timer_id); // FIXME: Aforementioned wraparound. + int timer_id = s_id_allocator.allocate(); timer->timer_id = timer_id; s_timers->set(timer_id, move(timer)); return timer_id; @@ -451,6 +448,7 @@ int CEventLoop::register_timer(CObject& object, int milliseconds, bool should_re bool CEventLoop::unregister_timer(int timer_id) { + s_id_allocator.deallocate(timer_id); auto it = s_timers->find(timer_id); if (it == s_timers->end()) return false; diff --git a/Libraries/LibCore/CEventLoop.h b/Libraries/LibCore/CEventLoop.h index af942bef19..0121501d4f 100644 --- a/Libraries/LibCore/CEventLoop.h +++ b/Libraries/LibCore/CEventLoop.h @@ -85,7 +85,6 @@ private: }; static HashMap>* s_timers; - static int s_next_timer_id; static HashTable* s_notifiers;