diff --git a/machinarium/machinarium.h b/machinarium/machinarium.h index d113b8e5..5b53a945 100644 --- a/machinarium/machinarium.h +++ b/machinarium/machinarium.h @@ -20,6 +20,7 @@ typedef void (*mmfunction_t)(void *arg); typedef void* mm_t; +typedef void* mmio_t; MM_API mm_t mm_new(void); @@ -34,4 +35,10 @@ MM_API void mm_sleep(mm_t, uint64_t time_ms); MM_API int mm_wait(mm_t, uint64_t id); MM_API int mm_cancel(mm_t, uint64_t id); +MM_API mmio_t +mm_io_new(mm_t); + +MM_API void mm_close(mmio_t); +MM_API int mm_fd(mmio_t); + #endif diff --git a/machinarium/machinarium_private.h b/machinarium/machinarium_private.h index 0e27035f..f0ef7537 100644 --- a/machinarium/machinarium_private.h +++ b/machinarium/machinarium_private.h @@ -29,5 +29,6 @@ #include "mm_fiber.h" #include "mm_scheduler.h" #include "mm.h" +#include "mm_io.h" #endif diff --git a/machinarium/makefile b/machinarium/makefile index 405eb98c..3014a98d 100644 --- a/machinarium/makefile +++ b/machinarium/makefile @@ -7,7 +7,8 @@ CFLAGS = -I. -Wall -g -O0 -pedantic OBJECTS = mm_context.o \ mm_fiber.o \ mm_scheduler.o \ - mm.o + mm.o \ + mm_io.o LIB = libmachinarium.a $(LIB): clean $(OBJECTS) $(AR) cr $(LIB) $(OBJECTS) diff --git a/machinarium/mm_io.c b/machinarium/mm_io.c new file mode 100644 index 00000000..b4251536 --- /dev/null +++ b/machinarium/mm_io.c @@ -0,0 +1,81 @@ + +/* + * machinarium. + * + * Cooperative multitasking engine. +*/ + +#include +#include + +MM_API mmio_t +mm_io_new(mm_t envp) +{ + mm *env = envp; + mmio *io = malloc(sizeof(*io)); + if (io == NULL) + return NULL; + /* tcp */ + io->fd = -1; + io->f = env; + uv_tcp_init(&env->loop, &io->handle); + io->handle.data = io; + /* connect */ + memset(&io->connect, 0, sizeof(io->connect)); + uv_timer_init(&env->loop, &io->connect_timer); + io->connect.data = io; + io->connect_timer.data = io; + io->connect_timeout = 0; + io->connect_status = 0; + io->connected = 0; + io->connect_fiber = NULL; + /* accept */ + io->accept_status = 0; + io->accept_fiber = NULL; + /* read */ + mm_bufinit(&io->read_buf); + uv_timer_init(&env->loop, &io->read_timer); + io->read_timer.data = io; + io->read_size = 0; + io->read_status = 0; + io->read_timeout = 0; + io->read_eof = 0; + io->read_fiber = NULL; + /* write */ + memset(&io->write, 0, sizeof(io->write)); + uv_timer_init(&env->loop, &io->write_timer); + io->write.data = io; + io->write_timer.data = io; + io->write_timeout = 0; + io->write_fiber = NULL; + io->write_status = 0; + return io; +} + +MM_API void +mm_close(mmio_t iop) +{ + mmio *io = iop; + + if (! uv_is_closing((uv_handle_t*)&io->connect_timer)) + uv_close((uv_handle_t*)&io->connect_timer, NULL); + + if (! uv_is_closing((uv_handle_t*)&io->read_timer)) + uv_close((uv_handle_t*)&io->read_timer, NULL); + + if (! uv_is_closing((uv_handle_t*)&io->write_timer)) + uv_close((uv_handle_t*)&io->write_timer, NULL); + + if (! uv_is_closing((uv_handle_t*)&io->handle)) + uv_close((uv_handle_t*)&io->handle, NULL); + + mm_buffree(&io->read_buf); + free(io); +} + +MM_API int +mm_fd(mmio_t iop) +{ + mmio *io = iop; + return io->fd; +} diff --git a/machinarium/mm_io.h b/machinarium/mm_io.h new file mode 100644 index 00000000..196a47bf --- /dev/null +++ b/machinarium/mm_io.h @@ -0,0 +1,58 @@ +#ifndef MM_IO_H_ +#define MM_IO_H_ + +/* + * machinarium. + * + * Cooperative multitasking engine. +*/ + +typedef struct mmio mmio; + +struct mmio { + uv_os_sock_t fd; + uv_tcp_t handle; + mm *f; + /* connect */ + uv_timer_t connect_timer; + uv_connect_t connect; + int connect_timeout; + int connected; + int connect_status; + mmfiber *connect_fiber; + /* accept */ + int accept_status; + mmfiber *accept_fiber; + /* read */ + uv_timer_t read_timer; + mmbuf read_buf; + int read_size; + int read_timeout; + int read_eof; + int read_status; + mmfiber *read_fiber; + /* write */ + uv_timer_t write_timer; + uv_write_t write; + int write_timeout; + int write_status; + mmfiber *write_fiber; +}; + +static inline void +mm_io_timer_start(uv_timer_t *timer, uv_timer_cb callback, uint64_t time_ms) +{ + if (time_ms > 0) + uv_timer_start(timer, callback, time_ms, 0); +} + +static inline void +mm_io_timer_stop(uv_timer_t *timer) +{ + uv_timer_stop(timer); + uv_handle_t *handle = (uv_handle_t*)timer; + if (! uv_is_closing(handle)) + uv_close(handle, NULL); +} + +#endif