diff options
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | Makefile | 11 | ||||
m--------- | libeio | 0 | ||||
-rw-r--r-- | src/Handle.cc | 82 | ||||
-rw-r--r-- | src/Input.cc | 123 | ||||
-rw-r--r-- | src/Output.cc | 124 |
6 files changed, 217 insertions, 126 deletions
diff --git a/.gitmodules b/.gitmodules index e78fd64..94de112 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "libcoro"] path = libcoro url = git.grumpycoder.net:/pub/repo.git/libcoro -[submodule "libeio"] - path = libeio - url = git.grumpycoder.net:/pub/repo.git/libeio [submodule "libev"] path = libev url = git.grumpycoder.net:/pub/repo.git/libev @@ -24,7 +24,7 @@ CPPFLAGS += -g -DDEBUG -DEV_VERIFY=3 LDFLAGS += -g endif -INCLUDES = includes libcoro libeio libev LuaJIT/src +INCLUDES = includes libcoro libev LuaJIT/src LIBS = z ifeq ($(SYSTEM),Darwin) @@ -111,7 +111,7 @@ LDFLAGS += $(ARCH_FLAGS) LDLIBS = $(addprefix -l, $(LIBS)) vpath %.cc src:tests -vpath %.c libcoro:libeio:libev:win32/pthreads-win32:win32/iconv:win32/regex +vpath %.c libcoro:libev:win32/pthreads-win32:win32/iconv:win32/regex BALAU_SOURCES = \ Exceptions.cc \ @@ -171,9 +171,6 @@ LIBEV_SOURCES = \ ev.c \ event.c \ -LIBEIO_SOURCES = \ -eio.c \ - TEST_SOURCES = \ test-Sanity.cc \ test-String.cc \ @@ -188,9 +185,9 @@ test-Regex.cc \ LIB = libBalau.a -BALAU_OBJECTS = $(addsuffix .o, $(notdir $(basename $(BALAU_SOURCES) $(LIBCORO_SOURCES) $(LIBEIO_SOURCES) $(LIBEV_SOURCES) $(WIN32_SOURCES) $(DARWIN_SOURCES)))) +BALAU_OBJECTS = $(addsuffix .o, $(notdir $(basename $(BALAU_SOURCES) $(LIBCORO_SOURCES) $(LIBEV_SOURCES) $(WIN32_SOURCES) $(DARWIN_SOURCES)))) -WHOLE_SOURCES = $(BALAU_SOURCES) $(LIBCORO_SOURCES) $(LIBEIO_SOURCES) $(LIBEV_SOURCES) $(WIN32_SOURCES) $(DARWIN_SOURCES) $(TEST_SOURCES) +WHOLE_SOURCES = $(BALAU_SOURCES) $(LIBCORO_SOURCES) $(LIBEV_SOURCES) $(WIN32_SOURCES) $(DARWIN_SOURCES) $(TEST_SOURCES) TESTS = $(addsuffix .$(BINEXT), $(notdir $(basename $(TEST_SOURCES)))) ALL_OBJECTS = $(addsuffix .o, $(notdir $(basename $(WHOLE_SOURCES)))) diff --git a/libeio b/libeio deleted file mode 160000 -Subproject f6a4a63e6978359f5742136c28a6412f4e0979a diff --git a/src/Handle.cc b/src/Handle.cc index 9bcb419..11f64d6 100644 --- a/src/Handle.cc +++ b/src/Handle.cc @@ -1,10 +1,11 @@ #include <typeinfo> +#include <errno.h> #include "ev++.h" -#include "eio.h" #include "Main.h" #include "TaskMan.h" #include "Handle.h" #include "Printer.h" +#include "Async.h" #ifdef _WIN32 static const char * strerror_r(int errorno, char * buf, size_t bufsize) { @@ -17,50 +18,6 @@ static const char * strerror_r(int errorno, char * buf, size_t bufsize) { } #endif -class eioInterface : public Balau::AtStart { - public: - eioInterface() : AtStart(100) { } - void repeatCB(ev::idle & w, int revents); - void readyCB(ev::async & w, int revents); - static void wantPoll(); - virtual void doStart(); - ev::idle m_repeat; - ev::async m_ready; -}; - -static eioInterface eioIF; - -void eioInterface::repeatCB(ev::idle & w, int revents) { - if (eio_poll() != -1) - w.stop(); -} - -void eioInterface::readyCB(ev::async & w, int revents) { - if (eio_poll() == -1) - m_repeat.start(); -} - -void eioInterface::doStart() { - Balau::Printer::elog(Balau::E_HANDLE, "Starting the eio interface"); - - Balau::TaskMan * taskMan = Balau::TaskMan::getDefaultTaskMan(); - IAssert(taskMan, "The eio interface shouldn't have started before the task manager"); - struct ev_loop * loop = taskMan->getLoop(); - - m_repeat.set(loop); - m_repeat.set<eioInterface, &eioInterface::repeatCB>(this); - - m_ready.set(loop); - m_ready.set<eioInterface, &eioInterface::readyCB>(this); - m_ready.start(); - - eio_init(wantPoll, NULL); -} - -void eioInterface::wantPoll() { - eioIF.m_ready.send(); -} - bool Balau::Handle::canSeek() { return false; } bool Balau::Handle::canRead() { return false; } bool Balau::Handle::canWrite() { return false; } @@ -225,28 +182,41 @@ bool Balau::SeekableHandle::isEOF() { return m_rOffset == getSize(); } +namespace { + struct cbResults_t { Balau::Events::Custom evt; int result, errorno; }; -static int eioDone(eio_req * req) { - cbResults_t * cbResults = (cbResults_t *) req->data; - cbResults->result = req->result; - cbResults->errorno = req->errorno; - cbResults->evt.doSignal(); - return 0; -} +class AsyncOpMkdir : public Balau::AsyncOperation { + public: + AsyncOpMkdir(const char * path, mode_t mode, cbResults_t * results) : m_path(path), m_mode(mode), m_results(results) { } + virtual void run() { + int r = m_results->result = mkdir(m_path, m_mode); + m_results->errorno = r < 0 ? errno : 0; + } + virtual void done() { + m_results->evt.doSignal(); + delete this; + } + private: + const char * m_path; + mode_t m_mode; + cbResults_t * m_results; +}; + +}; int Balau::FileSystem::mkdir(const char * path) throw (GeneralException) { cbResults_t cbResults; - eio_req * r = eio_mkdir(path, 0755, 0, eioDone, &cbResults); - EAssert(r != NULL, "eio_mkdir returned a NULL eio_req"); + createAsyncOp(new AsyncOpMkdir(path, 0755, &cbResults)); Task::operationYield(&cbResults.evt); - char str[4096]; - if (cbResults.result < 0) + if (cbResults.result < 0) { + char str[4096]; throw GeneralException(String("Unable to create directory ") + path + ": " + strerror_r(cbResults.errorno, str, sizeof(str)) + " (err#" + cbResults.errorno + ")"); + } return cbResults.result; } diff --git a/src/Input.cc b/src/Input.cc index 3608cd0..5e8c36c 100644 --- a/src/Input.cc +++ b/src/Input.cc @@ -3,9 +3,10 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -#include "eio.h" +#include "Async.h" #include "Input.h" #include "Task.h" +#include "TaskMan.h" #include "Printer.h" #ifdef _WIN32 @@ -19,33 +20,52 @@ static const char * strerror_r(int errorno, char * buf, size_t bufsize) { } #endif +namespace { + struct cbResults_t { Balau::Events::Custom evt; int result, errorno; }; -static int eioDone(eio_req * req) { - cbResults_t * cbResults = (cbResults_t *) req->data; - cbResults->result = req->result; - cbResults->errorno = req->errorno; - cbResults->evt.doSignal(); - return 0; -} +class AsyncOpOpen : public Balau::AsyncOperation { + public: + AsyncOpOpen(const char * path, cbResults_t * results) : m_path(path), m_results(results) { } + virtual void run() { + int r = m_results->result = open(m_path, O_RDONLY); + m_results->errorno = r < 0 ? errno : 0; + } + virtual void done() { + m_results->evt.doSignal(); + delete this; + } + private: + const char * m_path; + cbResults_t * m_results; +}; struct cbStatsResults_t { Balau::Events::Custom evt; int result, errorno; - EIO_STRUCT_STAT statdata; + struct stat statdata; }; -static int eioStatsDone(eio_req * req) { - cbStatsResults_t * cbStatsResults = (cbStatsResults_t *) req->data; - cbStatsResults->result = req->result; - cbStatsResults->errorno = req->errorno; - cbStatsResults->statdata = *(EIO_STRUCT_STAT *) req->ptr2; - cbStatsResults->evt.doSignal(); - return 0; -} +class AsyncOpStat : public Balau::AsyncOperation { + public: + AsyncOpStat(int fd, cbStatsResults_t * results) : m_fd(fd), m_results(results) { } + virtual void run() { + int r = m_results->result = fstat(m_fd, &m_results->statdata); + m_results->errorno = r < 0 ? errno : 0; + } + virtual void done() { + m_results->evt.doSignal(); + delete this; + } + private: + int m_fd; + cbStatsResults_t * m_results; +}; + +}; Balau::Input::Input(const char * fname) throw (GeneralException) { m_name.set("Input(%s)", fname); @@ -54,14 +74,13 @@ Balau::Input::Input(const char * fname) throw (GeneralException) { Printer::elog(E_INPUT, "Opening file %s", fname); cbResults_t cbResults; - eio_req * r = eio_open(fname, O_RDONLY, 0, 0, eioDone, &cbResults); - EAssert(r != NULL, "eio_open returned a NULL eio_req"); + createAsyncOp(new AsyncOpOpen(fname, &cbResults)); Task::operationYield(&cbResults.evt); if (cbResults.result < 0) { - char str[4096]; if (cbResults.errorno == ENOENT) { throw ENoEnt(fname); } else { + char str[4096]; throw GeneralException(String("Unable to open file ") + m_name + " for reading: " + strerror_r(cbResults.errorno, str, sizeof(str)) + " (err#" + cbResults.errorno + ")"); } } else { @@ -69,8 +88,7 @@ Balau::Input::Input(const char * fname) throw (GeneralException) { } cbStatsResults_t cbStatsResults; - r = eio_fstat(m_fd, 0, eioStatsDone, &cbStatsResults); - EAssert(r != NULL, "eio_fstat returned a NULL eio_req"); + createAsyncOp(new AsyncOpStat(m_fd, &cbStatsResults)); Task::operationYield(&cbStatsResults.evt); if (cbStatsResults.result == 0) { m_size = cbStatsResults.statdata.st_size; @@ -78,27 +96,72 @@ Balau::Input::Input(const char * fname) throw (GeneralException) { } } +namespace { + +class AsyncOpClose : public Balau::AsyncOperation { + public: + AsyncOpClose(int fd, cbResults_t * results) : m_fd(fd), m_results(results) { } + virtual void run() { + int r = m_results->result = close(m_fd); + m_results->errorno = r < 0 ? errno : 0; + } + virtual void done() { + m_results->evt.doSignal(); + delete this; + } + private: + int m_fd; + cbResults_t * m_results; +}; + +}; + void Balau::Input::close() throw (GeneralException) { if (m_fd < 0) return; cbResults_t cbResults; - eio_req * r = eio_close(m_fd, 0, eioDone, &cbResults); - EAssert(r != NULL, "eio_close returned a NULL eio_req"); - m_fd = -1; + createAsyncOp(new AsyncOpClose(m_fd, &cbResults)); Task::operationYield(&cbResults.evt); + m_fd = -1; if (cbResults.result < 0) { char str[4096]; strerror_r(cbResults.errorno, str, sizeof(str)); throw GeneralException(String("Unable to close file ") + m_name + ": " + str); - } else { - m_fd = cbResults.result; } } +namespace { + +struct cbReadResults_t { + Balau::Events::Custom evt; + ssize_t result; + int errorno; +}; + +class AsyncOpRead : public Balau::AsyncOperation { + public: + AsyncOpRead(int fd, void * buf, size_t count, off_t offset, cbReadResults_t * results) : m_fd(fd), m_buf(buf), m_count(count), m_offset(offset), m_results(results) { } + virtual void run() { + ssize_t r = m_results->result = pread(m_fd, m_buf, m_count, m_offset); + m_results->errorno = r < 0 ? errno : 0; + } + virtual void done() { + m_results->evt.doSignal(); + delete this; + } + private: + int m_fd; + void * m_buf; + size_t m_count; + off_t m_offset; + cbReadResults_t * m_results; +}; + +}; + ssize_t Balau::Input::read(void * buf, size_t count) throw (GeneralException) { - cbResults_t cbResults; - eio_req * r = eio_read(m_fd, buf, count, getROffset(), 0, eioDone, &cbResults); - EAssert(r != NULL, "eio_read returned a NULL eio_req"); + cbReadResults_t cbResults; + createAsyncOp(new AsyncOpRead(m_fd, buf, count, getROffset(), &cbResults)); Task::operationYield(&cbResults.evt); if (cbResults.result > 0) { rseek(cbResults.result, SEEK_CUR); diff --git a/src/Output.cc b/src/Output.cc index dd0a588..1f4c36f 100644 --- a/src/Output.cc +++ b/src/Output.cc @@ -3,9 +3,10 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -#include "eio.h" +#include "Async.h" #include "Output.h" #include "Task.h" +#include "TaskMan.h" #include "Printer.h" #ifdef _WIN32 @@ -19,33 +20,53 @@ static const char * strerror_r(int errorno, char * buf, size_t bufsize) { } #endif +namespace { + struct cbResults_t { Balau::Events::Custom evt; int result, errorno; }; -static int eioDone(eio_req * req) { - cbResults_t * cbResults = (cbResults_t *) req->data; - cbResults->result = req->result; - cbResults->errorno = req->errorno; - cbResults->evt.doSignal(); - return 0; -} +class AsyncOpOpen : public Balau::AsyncOperation { + public: + AsyncOpOpen(const char * path, bool truncate, cbResults_t * results) : m_path(path), m_truncate(truncate), m_results(results) { } + virtual void run() { + int r = m_results->result = open(m_path, O_WRONLY | O_CREAT | (m_truncate ? O_TRUNC : 0), 0755); + m_results->errorno = r < 0 ? errno : 0; + } + virtual void done() { + m_results->evt.doSignal(); + delete this; + } + private: + const char * m_path; + bool m_truncate; + cbResults_t * m_results; +}; struct cbStatsResults_t { Balau::Events::Custom evt; int result, errorno; - EIO_STRUCT_STAT statdata; + struct stat statdata; }; -static int eioStatsDone(eio_req * req) { - cbStatsResults_t * cbStatsResults = (cbStatsResults_t *) req->data; - cbStatsResults->result = req->result; - cbStatsResults->errorno = req->errorno; - cbStatsResults->statdata = *(EIO_STRUCT_STAT *) req->ptr2; - cbStatsResults->evt.doSignal(); - return 0; -} +class AsyncOpStat : public Balau::AsyncOperation { + public: + AsyncOpStat(int fd, cbStatsResults_t * results) : m_fd(fd), m_results(results) { } + virtual void run() { + int r = m_results->result = fstat(m_fd, &m_results->statdata); + m_results->errorno = r < 0 ? errno : 0; + } + virtual void done() { + m_results->evt.doSignal(); + delete this; + } + private: + int m_fd; + cbStatsResults_t * m_results; +}; + +}; Balau::Output::Output(const char * fname, bool truncate) throw (GeneralException) { m_name.set("Output(%s)", fname); @@ -54,14 +75,13 @@ Balau::Output::Output(const char * fname, bool truncate) throw (GeneralException Printer::elog(E_OUTPUT, "Opening file %s", fname); cbResults_t cbResults; - eio_req * r = eio_open(fname, O_WRONLY | O_CREAT | (truncate ? O_TRUNC : 0), 0755, 0, eioDone, &cbResults); - EAssert(r != NULL, "eio_open returned a NULL eio_req"); + createAsyncOp(new AsyncOpOpen(fname, truncate, &cbResults)); Task::operationYield(&cbResults.evt); if (cbResults.result < 0) { - char str[4096]; if (cbResults.errorno == ENOENT) { throw ENoEnt(fname); } else { + char str[4096]; throw GeneralException(String("Unable to open file ") + m_name + " for reading: " + strerror_r(cbResults.errorno, str, sizeof(str)) + " (err#" + cbResults.errorno + ")"); } } else { @@ -69,8 +89,7 @@ Balau::Output::Output(const char * fname, bool truncate) throw (GeneralException } cbStatsResults_t cbStatsResults; - r = eio_fstat(m_fd, 0, eioStatsDone, &cbStatsResults); - EAssert(r != NULL, "eio_fstat returned a NULL eio_req"); + createAsyncOp(new AsyncOpStat(m_fd, &cbStatsResults)); Task::operationYield(&cbStatsResults.evt); if (cbStatsResults.result == 0) { m_size = cbStatsResults.statdata.st_size; @@ -78,27 +97,72 @@ Balau::Output::Output(const char * fname, bool truncate) throw (GeneralException } } +namespace { + +class AsyncOpClose : public Balau::AsyncOperation { + public: + AsyncOpClose(int fd, cbResults_t * results) : m_fd(fd), m_results(results) { } + virtual void run() { + int r = m_results->result = close(m_fd); + m_results->errorno = r < 0 ? errno : 0; + } + virtual void done() { + m_results->evt.doSignal(); + delete this; + } + private: + int m_fd; + cbResults_t * m_results; +}; + +}; + void Balau::Output::close() throw (GeneralException) { if (m_fd < 0) return; cbResults_t cbResults; - eio_req * r = eio_close(m_fd, 0, eioDone, &cbResults); - EAssert(r != NULL, "eio_close returned a NULL eio_req"); - m_fd = -1; + createAsyncOp(new AsyncOpClose(m_fd, &cbResults)); Task::operationYield(&cbResults.evt); + m_fd = -1; if (cbResults.result < 0) { char str[4096]; strerror_r(cbResults.errorno, str, sizeof(str)); throw GeneralException(String("Unable to close file ") + m_name + ": " + str); - } else { - m_fd = cbResults.result; } } +namespace { + +struct cbWriteResults_t { + Balau::Events::Custom evt; + ssize_t result; + int errorno; +}; + +class AsyncOpWrite : public Balau::AsyncOperation { + public: + AsyncOpWrite(int fd, const void * buf, size_t count, off_t offset, cbWriteResults_t * results) : m_fd(fd), m_buf(buf), m_count(count), m_offset(offset), m_results(results) { } + virtual void run() { + int r = m_results->result = pwrite(m_fd, m_buf, m_count, m_offset); + m_results->errorno = r < 0 ? errno : 0; + } + virtual void done() { + m_results->evt.doSignal(); + delete this; + } + private: + int m_fd; + const void * m_buf; + size_t m_count; + off_t m_offset; + cbWriteResults_t * m_results; +}; + +}; + ssize_t Balau::Output::write(const void * buf, size_t count) throw (GeneralException) { - cbResults_t cbResults; - eio_req * r = eio_write(m_fd, const_cast<void *>(buf), count, getWOffset(), 0, eioDone, &cbResults); - EAssert(r != NULL, "eio_write returned a NULL eio_req"); + cbWriteResults_t cbResults; + createAsyncOp(new AsyncOpWrite(m_fd, buf, count, getWOffset(), &cbResults)); Task::operationYield(&cbResults.evt); if (cbResults.result > 0) { wseek(cbResults.result, SEEK_CUR); |