From: Davin McCall Date: Sat, 10 Feb 2018 15:51:35 +0000 (+0000) Subject: control: rework handle allocation. X-Git-Tag: v0.1.0~34 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=5c461c4271841b678aefed4262921b6a3c362e9a;p=oweals%2Fdinit.git control: rework handle allocation. --- diff --git a/src/control.cc b/src/control.cc index fd89e20..e285e2b 100644 --- a/src/control.cc +++ b/src/control.cc @@ -292,20 +292,16 @@ bool control_conn_t::list_services() control_conn_t::handle_t control_conn_t::allocate_service_handle(service_record *record) { - // Try to find a unique handle (integer) in a single pass. Start with 0, and keep track of the largest - // handle seen so far. If we find the current candidate, we set the candidate to (largest+1). - bool is_unique = true; - handle_t largest_seen = 0; + // Try to find a unique handle (integer) in a single pass. Since the map is ordered, we can search until + // we find a gap in the handle values. handle_t candidate = 0; for (auto p : keyServiceMap) { - if (p.first > largest_seen) largest_seen = p.first; - if (p.first == candidate) { - if (largest_seen == std::numeric_limits::max()) throw std::bad_alloc(); - candidate = largest_seen + 1; - } - is_unique &= (p.second != record); + if (p.first == candidate) candidate++; + else break; } + bool is_unique = (serviceKeyMap.find(record) == serviceKeyMap.end()); + // The following operations perform allocation (can throw std::bad_alloc). If an exception occurs we // must undo any previous actions: if (is_unique) { diff --git a/src/includes/control.h b/src/includes/control.h index dd92201..e2aa1df 100644 --- a/src/includes/control.h +++ b/src/includes/control.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -104,7 +105,7 @@ class control_conn_t : private service_listener // in communction using handle_t = uint32_t; std::unordered_multimap serviceKeyMap; - std::unordered_map keyServiceMap; + std::map keyServiceMap; // Buffer for outgoing packets. Each outgoing back is represented as a vector. list> outbuf;