From 99a5b882d8cfaba6ed18966e893ce70ac3c81fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Tue, 30 May 2017 11:00:37 +0200 Subject: [PATCH] Limit the number of recycled fibers. This allows the process to free up memory after heavy load spikes, while not impacting performance negatively. --- source/vibe/core/core.d | 15 +++++++++++++-- source/vibe/core/task.d | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/source/vibe/core/core.d b/source/vibe/core/core.d index 4f9c0d6..d43f6e3 100644 --- a/source/vibe/core/core.d +++ b/source/vibe/core/core.d @@ -1,7 +1,7 @@ /** This module contains the core functionality of the vibe.d framework. - Copyright: © 2012-2016 RejectedSoftware e.K. + Copyright: © 2012-2017 RejectedSoftware e.K. License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. Authors: Sönke Ludwig */ @@ -763,7 +763,7 @@ unittest { } /// Compatibility overload - use a `@safe nothrow` callback instead. -deprecated("Use anothrow callback as argument to setTimer.") +deprecated("Use an @safe nothrow callback as argument to setTimer.") Timer setTimer(Duration timeout, void delegate() callback, bool periodic = false) @safe nothrow { return setTimer(timeout, () @trusted nothrow { @@ -1108,6 +1108,7 @@ private { TaskScheduler s_scheduler; FixedRingBuffer!TaskFiber s_availableFibers; + size_t s_maxRecycledFibers = 100; string s_privilegeLoweringUserName; string s_privilegeLoweringGroupName; @@ -1124,6 +1125,16 @@ package @property ref TaskScheduler taskScheduler() @safe nothrow @nogc { return package void recycleFiber(TaskFiber fiber) @safe nothrow { + if (s_availableFibers.length >= s_maxRecycledFibers) { + auto fl = s_availableFibers.front; + s_availableFibers.popFront(); + fl.shutdown(); + () @trusted { + try destroy(fl); + catch (Exception e) logWarn("Failed to destroy fiber: %s", e.msg); + } (); + } + if (s_availableFibers.full) s_availableFibers.capacity = 2 * s_availableFibers.capacity; diff --git a/source/vibe/core/task.d b/source/vibe/core/task.d index 584dc5b..44c5067 100644 --- a/source/vibe/core/task.d +++ b/source/vibe/core/task.d @@ -293,6 +293,7 @@ final package class TaskFiber : Fiber { ThreadInfo m_tidInfo; shared size_t m_taskCounter; shared bool m_running; + bool m_shutdown = false; shared(ManualEvent) m_onExit; @@ -352,6 +353,7 @@ final package class TaskFiber : Fiber { logWarn("CoreTaskFiber was resumed with exception but without active task!"); logDiagnostic("Full error: %s", e.toString().sanitize()); } + if (m_shutdown) return; } TaskFuncInfo task; @@ -431,6 +433,19 @@ final package class TaskFiber : Fiber { @property size_t taskCounter() const @safe nothrow { return m_taskCounter; } + /** Shuts down the task handler loop. + */ + void shutdown() + @safe nothrow { + assert(!m_running); + m_shutdown = true; + while (state != Fiber.State.TERM) + () @trusted { + try call(Fiber.Rethrow.no); + catch (Exception e) assert(false, e.msg); + } (); + } + /** Blocks until the task has ended. */ void join(bool interruptiple)(size_t task_counter)