#include <vector>
#include <utility>
#include <algorithm>
+#include <memory>
#include <map>
#include <cstdlib>
// map of fd to read results to supply for reads of that fd
std::map<int,read_cond> read_data;
-// map of data written to each fd
-std::map<int,std::vector<char>> written_data;
+// map of fd to the handler for writes to that fd
+std::map<int, std::unique_ptr<bp_sys::write_handler>> write_hndlr_map;
} // anon namespace
// Test helper methods:
+void init_bpsys()
+{
+ write_hndlr_map[0] = std::unique_ptr<bp_sys::write_handler> { new default_write_handler() };
+ write_hndlr_map[1] = std::unique_ptr<bp_sys::write_handler> { new default_write_handler() };
+ write_hndlr_map[2] = std::unique_ptr<bp_sys::write_handler> { new default_write_handler() };
+}
+
// Allocate a file descriptor
int allocfd()
+{
+ return allocfd(new default_write_handler());
+}
+
+int allocfd(write_handler *whndlr)
{
auto f = std::find(usedfds.begin(), usedfds.end(), false);
if (f == usedfds.end()) {
int r = usedfds.size();
usedfds.push_back(true);
+ write_hndlr_map[r] = std::unique_ptr<bp_sys::write_handler>(whndlr);
return r;
}
*f = true;
- return f - usedfds.begin();
+ auto r = f - usedfds.begin();
+ write_hndlr_map[r] = std::unique_ptr<bp_sys::write_handler>(whndlr);
+ return r;
}
// Supply data to be returned by read()
// retrieve data written via write()
void extract_written_data(int fd, std::vector<char> &data)
{
- data = std::move(written_data[fd]);
+ auto &whandler = write_hndlr_map[fd];
+ if (whandler == nullptr) abort();
+ default_write_handler *dwhndlr = static_cast<default_write_handler *>(whandler.get());
+ data = std::move(dwhndlr->data);
}
int close(int fd)
{
if (size_t(fd) >= usedfds.size()) abort();
+ if (! usedfds[fd]) abort();
usedfds[fd] = false;
+ write_hndlr_map.erase(fd);
return 0;
}
ssize_t write(int fd, const void *buf, size_t count)
{
- std::vector<char> &wd = written_data[fd];
- wd.insert(wd.end(), (char *)buf, (char *)buf + count);
- return count;
+ return write_hndlr_map[fd]->write(fd, buf, count);
}
ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
namespace bp_sys {
+class write_handler
+{
+public:
+ virtual ssize_t write(int fd, const void *buf, size_t count) = 0;
+ virtual ~write_handler() { }
+};
+
+class default_write_handler : public write_handler
+{
+public:
+ std::vector<char> data;
+
+ virtual ssize_t write(int fd, const void *buf, size_t count)
+ {
+ data.insert(data.end(), (char *)buf, (char *)buf + count);
+ return count;
+ }
+};
+
// Test helper functions:
+void init_bpsys();
+
// allocate a file descriptor
int allocfd();
+int allocfd(write_handler *hndlr);
void supply_read_data(int fd, std::vector<char> &data);
void supply_read_data(int fd, std::vector<char> &&data);
{
auto i = regd_fd_watchers.find(fd);
if (i != regd_fd_watchers.end()) {
- i->second->fd_event(*this, fd, events);
+ fd_watcher *watcher = i->second;
+ dasynq::rearm r = watcher->fd_event(*this, fd, events);
+ if (r == dasynq::rearm::REMOVE) {
+ watcher->deregister(*this);
+ }
}
}
{
loop.regd_fd_watchers.erase(watched_fd);
watched_fd = -1;
+ watch_removed();
}
virtual rearm fd_event(eventloop_t & loop, int fd, int flags) = 0;