From d04ce4cb7d4aa3eb72bc79c09dfe5bb025ad79f4 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 17 Nov 2012 21:50:35 +0000 Subject: Gracefully handle failure to send notifications due to buffer overrun. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4827 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/Context.cpp | 16 +++++++++------- src/server/Context.hpp | 6 ++++-- src/server/PortImpl.cpp | 10 +++++++--- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/server/Context.cpp b/src/server/Context.cpp index 3b07373d..20d78c0e 100644 --- a/src/server/Context.cpp +++ b/src/server/Context.cpp @@ -53,7 +53,7 @@ Context::Context(Engine& engine, ID id) , _realtime(true) {} -void +bool Context::notify(LV2_URID key, FrameTime time, PortImpl* port, @@ -63,14 +63,16 @@ Context::notify(LV2_URID key, { const Notification n(port, time, key, size, type); if (_event_sink.write_space() < sizeof(n) + size) { - _engine.log().warn("Notification ring overflow\n"); + return false; + } + if (_event_sink.write(sizeof(n), &n) != sizeof(n)) { + _engine.log().error("Error writing header to notification ring\n"); + } else if (_event_sink.write(size, body) != size) { + _engine.log().error("Error writing body to notification ring\n"); } else { - if (_event_sink.write(sizeof(n), &n) != sizeof(n)) { - _engine.log().error("Error writing header to notification ring\n"); - } else if (_event_sink.write(size, body) != size) { - _engine.log().error("Error writing body to notification ring\n"); - } + return true; } + return false; } void diff --git a/src/server/Context.hpp b/src/server/Context.hpp index cabfcc89..5343b817 100644 --- a/src/server/Context.hpp +++ b/src/server/Context.hpp @@ -53,8 +53,10 @@ public: virtual ~Context() {} - /** Send a notification from this run context. */ - void notify(LV2_URID key = 0, + /** Send a notification from this run context. + * @return false on failure (ring is full) + */ + bool notify(LV2_URID key = 0, FrameTime time = 0, PortImpl* port = 0, uint32_t size = 0, diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp index a5fe8fe6..dfd24dc0 100644 --- a/src/server/PortImpl.cpp +++ b/src/server/PortImpl.cpp @@ -367,9 +367,13 @@ PortImpl::broadcast_value(Context& context, bool force) } if (val.is_valid() && (force || val != _last_broadcasted_value)) { - _last_broadcasted_value = val; - context.notify(key, context.start(), this, - val.size(), val.type(), val.get_body()); + if (context.notify(key, context.start(), this, + val.size(), val.type(), val.get_body())) { + _last_broadcasted_value = val; + } + + /* On failure, last_broadcasted_value remains unaffected, so we'll try + again next cycle and so on until the value is finally delivered. */ } } -- cgit v1.2.1