From c6518eb6e1caa68cdf0dc242d52cfc172b96efdc Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Fri, 2 Aug 2013 18:36:38 -0700 Subject: Lua's dumpvars is now properly yielding if needed. --- Makefile | 2 ++ includes/HelperTasks.h | 24 ++++++++++++++++++++++++ src/BLua.cc | 22 +++++++++++++++++++++- src/HelperTasks.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 includes/HelperTasks.h create mode 100644 src/HelperTasks.cc diff --git a/Makefile b/Makefile index acb2640..3386bf8 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,8 @@ StdIO.cc \ Task.cc \ TaskMan.cc \ \ +HelperTasks.cc \ +\ Http.cc \ HttpServer.cc \ SimpleMustache.cc \ diff --git a/includes/HelperTasks.h b/includes/HelperTasks.h new file mode 100644 index 0000000..6f3f0ff --- /dev/null +++ b/includes/HelperTasks.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +namespace Balau { + +#define COPY_BUFSIZE 4096 + +class CopyTask : public StacklessTask { + public: + CopyTask(IO s, IO d, ssize_t tocopy = -1); + virtual const char * getName() const override { return m_name.to_charp(); } + virtual void Do(); + private: + char m_buffer[COPY_BUFSIZE]; + IO m_s, m_d; + ssize_t m_tocopy, m_current = 0, m_written, m_read; + size_t m_towrite; + String m_name; +}; + +}; diff --git a/src/BLua.cc b/src/BLua.cc index 29f4a58..7eda510 100644 --- a/src/BLua.cc +++ b/src/BLua.cc @@ -3,6 +3,7 @@ #include "Printer.h" #include "Input.h" #include "Buffer.h" +#include "HelperTasks.h" extern "C" { #include @@ -90,7 +91,26 @@ int Balau::LuaStatics::dumpvars(lua_State * __L) { IO h(L.recast()); - L.dumpvars(h, prefix); + if (h.isA()) { + L.dumpvars(h, prefix); + } else { + IO s(new Buffer()); + L.dumpvars(h, prefix); + Task * t = new CopyTask(s, h); + Events::TaskEvent * evt = new Events::TaskEvent(t); + L.yield(Future([evt, s]() mutable { + for (;;) { + if (evt->gotSignal()) { + evt->ack(); + delete evt; + s->close(); + } else { + Task::operationYield(evt, Task::INTERRUPTIBLE); + } + } + return 0; + })); + } return 0; } diff --git a/src/HelperTasks.cc b/src/HelperTasks.cc new file mode 100644 index 0000000..ab1c2a9 --- /dev/null +++ b/src/HelperTasks.cc @@ -0,0 +1,42 @@ +#include + +#include "HelperTasks.h" + +Balau::CopyTask::CopyTask(IO s, IO d, ssize_t tocopy) + : m_s(s) + , m_d(d) + , m_tocopy(tocopy) +{ + m_name.set("CopyTask from %s to %s", s->getName(), d->getName()); +} + +void Balau::CopyTask::Do() { + ssize_t toread, w; + + try { + for (;;) { + switch (m_state) { + case 0: + toread = m_tocopy >= 0 ? m_tocopy - m_current : COPY_BUFSIZE; + toread = std::min(toread, (ssize_t) COPY_BUFSIZE); + m_read = m_s->read(m_buffer, toread); + AAssert(m_read >= 0, "Error while reading"); + if (m_s->isEOF() || !m_read) + return; + m_written = 0; + m_state = 1; + case 1: + do { + w = m_d->write(m_buffer + m_written, m_read - m_written); + AAssert(w >= 0, "Error while writing"); + m_written += w; + } while (m_read != m_written); + m_state = 0; + m_current += m_read; + } + } + } + catch (EAgain & e) { + taskSwitch(); + } +} -- cgit v1.2.3