diff options
author | Yaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx> | 2017-11-29 11:44:34 +0300 |
---|---|---|
committer | Yaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx> | 2017-11-29 11:44:34 +0300 |
commit | 67fdec20726e48ba3a934cb25bb30d47ec4a4f29 (patch) | |
tree | 37fd9f4f0b0c20103e1646fc83021e4765de3680 /node_modules/uws/src/Asio.h | |
download | spanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.tar.gz spanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.zip |
Initial commit, version 0.5.3
Diffstat (limited to 'node_modules/uws/src/Asio.h')
-rw-r--r-- | node_modules/uws/src/Asio.h | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/node_modules/uws/src/Asio.h b/node_modules/uws/src/Asio.h new file mode 100644 index 0000000..2792c29 --- /dev/null +++ b/node_modules/uws/src/Asio.h @@ -0,0 +1,184 @@ +#ifndef ASIO_H +#define ASIO_H + +#include <boost/asio.hpp> + +typedef boost::asio::ip::tcp::socket::native_type uv_os_sock_t; +static const int UV_READABLE = 1; +static const int UV_WRITABLE = 2; + +struct Loop : boost::asio::io_service { + + static Loop *createLoop(bool defaultLoop = true) { + return new Loop; + } + + void destroy() { + delete this; + } + + void run() { + boost::asio::io_service::run(); + } +}; + +struct Timer { + boost::asio::deadline_timer asio_timer; + void *data; + + Timer(Loop *loop) : asio_timer(*loop) { + + } + + void start(void (*cb)(Timer *), int first, int repeat) { + asio_timer.expires_from_now(boost::posix_time::milliseconds(first)); + asio_timer.async_wait([this, cb, repeat](const boost::system::error_code &ec) { + if (ec != boost::asio::error::operation_aborted) { + if (repeat) { + start(cb, repeat, repeat); + } + cb(this); + } + }); + } + + void setData(void *data) { + this->data = data; + } + + void *getData() { + return data; + } + + // bug: cancel does not cancel expired timers! + // it has to guarantee that the timer is not called after + // stop is called! ffs boost! + void stop() { + asio_timer.cancel(); + } + + void close() { + asio_timer.get_io_service().post([this]() { + delete this; + }); + } +}; + +struct Async { + Loop *loop; + void (*cb)(Async *); + void *data; + + boost::asio::io_service::work asio_work; + + Async(Loop *loop) : loop(loop), asio_work(*loop) { + } + + void start(void (*cb)(Async *)) { + this->cb = cb; + } + + void send() { + loop->post([this]() { + cb(this); + }); + } + + void close() { + loop->post([this]() { + delete this; + }); + } + + void setData(void *data) { + this->data = data; + } + + void *getData() { + return data; + } +}; + +struct Poll { + boost::asio::posix::stream_descriptor *socket; + void (*cb)(Poll *p, int status, int events); + + Poll(Loop *loop, uv_os_sock_t fd) { + socket = new boost::asio::posix::stream_descriptor(*loop, fd); + socket->non_blocking(true); + } + + bool isClosed() { + return !socket; + } + + boost::asio::ip::tcp::socket::native_type getFd() { + return socket ? socket->native_handle() : -1; + } + + void setCb(void (*cb)(Poll *p, int status, int events)) { + this->cb = cb; + } + + void (*getCb())(Poll *, int, int) { + return cb; + } + + void reInit(Loop *loop, uv_os_sock_t fd) { + delete socket; + socket = new boost::asio::posix::stream_descriptor(*loop, fd); + socket->non_blocking(true); + } + + void start(Loop *, Poll *self, int events) { + if (events & UV_READABLE) { + socket->async_read_some(boost::asio::null_buffers(), [self](boost::system::error_code ec, std::size_t) { + if (ec != boost::asio::error::operation_aborted) { + self->start(nullptr, self, UV_READABLE); + self->cb(self, ec ? -1 : 0, UV_READABLE); + } + }); + } + + if (events & UV_WRITABLE) { + socket->async_write_some(boost::asio::null_buffers(), [self](boost::system::error_code ec, std::size_t) { + if (ec != boost::asio::error::operation_aborted) { + self->start(nullptr, self, UV_WRITABLE); + self->cb(self, ec ? -1 : 0, UV_WRITABLE); + } + }); + } + } + + void change(Loop *, Poll *self, int events) { + socket->cancel(); + start(nullptr, self, events); + } + + bool fastTransfer(Loop *loop, Loop *newLoop, int events) { + return false; + } + + // todo: asio is thread safe, use it! + bool threadSafeChange(Loop *loop, Poll *self, int events) { + return false; + } + + void stop(Loop *) { + socket->cancel(); + } + + // this is not correct, but it works for now + // think about transfer - should allow one to not delete + // but in this case it doesn't matter at all + void close(Loop *loop, void (*cb)(Poll *)) { + socket->release(); + socket->get_io_service().post([cb, this]() { + cb(this); + }); + delete socket; + socket = nullptr; + } +}; + +#endif // ASIO_H |