Protect against timer exhaustion
Currently there is no check to see if all timers
are used. This adds a check so that under many
connections we don't get a double free.
Tested: Spun up many connections and double free
went away
Change-Id: I7c6914f566064c57ad28d3bfe79a53e44f598a35
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/http/http_connection.h b/http/http_connection.h
index 9f6c7b6..b786175 100644
--- a/http/http_connection.h
+++ b/http/http_connection.h
@@ -864,6 +864,12 @@
close();
});
+
+ if (!timerCancelKey)
+ {
+ close();
+ return;
+ }
BMCWEB_LOG_DEBUG << this << " timer added: " << &timerQueue << ' '
<< *timerCancelKey;
}
diff --git a/http/timer_queue.h b/http/timer_queue.h
index d7a427e..b61c188 100644
--- a/http/timer_queue.h
+++ b/http/timer_queue.h
@@ -13,14 +13,14 @@
{
constexpr const size_t timerQueueTimeoutSeconds = 5;
-
+constexpr const size_t maxSize = 100;
// fast timer queue for fixed tick value.
class TimerQueue
{
public:
TimerQueue()
{
- dq.set_capacity(100);
+ dq.set_capacity(maxSize);
}
void cancel(size_t k)
@@ -32,8 +32,13 @@
}
}
- size_t add(std::function<void()> f)
+ std::optional<size_t> add(std::function<void()> f)
{
+ if (dq.size() == maxSize)
+ {
+ return std::nullopt;
+ }
+
dq.push_back(
std::make_pair(std::chrono::steady_clock::now(), std::move(f)));
size_t ret = step + dq.size() - 1;