diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | includes/SmartWriter.h | 2 | ||||
-rw-r--r-- | src/SmartWriter.cc | 41 |
3 files changed, 28 insertions, 16 deletions
@@ -51,6 +51,7 @@ Output.cc \ MMap.cc \ Socket.cc \ Selectable.cc \ +SmartWriter.cc \ Buffer.cc \ BStream.cc \ ZHandle.cc \ diff --git a/includes/SmartWriter.h b/includes/SmartWriter.h index d8baf27..b237f29 100644 --- a/includes/SmartWriter.h +++ b/includes/SmartWriter.h @@ -11,7 +11,7 @@ class SmartWriter : public Filter { SmartWriter(IO<Handle> h) : Filter(h) { AAssert(h->canWrite(), "SmartWriter can't write"); m_name.set("SmartWriter(%s)", h->getName()); } virtual ssize_t write(const void * buf, size_t count) throw (GeneralException) override; virtual const char * getName() override { return m_name.to_charp(); } - virtual void close() override; + virtual void close() throw (GeneralException) override; private: SmartWriterTask * m_writerTask = NULL; String m_name; diff --git a/src/SmartWriter.cc b/src/SmartWriter.cc index 9a32330..662511a 100644 --- a/src/SmartWriter.cc +++ b/src/SmartWriter.cc @@ -5,9 +5,9 @@ namespace { struct WriteCell { - ~WriteCell() { delete buffer; } - const void * buffer = NULL; - const uint8_t * ptr; + ~WriteCell() { free(buffer); } + void * buffer = NULL; + uint8_t * ptr; size_t size; bool stop = false; bool close = false; @@ -32,7 +32,7 @@ class SmartWriterTask : public Balau::StacklessTask { cell->close = closeHandle; m_queue.push(cell); } - bool gotError() { return m_gotError; } + bool gotError() { return m_gotError.load(); } private: virtual ~SmartWriterTask() { empty(); } virtual const char * getName() const override { return m_name.to_charp(); } @@ -65,18 +65,29 @@ class SmartWriterTask : public Balau::StacklessTask { } ssize_t r = 0; - try { - r = m_h->write(m_current->ptr, m_current->size); - } - catch (Balau::EAgain & e) { - waitFor(e.getEvent()); - taskSwitch(); + + if (m_gotError.load()) { + delete m_current; + m_current = NULL; + r = -1; + } else { + try { + r = m_h->write(m_current->ptr, m_current->size); + } + catch (Balau::EAgain & e) { + waitFor(e.getEvent()); + taskSwitch(); + } } - m_current->ptr += r; - m_current->size -= r; + if (r < 0) { + m_gotError.store(true); + } else { + m_current->ptr += r; + m_current->size -= r; + } - if (m_current->size == 0) { + if (m_current && m_current->size == 0) { delete m_current; m_current = NULL; } @@ -88,12 +99,12 @@ class SmartWriterTask : public Balau::StacklessTask { } Balau::IO<Balau::Handle> m_h; Balau::String m_name; - std::atomic<bool> m_gotError = false; + std::atomic<bool> m_gotError; Balau::TQueue<WriteCell> m_queue; WriteCell * m_current = NULL; }; -void Balau::SmartWriter::close() { +void Balau::SmartWriter::close() throw (GeneralException) { if (m_writerTask) { m_writerTask->stop(!isDetached()); m_writerTask = NULL; |