summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--Makefile11
m---------libeio0
-rw-r--r--src/Handle.cc82
-rw-r--r--src/Input.cc123
-rw-r--r--src/Output.cc124
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
diff --git a/Makefile b/Makefile
index 6516423..e3f8898 100644
--- a/Makefile
+++ b/Makefile
@@ -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);