[esnacc-dev] [PATCH 2/2] cxx-lib/asn-buf: Stream buffer monitor
Aaron Conole
aconole at bytheb.org
Fri Aug 26 19:32:09 UTC 2016
Introduce a mechanism for monitoring and calling back stream buffer
objects. This is useful for building busy-wait loops, which can perform
tasks as interleaved callbacks.
Signed-off-by: Aaron Conole <aconole at bytheb.org>
---
cxx-lib/inc/asn-buf.h | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
diff --git a/cxx-lib/inc/asn-buf.h b/cxx-lib/inc/asn-buf.h
index d316ba9..872484b 100644
--- a/cxx-lib/inc/asn-buf.h
+++ b/cxx-lib/inc/asn-buf.h
@@ -7,9 +7,11 @@
#pragma warning(push,3)
#endif
+#include <algorithm>
#include <deque>
#include <fstream>
#include <list>
+#include <map>
#include <ostream>
#include <sstream>
#include <streambuf>
@@ -413,6 +415,103 @@ private:
};
+
+class StreambufCallback
+{
+public:
+ enum Streambuf_CB_RESULT {
+ CB_NONE,
+ CB_DROP_STREAM
+ };
+
+ enum Streambuf_CB_STATUS {
+ CB_READ_OK,
+ CB_WRITE_OK,
+ CB_OPENED,
+ CB_CLOSED
+ };
+
+ StreambufCallback(){}
+ virtual ~StreambufCallback(){}
+ virtual Streambuf_CB_RESULT callback(Streambuf_CB_STATUS status,
+ std::streambuf *stream) = 0;
+};
+
+class StreambufMonitor
+{
+public:
+ typedef std::map<std::streambuf*,StreambufCallback&> callbackMap;
+
+private:
+ callbackMap callbacks;
+ std::list<std::streambuf*> toDrop;
+
+ static void check_buffer(callbackMap::value_type t,
+ std::list<std::streambuf*> &StreamDropList)
+ {
+ std::streambuf *Stream = t.first;
+ std::streamsize Bytes = Stream->in_avail();
+ StreambufCallback::Streambuf_CB_RESULT result =
+ StreambufCallback::CB_NONE;
+
+ if (Bytes == -1) {
+ result = (t.second).callback(StreambufCallback::CB_CLOSED, Stream);
+ } else if (Bytes > 0) {
+ result = (t.second).callback(StreambufCallback::CB_READ_OK,
+ Stream);
+ }
+
+ if (result == StreambufCallback::CB_DROP_STREAM) {
+ StreamDropList.push_back(Stream);
+ }
+ }
+
+ struct buffer_checker
+ {
+ StreambufMonitor *Mon;
+ void operator()(callbackMap::value_type t)
+ {
+ StreambufMonitor::check_buffer(t, Mon->toDrop);
+ }
+ };
+
+public:
+ StreambufMonitor() {}
+ ~StreambufMonitor() {}
+
+ /**
+ * Adds a streambuf to be monitored, with a specific callback instance. */
+ bool push(std::streambuf *Stream, StreambufCallback &CB, bool callOpen)
+ {
+ if (callOpen) {
+ StreambufCallback::Streambuf_CB_RESULT result =
+ CB.callback(StreambufCallback::CB_OPENED, Stream);
+ if (result == StreambufCallback::CB_DROP_STREAM)
+ return false;
+ }
+ callbacks.insert(
+ std::pair<std::streambuf*,StreambufCallback&>(Stream,CB));
+ return true;
+ }
+
+ /**
+ * Removes a streambuf from the monitor. */
+ bool pop(std::streambuf *Stream)
+ {
+ if (callbacks.erase(Stream))
+ return true;
+ return false;
+ }
+
+ void operator()()
+ {
+ buffer_checker bc;
+ bc.Mon = this;
+ std::for_each(callbacks.begin(), callbacks.end(), bc);
+ toDrop.clear();
+ }
+};
+
} // end namespace SNACC
SNACCDLL_API void sortSet(std::list<SNACC::AsnBuf> &bufList);
--
2.5.5
More information about the dev
mailing list