diff options
Diffstat (limited to '')
-rw-r--r-- | src/MusicBuffer.cxx | 6 | ||||
-rw-r--r-- | src/util/SliceBuffer.hxx | 27 |
2 files changed, 28 insertions, 5 deletions
diff --git a/src/MusicBuffer.cxx b/src/MusicBuffer.cxx index ec6e52054..5fddddc22 100644 --- a/src/MusicBuffer.cxx +++ b/src/MusicBuffer.cxx @@ -21,6 +21,7 @@ #include "MusicBuffer.hxx" #include "MusicChunk.hxx" #include "util/SliceBuffer.hxx" +#include "mpd_error.h" #include <glib.h> @@ -32,7 +33,10 @@ struct music_buffer : public SliceBuffer<music_chunk> { music_buffer(unsigned num_chunks) :SliceBuffer(num_chunks), - mutex(g_mutex_new()) {} + mutex(g_mutex_new()) { + if (IsOOM()) + MPD_ERROR("Failed to allocate buffer"); + } ~music_buffer() { g_mutex_free(mutex); diff --git a/src/util/SliceBuffer.hxx b/src/util/SliceBuffer.hxx index 1f5ff873d..c61f164f4 100644 --- a/src/util/SliceBuffer.hxx +++ b/src/util/SliceBuffer.hxx @@ -20,10 +20,9 @@ #ifndef MPD_SLICE_BUFFER_HXX #define MPD_SLICE_BUFFER_HXX +#include "HugeAllocator.hxx" #include "gcc.h" -#include <glib.h> - #include <utility> #include <new> @@ -66,10 +65,15 @@ class SliceBuffer { */ Slice *available; + size_t CalcAllocationSize() const { + return n_max * sizeof(Slice); + } + public: SliceBuffer(unsigned _count) :n_max(_count), n_initialized(0), n_allocated(0), - data(g_new(Slice, n_max)), available(nullptr) { + data((Slice *)HugeAllocate(CalcAllocationSize())), + available(nullptr) { assert(n_max > 0); } @@ -78,12 +82,19 @@ public: assertion checks for leaks */ assert(n_allocated == 0); - g_free(data); + HugeFree(data, CalcAllocationSize()); } SliceBuffer(const SliceBuffer &other) = delete; SliceBuffer &operator=(const SliceBuffer &other) = delete; + /** + * @return true if buffer allocation (by the constructor) has failed + */ + bool IsOOM() { + return data == nullptr; + } + unsigned GetCapacity() const { return n_max; } @@ -136,6 +147,14 @@ public: slice->next = available; available = slice; --n_allocated; + + /* give memory back to the kernel when the last slice + was freed */ + if (n_allocated == 0) { + HugeDiscard(data, CalcAllocationSize()); + n_initialized = 0; + available = nullptr; + } } }; |