From 70697f4ae92d581152df12f93cc733dcddb003d5 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 10 Mar 2023 10:52:03 +0100 Subject: [PATCH] uvw v3 (#263) --- .conan/test_package/test_package.cpp | 22 +- .github/workflows/sanitizer.yml | 30 + CMakeLists.txt | 7 +- README.md | 129 ++--- TODO | 5 + src/uvw.hpp | 3 +- src/uvw/async.cpp | 14 +- src/uvw/async.h | 30 +- src/uvw/check.cpp | 18 +- src/uvw/check.h | 35 +- src/uvw/dns.cpp | 99 ++-- src/uvw/dns.h | 119 ++-- src/uvw/emitter.cpp | 10 +- src/uvw/emitter.h | 234 ++------ src/uvw/enum.hpp | 76 +++ src/uvw/fs.cpp | 519 +++++++++-------- src/uvw/fs.h | 816 ++++++++++----------------- src/uvw/fs_event.cpp | 32 +- src/uvw/fs_event.h | 79 +-- src/uvw/fs_poll.cpp | 29 +- src/uvw/fs_poll.h | 45 +- src/uvw/handle.hpp | 155 +++-- src/uvw/idle.cpp | 18 +- src/uvw/idle.h | 38 +- src/uvw/lib.cpp | 17 +- src/uvw/lib.h | 13 +- src/uvw/loop.cpp | 152 +++-- src/uvw/loop.h | 244 ++++---- src/uvw/pipe.cpp | 53 +- src/uvw/pipe.h | 59 +- src/uvw/poll.cpp | 41 +- src/uvw/poll.h | 89 ++- src/uvw/prepare.cpp | 18 +- src/uvw/prepare.h | 37 +- src/uvw/process.cpp | 83 ++- src/uvw/process.h | 130 +++-- src/uvw/request.hpp | 43 +- src/uvw/resource.hpp | 45 +- src/uvw/signal.cpp | 28 +- src/uvw/signal.h | 42 +- src/uvw/stream.cpp | 25 +- src/uvw/stream.h | 356 ++++++------ src/uvw/tcp.cpp | 108 ++-- src/uvw/tcp.h | 160 +++--- src/uvw/thread.cpp | 164 +++--- src/uvw/thread.h | 152 ++--- src/uvw/timer.cpp | 34 +- src/uvw/timer.h | 52 +- src/uvw/tty.cpp | 41 +- src/uvw/tty.h | 63 ++- src/uvw/type_info.hpp | 3 +- src/uvw/udp.cpp | 307 ++++------ src/uvw/udp.h | 462 ++++++--------- src/uvw/underlying_type.hpp | 118 ---- src/uvw/util.cpp | 269 +++++---- src/uvw/util.h | 369 ++++-------- src/uvw/uv_type.hpp | 89 +++ src/uvw/work.cpp | 20 +- src/uvw/work.h | 31 +- test/CMakeLists.txt | 3 +- test/main.cpp | 42 +- test/uvw/async.cpp | 19 +- test/uvw/check.cpp | 27 +- test/uvw/dns.cpp | 72 +-- test/uvw/emitter.cpp | 143 +---- test/uvw/file_req.cpp | 407 ++++++------- test/uvw/file_req_sendfile.cpp | 53 +- test/uvw/fs_event.cpp | 39 +- test/uvw/fs_poll.cpp | 41 -- test/uvw/fs_req.cpp | 729 ++++++++++++------------ test/uvw/handle.cpp | 29 +- test/uvw/idle.cpp | 25 +- test/uvw/lib.cpp | 12 +- test/uvw/loop.cpp | 91 ++- test/uvw/pipe.cpp | 109 ++-- test/uvw/prepare.cpp | 25 +- test/uvw/process.cpp | 24 +- test/uvw/request.cpp | 6 +- test/uvw/resource.cpp | 16 +- test/uvw/signal.cpp | 24 +- test/uvw/stream.cpp | 8 +- test/uvw/tcp.cpp | 146 +++-- test/uvw/thread.cpp | 28 +- test/uvw/timer.cpp | 88 +-- test/uvw/tty.cpp | 22 +- test/uvw/udp.cpp | 84 +-- test/uvw/underlying_type.cpp | 22 - test/uvw/util.cpp | 158 ++---- test/uvw/uv_type.cpp | 22 + test/uvw/work.cpp | 28 +- 90 files changed, 4083 insertions(+), 4938 deletions(-) create mode 100644 .github/workflows/sanitizer.yml create mode 100644 TODO create mode 100644 src/uvw/enum.hpp delete mode 100644 src/uvw/underlying_type.hpp create mode 100644 src/uvw/uv_type.hpp delete mode 100644 test/uvw/fs_poll.cpp delete mode 100644 test/uvw/underlying_type.cpp create mode 100644 test/uvw/uv_type.cpp diff --git a/.conan/test_package/test_package.cpp b/.conan/test_package/test_package.cpp index 2ae52b31..f6abd5d9 100644 --- a/.conan/test_package/test_package.cpp +++ b/.conan/test_package/test_package.cpp @@ -3,14 +3,14 @@ #include #include -void listen(uvw::Loop &loop) { - std::shared_ptr tcp = loop.resource(); +void listen(uvw::loop &loop) { + std::shared_ptr tcp = loop.resource(); - tcp->once([](const uvw::ListenEvent &, uvw::TCPHandle &srv) { - std::shared_ptr client = srv.loop().resource(); + tcp->on([](const uvw::listen_event &, uvw::tcp_handle &srv) { + std::shared_ptr client = srv.loop().resource(); - client->on([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::TCPHandle &) { ptr->close(); }); - client->on([](const uvw::EndEvent &, uvw::TCPHandle &client) { client.close(); }); + client->on([ptr = srv.shared_from_this()](const uvw::close_event &, uvw::tcp_handle &) { ptr->close(); }); + client->on([](const uvw::end_event &, uvw::tcp_handle &client) { client.close(); }); srv.accept(*client); client->read(); @@ -20,12 +20,12 @@ void listen(uvw::Loop &loop) { tcp->listen(); } -void conn(uvw::Loop &loop) { - auto tcp = loop.resource(); +void conn(uvw::loop &loop) { + auto tcp = loop.resource(); - tcp->on([](const uvw::ErrorEvent &, uvw::TCPHandle &) { /* handle errors */ }); + tcp->on([](const uvw::error_event &, uvw::tcp_handle &) { /* handle errors */ }); - tcp->once([](const uvw::ConnectEvent &, uvw::TCPHandle &tcp) { + tcp->on([](const uvw::connect_event &, uvw::tcp_handle &tcp) { auto dataWrite = std::unique_ptr(new char[2]{ 'b', 'c' }); tcp.write(std::move(dataWrite), 2); tcp.close(); @@ -36,7 +36,7 @@ void conn(uvw::Loop &loop) { int main() { std::cout << "Getting UVW loop ...\n"; - auto loop = uvw::Loop::getDefault(); + auto loop = uvw::loop::get_default(); std::cout << "Staring UVW listener ...\n"; listen(*loop); std::cout << "Connecting ...\n"; diff --git a/.github/workflows/sanitizer.yml b/.github/workflows/sanitizer.yml new file mode 100644 index 00000000..6ebce448 --- /dev/null +++ b/.github/workflows/sanitizer.yml @@ -0,0 +1,30 @@ +name: sanitizer + +on: [push, pull_request] + +jobs: + + clang: + timeout-minutes: 15 + + strategy: + matrix: + compiler: [clang++] + sanitizer: [ASAN, UBSAN] + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Compile tests + working-directory: build + env: + CXX: ${{ matrix.compiler }} + run: | + cmake ${{ matrix.mode }} -DBUILD_TESTING=ON -Dlibuv_buildtests=OFF -DUSE_${{ matrix.sanitizer }}=ON .. + make -j2 + - name: Run tests + working-directory: build + env: + CTEST_OUTPUT_ON_FAILURE: 1 + run: ctest --timeout 5 -C Debug -j2 diff --git a/CMakeLists.txt b/CMakeLists.txt index f50dba08..66a20828 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,9 +15,9 @@ endif() # # Project configuration # -set(UVW_VERSION_MAJOR 2) -set(UVW_VERSION_MINOR 12) -set(UVW_VERSION_PATCH 1) +set(UVW_VERSION_MAJOR 3) +set(UVW_VERSION_MINOR 0) +set(UVW_VERSION_PATCH 0) project( uvw @@ -263,4 +263,5 @@ add_custom_target( AUTHORS LICENSE README.md + TODO ) diff --git a/README.md b/README.md index 78daac49..9b5883c7 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,8 @@ and still support me today. [`libuv`](https://github.com/libuv/libuv) written in modern C++.
Now it's finally available also as a compilable static library. -The basic idea is to hide completely the *C-ish* interface of `libuv` behind a -graceful C++ API. Currently, no `uv_*_t` data structure is actually exposed by -the library.
+The basic idea is to wrap the *C-ish* interface of `libuv` behind a graceful C++ +API.
Note that `uvw` stays true to the API of `libuv` and it doesn't add anything to its interface. For the same reasons, users of the library must follow the same rules which are used with `libuv`.
@@ -43,14 +42,14 @@ closed once it is no longer in use. #include #include -void listen(uvw::Loop &loop) { - std::shared_ptr tcp = loop.resource(); +void listen(uvw::loop &loop) { + std::shared_ptr tcp = loop.resource(); - tcp->once([](const uvw::ListenEvent &, uvw::TCPHandle &srv) { - std::shared_ptr client = srv.loop().resource(); + tcp->once([](const uvw::listen_event &, uvw::tcp_handle &srv) { + std::shared_ptr client = srv.parent().resource(); - client->on([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::TCPHandle &) { ptr->close(); }); - client->on([](const uvw::EndEvent &, uvw::TCPHandle &client) { client.close(); }); + client->on([ptr = srv.shared_from_this()](const uvw::close_event &, uvw::tcp_handle &) { ptr->close(); }); + client->on([](const uvw::end_event &, uvw::tcp_handle &client) { client.close(); }); srv.accept(*client); client->read(); @@ -60,12 +59,12 @@ void listen(uvw::Loop &loop) { tcp->listen(); } -void conn(uvw::Loop &loop) { - auto tcp = loop.resource(); +void conn(uvw::loop &loop) { + auto tcp = loop.resource(); - tcp->on([](const uvw::ErrorEvent &, uvw::TCPHandle &) { /* handle errors */ }); + tcp->on([](const uvw::error_event &, uvw::tcp_handle &) { /* handle errors */ }); - tcp->once([](const uvw::ConnectEvent &, uvw::TCPHandle &tcp) { + tcp->once([](const uvw::connect_event &, uvw::tcp_handle &tcp) { auto dataWrite = std::unique_ptr(new char[2]{ 'b', 'c' }); tcp.write(std::move(dataWrite), 2); tcp.close(); @@ -75,7 +74,7 @@ void conn(uvw::Loop &loop) { } int main() { - auto loop = uvw::Loop::getDefault(); + auto loop = uvw::loop::get_default(); listen(*loop); conn(*loop); loop->run(); @@ -229,7 +228,7 @@ For more details, please refer to the ## Handles Initialization is usually performed under the hood and can be even passed over, -as far as handles are created using the `Loop::resource` member function.
+as far as handles are created using the `loop::resource` member function.
On the other side, handles keep themselves alive until one explicitly closes them. Because of that, memory usage will grow if users simply forget about a handle.
@@ -239,7 +238,7 @@ as calling the `close` member function on them. ## Requests Usually initializing a request object is not required. Anyway, the recommended -way to create a request is still through the `Loop::resource` member +way to create a request is still through the `loop::resource` member function.
Requests will keep themselves alive as long as they are bound to unfinished underlying activities. This means that users don't have to discard a @@ -253,7 +252,7 @@ The first thing to do to use `uvw` is to create a loop. In case the default one is enough, it's easy as doing this: ```cpp -auto loop = uvw::Loop::getDefault(); +auto loop = uvw::loop::get_default(); ``` Note that loop objects don't require being closed explicitly, even if they offer @@ -263,7 +262,7 @@ equivalent: ```cpp loop->run(); -loop->run(); +loop->run(uvw::loop::run_mode::DEFAULT); ``` Available modes are: `DEFAULT`, `ONCE`, `NOWAIT`. Please refer to the @@ -273,23 +272,21 @@ In order to create a resource and to bind it to the given loop, just do the following: ```cpp -auto tcp = loop->resource(); +auto tcp = loop->resource(); ``` -The line above will create and initialize a tcp handle, then a shared pointer to -that resource will be returned.
+The line above creates and initializes a tcp handle, then a shared pointer to +that resource is returned.
Users should check if pointers have been correctly initialized: in case of errors, they won't be.
-Another way to create a resource is: +It also is possible to create uninitialized resources to init later on as: ```cpp -auto tcp = TCPHandle::create(loop); +auto tcp = loop->uninitialized_resource(); tcp->init(); ``` -Pretty annoying indeed. Using a loop is the recommended approach. - -The resources also accept arbitrary user-data that won't be touched in any +All resources also accept arbitrary user-data that won't be touched in any case.
Users can set and get them through the `data` member function as it follows: @@ -311,12 +308,12 @@ Remember from the previous section that a handle will keep itself alive until one invokes the `close` member function on it.
To know what are the handles that are still alive and bound to a given loop, there exists the `walk` member function. It returns handles with their types. -Therefore, the use of `Overloaded` is recommended to be able to intercept all +Therefore, the use of `overloaded` is recommended to be able to intercept all types of interest: ```cpp -handle.loop().walk(uvw::Overloaded{ - [](uvw::TimerHandle &h){ /* application code for timers here */ }, +handle.parent().walk(uvw::overloaded{ + [](uvw::timer_handle &h){ /* application code for timers here */ }, [](auto &&){ /* ignore all other types */ } }); ``` @@ -332,58 +329,52 @@ No need to keep track of them. ## The event-based approach -`uvw` offers an event-based approach, so resources are small event emitters -to which listeners can be attached.
-Attaching a listener to a resource is the recommended way to be notified about -changes.
-Listeners must be callable objects of type `void(EventType &, ResourceType &)`, +`uvw` offers an event-based approach where resources are small event emitters to +which listeners are attached.
+Attaching listeners to resources is the recommended way to receive notifications +about their operations.
+Listeners are callable objects of type `void(event_type &, resource_type &)`, where: -* `EventType` is the type of the event for which they have been designed. -* `ResourceType` is the type of the resource that has originated the event. +* `event_type` is the type of the event for which they have been designed. +* `resource_type` is the type of the resource that has originated the event. It means that the following function types are all valid: -* `void(EventType &, ResourceType &)` -* `void(const EventType &, ResourceType &)` -* `void(EventType &, const ResourceType &)` -* `void(const EventType &, const ResourceType &)` +* `void(event_type &, resource_type &)` +* `void(const event_type &, resource_type &)` +* `void(event_type &, const resource_type &)` +* `void(const event_type &, const resource_type &)` -Please note that there is no need to keep around references to the resources: -they will pass themselves as an argument whenever an event is published. +Please note that there is no need to keep around references to the resources, +since they pass themselves as an argument whenever an event is published.
+The `on` member function is the way to go to register long-running listeners: -There exist two methods to attach a listener to a resource: +```cpp +resource.on(listener) +``` -* `resource.once(listener)`: the listener will be automatically - removed after the first event of the given type. -* `resource.on(listener)`: to be used for long-running listeners. +To know if a listener exists for a given type, the class offers a `has` function +template. Similarly, the `reset` function template is be used to reset and thus +disconnect listeners, if any. A non-template version of `reset` also exists to +clear an emitter as a whole. -Both of them return an object of type `ResourceType::Connection` (as an example, -`TCPHandle::Connection`).
-A connection object can be used later as an argument to the `erase` member -function of the resource to remove the listener.
-There exists also the `clear` member function to drop all the listeners at once. -Note that `clear` should only be invoked on non-active handles. The handles -exploit the same event mechanism made available to users to satisfy pending -requests. Invoking `clear` on an active handle, for example with requests still -in progress, risks leading to memory leaks or unexpected behavior. - -Almost all the resources emit `ErrorEvent` in case of errors.
+Almost all the resources emit `error_event` in case of errors.
All the other events are specific for the given resource and documented in the API reference. The code below shows how to create a simple tcp server using `uvw`: ```cpp -auto loop = uvw::Loop::getDefault(); -auto tcp = loop->resource(); +auto loop = uvw::loop::get_default(); +auto tcp = loop->resource(); -tcp->on([](const uvw::ErrorEvent &, uvw::TCPHandle &) { /* something went wrong */ }); +tcp->on([](const uvw::error_event &, uvw::tcp_handle &) { /* something went wrong */ }); -tcp->on([](const uvw::ListenEvent &, uvw::TCPHandle &srv) { - std::shared_ptr client = srv.loop().resource(); - client->once([](const uvw::EndEvent &, uvw::TCPHandle &client) { client.close(); }); - client->on([](const uvw::DataEvent &, uvw::TCPHandle &) { /* data received */ }); +tcp->on([](const uvw::listen_event &, uvw::tcp_handle &srv) { + std::shared_ptr client = srv.parent().resource(); + client->on([](const uvw::end_event &, uvw::tcp_handle &client) { client.close(); }); + client->on([](const uvw::data_event &, uvw::tcp_handle &) { /* data received */ }); srv.accept(*client); client->read(); }); @@ -392,11 +383,7 @@ tcp->bind("127.0.0.1", 4242); tcp->listen(); ``` -Note also that `uvw::TCPHandle` already supports _IPv6_ out-of-the-box. The -statement above is equivalent to `tcp->bind("127.0.0.1", 4242)`.
-It's sufficient to explicitly specify `uvw::IPv6` as the underlying protocol to -use it. - +Note also that `uvw::tcp_handle` already supports _IPv6_ out-of-the-box.
The API reference is the recommended documentation for further details about resources and their methods. @@ -414,8 +401,8 @@ things. That being said, _going raw_ is a matter of using the `raw` member functions: ```cpp -auto loop = uvw::Loop::getDefault(); -auto tcp = loop->resource(); +auto loop = uvw::loop::get_default(); +auto tcp = loop->resource(); uv_loop_t *raw = loop->raw(); uv_tcp_t *handle = tcp->raw(); diff --git a/TODO b/TODO new file mode 100644 index 00000000..99fa6b18 --- /dev/null +++ b/TODO @@ -0,0 +1,5 @@ +* do not send error events when the return value is enough (still wip) +* also cleanup error event mentions in the doc +* Make all tests pass on all platforms +* add iwyu and clean up everything +* Allocator support diff --git a/src/uvw.hpp b/src/uvw.hpp index aaf8f4c7..2aea4c97 100644 --- a/src/uvw.hpp +++ b/src/uvw.hpp @@ -3,6 +3,7 @@ #include "uvw/config.h" #include "uvw/dns.h" #include "uvw/emitter.h" +#include "uvw/enum.hpp" #include "uvw/fs.h" #include "uvw/fs_event.h" #include "uvw/fs_poll.h" @@ -22,6 +23,6 @@ #include "uvw/timer.h" #include "uvw/tty.h" #include "uvw/udp.h" -#include "uvw/underlying_type.hpp" #include "uvw/util.h" +#include "uvw/uv_type.hpp" #include "uvw/work.h" diff --git a/src/uvw/async.cpp b/src/uvw/async.cpp index bbc9a54f..fabbe453 100644 --- a/src/uvw/async.cpp +++ b/src/uvw/async.cpp @@ -6,17 +6,17 @@ namespace uvw { -UVW_INLINE void AsyncHandle::sendCallback(uv_async_t *handle) { - AsyncHandle &async = *(static_cast(handle->data)); - async.publish(AsyncEvent{}); +UVW_INLINE void async_handle::send_callback(uv_async_t *hndl) { + async_handle &async = *(static_cast(hndl->data)); + async.publish(async_event{}); } -UVW_INLINE bool AsyncHandle::init() { - return initialize(&uv_async_init, &sendCallback); +UVW_INLINE int async_handle::init() { + return leak_if(uv_async_init(parent().raw(), raw(), &send_callback)); } -UVW_INLINE void AsyncHandle::send() { - invoke(&uv_async_send, get()); +UVW_INLINE int async_handle::send() { + return uv_async_send(raw()); } } // namespace uvw diff --git a/src/uvw/async.h b/src/uvw/async.h index 35afb28a..7d864ba4 100644 --- a/src/uvw/async.h +++ b/src/uvw/async.h @@ -7,26 +7,22 @@ namespace uvw { -/** - * @brief AsyncEvent event. - * - * It will be emitted by AsyncHandle according with its functionalities. - */ -struct AsyncEvent {}; +/*! @brief Async event. */ +struct async_event {}; /** - * @brief The AsyncHandle handle. + * @brief The async handle. * * Async handles allow the user to _wakeup_ the event loop and get an event * emitted from another thread. * - * To create an `AsyncHandle` through a `Loop`, no arguments are required. + * To create an `async_handle` through a `loop`, no arguments are required. */ -class AsyncHandle final: public Handle { - static void sendCallback(uv_async_t *handle); +class async_handle final: public handle { + static void send_callback(uv_async_t *hndl); public: - using Handle::Handle; + using handle::handle; /** * @brief Initializes the handle. @@ -34,21 +30,23 @@ public: * Unlike other handle initialization functions, it immediately starts the * handle. * - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** - * @brief Wakeups the event loop and emits the AsyncEvent event. + * @brief Wakeups the event loop and emits the async event. * * It’s safe to call this function from any thread.
- * An AsyncEvent event will be emitted on the loop thread. + * An async event is emitted on the loop thread. * * See the official * [documentation](http://docs.libuv.org/en/v1.x/async.html#c.uv_async_send) * for further details. + * + * @return Underlying return value. */ - void send(); + int send(); }; } // namespace uvw diff --git a/src/uvw/check.cpp b/src/uvw/check.cpp index a06b67ca..3608c0d2 100644 --- a/src/uvw/check.cpp +++ b/src/uvw/check.cpp @@ -6,21 +6,21 @@ namespace uvw { -UVW_INLINE void CheckHandle::startCallback(uv_check_t *handle) { - CheckHandle &check = *(static_cast(handle->data)); - check.publish(CheckEvent{}); +UVW_INLINE void check_handle::start_callback(uv_check_t *hndl) { + check_handle &check = *(static_cast(hndl->data)); + check.publish(check_event{}); } -UVW_INLINE bool CheckHandle::init() { - return initialize(&uv_check_init); +UVW_INLINE int check_handle::init() { + return leak_if(uv_check_init(parent().raw(), raw())); } -UVW_INLINE void CheckHandle::start() { - invoke(&uv_check_start, get(), &startCallback); +UVW_INLINE int check_handle::start() { + return uv_check_start(raw(), &start_callback); } -UVW_INLINE void CheckHandle::stop() { - invoke(&uv_check_stop, get()); +UVW_INLINE int check_handle::stop() { + return uv_check_stop(raw()); } } // namespace uvw diff --git a/src/uvw/check.h b/src/uvw/check.h index 2f5f9472..09b0401c 100644 --- a/src/uvw/check.h +++ b/src/uvw/check.h @@ -7,45 +7,44 @@ namespace uvw { -/** - * @brief CheckEvent event. - * - * It will be emitted by CheckHandle according with its functionalities. - */ -struct CheckEvent {}; +/*! @brief Check event. */ +struct check_event {}; /** - * @brief The CheckHandle handle. + * @brief The check handle. * - * Check handles will emit a CheckEvent event once per loop iteration, right - * after polling for I/O. + * Check handles will emit a check event once per loop iteration, right after + * polling for I/O. * - * To create a `CheckHandle` through a `Loop`, no arguments are required. + * To create a `check_handle` through a `loop`, no arguments are required. */ -class CheckHandle final: public Handle { - static void startCallback(uv_check_t *handle); +class check_handle final: public handle { + static void start_callback(uv_check_t *hndl); public: - using Handle::Handle; + using handle::handle; /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Starts the handle. * - * A CheckEvent event will be emitted once per loop iteration, right after + * A check event will be emitted once per loop iteration, right after * polling for I/O. + * + * @return Underlying return value. */ - void start(); + int start(); /** * @brief Stops the handle. + * @return Underlying return value. */ - void stop(); + int stop(); }; } // namespace uvw diff --git a/src/uvw/dns.cpp b/src/uvw/dns.cpp index cda70a01..4c706292 100644 --- a/src/uvw/dns.cpp +++ b/src/uvw/dns.cpp @@ -6,111 +6,88 @@ namespace uvw { -UVW_INLINE AddrInfoEvent::AddrInfoEvent(std::unique_ptr addr) +UVW_INLINE addr_info_event::addr_info_event(std::unique_ptr addr) : data{std::move(addr)} {} -UVW_INLINE NameInfoEvent::NameInfoEvent(const char *host, const char *serv) +UVW_INLINE name_info_event::name_info_event(const char *host, const char *serv) : hostname{host}, service{serv} {} -UVW_INLINE void GetAddrInfoReq::addrInfoCallback(uv_getaddrinfo_t *req, int status, addrinfo *res) { +UVW_INLINE void get_addr_info_req::addr_info_callback(uv_getaddrinfo_t *req, int status, addrinfo *res) { if(auto ptr = reserve(req); status) { - ptr->publish(ErrorEvent{status}); + ptr->publish(error_event{status}); } else { auto data = std::unique_ptr{res, [](addrinfo *addr) { uv_freeaddrinfo(addr); }}; - ptr->publish(AddrInfoEvent{std::move(data)}); + ptr->publish(addr_info_event{std::move(data)}); } } -UVW_INLINE void GetAddrInfoReq::nodeAddrInfo(const char *node, const char *service, addrinfo *hints) { - invoke(&uv_getaddrinfo, parent(), get(), &addrInfoCallback, node, service, hints); +UVW_INLINE int get_addr_info_req::node_addr_info(const char *node, const char *service, addrinfo *hints) { + return this->leak_if(uv_getaddrinfo(parent().raw(), raw(), &addr_info_callback, node, service, hints)); } -UVW_INLINE auto GetAddrInfoReq::nodeAddrInfoSync(const char *node, const char *service, addrinfo *hints) { - auto req = get(); - auto err = uv_getaddrinfo(parent(), req, nullptr, node, service, hints); +UVW_INLINE auto get_addr_info_req::node_addr_info_sync(const char *node, const char *service, addrinfo *hints) { + auto req = raw(); + auto err = uv_getaddrinfo(parent().raw(), req, nullptr, node, service, hints); auto data = std::unique_ptr{req->addrinfo, [](addrinfo *addr) { uv_freeaddrinfo(addr); }}; return std::make_pair(!err, std::move(data)); } -UVW_INLINE void GetAddrInfoReq::nodeAddrInfo(const std::string &node, addrinfo *hints) { - nodeAddrInfo(node.data(), nullptr, hints); +UVW_INLINE int get_addr_info_req::node_addr_info(const std::string &node, addrinfo *hints) { + return node_addr_info(node.data(), nullptr, hints); } -UVW_INLINE std::pair> GetAddrInfoReq::nodeAddrInfoSync(const std::string &node, addrinfo *hints) { - return nodeAddrInfoSync(node.data(), nullptr, hints); +UVW_INLINE std::pair> get_addr_info_req::node_addr_info_sync(const std::string &node, addrinfo *hints) { + return node_addr_info_sync(node.data(), nullptr, hints); } -UVW_INLINE void GetAddrInfoReq::serviceAddrInfo(const std::string &service, addrinfo *hints) { - nodeAddrInfo(nullptr, service.data(), hints); +UVW_INLINE int get_addr_info_req::service_addr_info(const std::string &service, addrinfo *hints) { + return node_addr_info(nullptr, service.data(), hints); } -UVW_INLINE std::pair> GetAddrInfoReq::serviceAddrInfoSync(const std::string &service, addrinfo *hints) { - return nodeAddrInfoSync(nullptr, service.data(), hints); +UVW_INLINE std::pair> get_addr_info_req::service_addr_info_sync(const std::string &service, addrinfo *hints) { + return node_addr_info_sync(nullptr, service.data(), hints); } -UVW_INLINE void GetAddrInfoReq::addrInfo(const std::string &node, const std::string &service, addrinfo *hints) { - nodeAddrInfo(node.data(), service.data(), hints); +UVW_INLINE int get_addr_info_req::addr_info(const std::string &node, const std::string &service, addrinfo *hints) { + return node_addr_info(node.data(), service.data(), hints); } -UVW_INLINE std::pair> GetAddrInfoReq::addrInfoSync(const std::string &node, const std::string &service, addrinfo *hints) { - return nodeAddrInfoSync(node.data(), service.data(), hints); +UVW_INLINE std::pair> get_addr_info_req::addr_info_sync(const std::string &node, const std::string &service, addrinfo *hints) { + return node_addr_info_sync(node.data(), service.data(), hints); } -UVW_INLINE void GetNameInfoReq::nameInfoCallback(uv_getnameinfo_t *req, int status, const char *hostname, const char *service) { +UVW_INLINE void get_name_info_req::name_info_callback(uv_getnameinfo_t *req, int status, const char *hostname, const char *service) { if(auto ptr = reserve(req); status) { - ptr->publish(ErrorEvent{status}); + ptr->publish(error_event{status}); } else { - ptr->publish(NameInfoEvent{hostname, service}); + ptr->publish(name_info_event{hostname, service}); } } -UVW_INLINE void GetNameInfoReq::nameInfo(const sockaddr &addr, int flags) { - invoke(&uv_getnameinfo, parent(), get(), &nameInfoCallback, &addr, flags); +UVW_INLINE int get_name_info_req::name_info(const sockaddr &addr, int flags) { + return this->leak_if(uv_getnameinfo(parent().raw(), raw(), &name_info_callback, &addr, flags)); } -template -UVW_INLINE void GetNameInfoReq::nameInfo(const std::string &ip, unsigned int port, int flags) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - nameInfo(reinterpret_cast(addr), flags); +UVW_INLINE int get_name_info_req::name_info(const std::string &ip, unsigned int port, int flags) { + return name_info(details::ip_addr(ip.data(), port), flags); } -template -UVW_INLINE void GetNameInfoReq::nameInfo(Addr addr, int flags) { - nameInfo(std::move(addr.ip), addr.port, flags); +UVW_INLINE int get_name_info_req::name_info(socket_address addr, int flags) { + return name_info(std::move(addr.ip), addr.port, flags); } -UVW_INLINE std::pair> GetNameInfoReq::nameInfoSync(const sockaddr &addr, int flags) { - auto req = get(); - auto err = uv_getnameinfo(parent(), req, nullptr, &addr, flags); +UVW_INLINE std::pair> get_name_info_req::name_info_sync(const sockaddr &addr, int flags) { + auto req = raw(); + auto err = uv_getnameinfo(parent().raw(), req, nullptr, &addr, flags); return std::make_pair(!err, std::make_pair(req->host, req->service)); } -template -UVW_INLINE std::pair> GetNameInfoReq::nameInfoSync(const std::string &ip, unsigned int port, int flags) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - return nameInfoSync(reinterpret_cast(addr), flags); +UVW_INLINE std::pair> get_name_info_req::name_info_sync(const std::string &ip, unsigned int port, int flags) { + return name_info_sync(details::ip_addr(ip.data(), port), flags); } -template -UVW_INLINE std::pair> GetNameInfoReq::nameInfoSync(Addr addr, int flags) { - return nameInfoSync(std::move(addr.ip), addr.port, flags); +UVW_INLINE std::pair> get_name_info_req::name_info_sync(socket_address addr, int flags) { + return name_info_sync(addr.ip, addr.port, flags); } -// explicit instantiations -#ifdef UVW_AS_LIB -template void GetNameInfoReq::nameInfo(const std::string &, unsigned int, int); -template void GetNameInfoReq::nameInfo(const std::string &, unsigned int, int); - -template void GetNameInfoReq::nameInfo(Addr, int); -template void GetNameInfoReq::nameInfo(Addr, int); - -template std::pair> GetNameInfoReq::nameInfoSync(const std::string &, unsigned int, int); -template std::pair> GetNameInfoReq::nameInfoSync(const std::string &, unsigned int, int); - -template std::pair> GetNameInfoReq::nameInfoSync(Addr, int); -template std::pair> GetNameInfoReq::nameInfoSync(Addr, int); -#endif // UVW_AS_LIB - } // namespace uvw diff --git a/src/uvw/dns.h b/src/uvw/dns.h index 2dea05cb..8bfb4a9d 100644 --- a/src/uvw/dns.h +++ b/src/uvw/dns.h @@ -11,15 +11,11 @@ namespace uvw { -/** - * @brief AddrInfoEvent event. - * - * It will be emitted by GetAddrInfoReq according with its functionalities. - */ -struct AddrInfoEvent { - using Deleter = void (*)(addrinfo *); +/*! @brief The addrinfo event. */ +struct addr_info_event { + using deleter = void (*)(addrinfo *); - AddrInfoEvent(std::unique_ptr addr); + addr_info_event(std::unique_ptr addr); /** * @brief An initialized instance of `addrinfo`. @@ -27,16 +23,12 @@ struct AddrInfoEvent { * See [getaddrinfo](http://linux.die.net/man/3/getaddrinfo) for further * details. */ - std::unique_ptr data; + std::unique_ptr data; }; -/** - * @brief NameInfoEvent event. - * - * It will be emitted by GetNameInfoReq according with its functionalities. - */ -struct NameInfoEvent { - NameInfoEvent(const char *host, const char *serv); +/*! @brief The nameinfo event. */ +struct name_info_event { + name_info_event(const char *host, const char *serv); /** * @brief A valid hostname. @@ -56,30 +48,31 @@ struct NameInfoEvent { }; /** - * @brief The GetAddrInfoReq request. + * @brief The getaddrinfo request. * * Wrapper for [getaddrinfo](http://linux.die.net/man/3/getaddrinfo).
* It offers either asynchronous and synchronous access methods. * - * To create a `GetAddrInfoReq` through a `Loop`, no arguments are required. + * To create a `get_addr_info_req` through a `loop`, no arguments are required. */ -class GetAddrInfoReq final: public Request { - static void addrInfoCallback(uv_getaddrinfo_t *req, int status, addrinfo *res); - void nodeAddrInfo(const char *node, const char *service, addrinfo *hints = nullptr); - auto nodeAddrInfoSync(const char *node, const char *service, addrinfo *hints = nullptr); +class get_addr_info_req final: public request { + static void addr_info_callback(uv_getaddrinfo_t *req, int status, addrinfo *res); + int node_addr_info(const char *node, const char *service, addrinfo *hints = nullptr); + auto node_addr_info_sync(const char *node, const char *service, addrinfo *hints = nullptr); public: - using Deleter = void (*)(addrinfo *); + using deleter = void (*)(addrinfo *); - using Request::Request; + using request::request; /** * @brief Async [getaddrinfo](http://linux.die.net/man/3/getaddrinfo). * @param node Either a numerical network address or a network hostname. * @param hints Optional `addrinfo` data structure with additional address * type constraints. + * @return Underlying return value. */ - void nodeAddrInfo(const std::string &node, addrinfo *hints = nullptr); + int node_addr_info(const std::string &node, addrinfo *hints = nullptr); /** * @brief Sync [getaddrinfo](http://linux.die.net/man/3/getaddrinfo). @@ -90,17 +83,18 @@ public: * * @return A `std::pair` composed as it follows: * * A boolean value that is true in case of success, false otherwise. - * * A `std::unique_ptr` containing the data requested. + * * A `std::unique_ptr` containing the data requested. */ - std::pair> nodeAddrInfoSync(const std::string &node, addrinfo *hints = nullptr); + std::pair> node_addr_info_sync(const std::string &node, addrinfo *hints = nullptr); /** * @brief Async [getaddrinfo](http://linux.die.net/man/3/getaddrinfo). * @param service Either a service name or a port number as a string. * @param hints Optional `addrinfo` data structure with additional address * type constraints. + * @return Underlying return value. */ - void serviceAddrInfo(const std::string &service, addrinfo *hints = nullptr); + int service_addr_info(const std::string &service, addrinfo *hints = nullptr); /** * @brief Sync [getaddrinfo](http://linux.die.net/man/3/getaddrinfo). @@ -111,9 +105,9 @@ public: * * @return A `std::pair` composed as it follows: * * A boolean value that is true in case of success, false otherwise. - * * A `std::unique_ptr` containing the data requested. + * * A `std::unique_ptr` containing the data requested. */ - std::pair> serviceAddrInfoSync(const std::string &service, addrinfo *hints = nullptr); + std::pair> service_addr_info_sync(const std::string &service, addrinfo *hints = nullptr); /** * @brief Async [getaddrinfo](http://linux.die.net/man/3/getaddrinfo). @@ -121,8 +115,9 @@ public: * @param service Either a service name or a port number as a string. * @param hints Optional `addrinfo` data structure with additional address * type constraints. + * @return Underlying return value. */ - void addrInfo(const std::string &node, const std::string &service, addrinfo *hints = nullptr); + int addr_info(const std::string &node, const std::string &service, addrinfo *hints = nullptr); /** * @brief Sync [getaddrinfo](http://linux.die.net/man/3/getaddrinfo). @@ -134,48 +129,49 @@ public: * * @return A `std::pair` composed as it follows: * * A boolean value that is true in case of success, false otherwise. - * * A `std::unique_ptr` containing the data requested. + * * A `std::unique_ptr` containing the data requested. */ - std::pair> addrInfoSync(const std::string &node, const std::string &service, addrinfo *hints = nullptr); + std::pair> addr_info_sync(const std::string &node, const std::string &service, addrinfo *hints = nullptr); }; /** - * @brief The GetNameInfoReq request. + * @brief The getnameinfo request. * * Wrapper for [getnameinfo](http://linux.die.net/man/3/getnameinfo).
* It offers either asynchronous and synchronous access methods. * - * To create a `GetNameInfoReq` through a `Loop`, no arguments are required. + * To create a `get_name_info_req` through a `loop`, no arguments are required. */ -class GetNameInfoReq final: public Request { - static void nameInfoCallback(uv_getnameinfo_t *req, int status, const char *hostname, const char *service); +class get_name_info_req final: public request { + static void name_info_callback(uv_getnameinfo_t *req, int status, const char *hostname, const char *service); public: - using Request::Request; + using request::request; /** * @brief Async [getnameinfo](http://linux.die.net/man/3/getnameinfo). * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. * @param flags Optional flags that modify the behavior of `getnameinfo`. + * @return Underlying return value. */ - void nameInfo(const sockaddr &addr, int flags = 0); + int name_info(const sockaddr &addr, int flags = 0); /** * @brief Async [getnameinfo](http://linux.die.net/man/3/getnameinfo). * @param ip A valid IP address. * @param port A valid port number. * @param flags Optional flags that modify the behavior of `getnameinfo`. + * @return Underlying return value. */ - template - void nameInfo(const std::string &ip, unsigned int port, int flags = 0); + int name_info(const std::string &ip, unsigned int port, int flags = 0); /** * @brief Async [getnameinfo](http://linux.die.net/man/3/getnameinfo). - * @param addr A valid instance of Addr. + * @param addr A valid instance of socket_address. * @param flags Optional flags that modify the behavior of `getnameinfo`. + * @return Underlying return value. */ - template - void nameInfo(Addr addr, int flags = 0); + int name_info(socket_address addr, int flags = 0); /** * @brief Sync [getnameinfo](http://linux.die.net/man/3/getnameinfo). @@ -189,7 +185,7 @@ public: * * A `const char *` containing a valid hostname. * * A `const char *` containing a valid service name. */ - std::pair> nameInfoSync(const sockaddr &addr, int flags = 0); + std::pair> name_info_sync(const sockaddr &addr, int flags = 0); /** * @brief Sync [getnameinfo](http://linux.die.net/man/3/getnameinfo). @@ -204,13 +200,12 @@ public: * * A `const char *` containing a valid hostname. * * A `const char *` containing a valid service name. */ - template - std::pair> nameInfoSync(const std::string &ip, unsigned int port, int flags = 0); + std::pair> name_info_sync(const std::string &ip, unsigned int port, int flags = 0); /** * @brief Sync [getnameinfo](http://linux.die.net/man/3/getnameinfo). * - * @param addr A valid instance of Addr. + * @param addr A valid instance of socket_address. * @param flags Optional flags that modify the behavior of `getnameinfo`. * * @return A `std::pair` composed as it follows: @@ -219,35 +214,9 @@ public: * * A `const char *` containing a valid hostname. * * A `const char *` containing a valid service name. */ - template - std::pair> nameInfoSync(Addr addr, int flags = 0); + std::pair> name_info_sync(socket_address addr, int flags = 0); }; -/** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - -// (extern) explicit instantiations -#ifdef UVW_AS_LIB -extern template void GetNameInfoReq::nameInfo(const std::string &, unsigned int, int); -extern template void GetNameInfoReq::nameInfo(const std::string &, unsigned int, int); - -extern template void GetNameInfoReq::nameInfo(Addr, int); -extern template void GetNameInfoReq::nameInfo(Addr, int); - -extern template std::pair> GetNameInfoReq::nameInfoSync(const std::string &, unsigned int, int); -extern template std::pair> GetNameInfoReq::nameInfoSync(const std::string &, unsigned int, int); - -extern template std::pair> GetNameInfoReq::nameInfoSync(Addr, int); -extern template std::pair> GetNameInfoReq::nameInfoSync(Addr, int); -#endif // UVW_AS_LIB - -/** - * Internal details not to be documented. - * @endcond - */ - } // namespace uvw #ifndef UVW_AS_LIB diff --git a/src/uvw/emitter.cpp b/src/uvw/emitter.cpp index 539c017d..b0cde511 100644 --- a/src/uvw/emitter.cpp +++ b/src/uvw/emitter.cpp @@ -6,23 +6,23 @@ namespace uvw { -UVW_INLINE int ErrorEvent::translate(int sys) noexcept { +UVW_INLINE int error_event::translate(int sys) noexcept { return uv_translate_sys_error(sys); } -UVW_INLINE const char *ErrorEvent::what() const noexcept { +UVW_INLINE const char *error_event::what() const noexcept { return uv_strerror(ec); } -UVW_INLINE const char *ErrorEvent::name() const noexcept { +UVW_INLINE const char *error_event::name() const noexcept { return uv_err_name(ec); } -UVW_INLINE int ErrorEvent::code() const noexcept { +UVW_INLINE int error_event::code() const noexcept { return ec; } -UVW_INLINE ErrorEvent::operator bool() const noexcept { +UVW_INLINE error_event::operator bool() const noexcept { return ec < 0; } diff --git a/src/uvw/emitter.h b/src/uvw/emitter.h index 2585861d..5ae80b67 100644 --- a/src/uvw/emitter.h +++ b/src/uvw/emitter.h @@ -1,7 +1,6 @@ #ifndef UVW_EMITTER_INCLUDE_H #define UVW_EMITTER_INCLUDE_H -#include #include #include #include @@ -11,18 +10,19 @@ #include #include #include +#include "config.h" #include "type_info.hpp" namespace uvw { /** - * @brief The ErrorEvent event. + * @brief Error event. * * Custom wrapper around error constants of `libuv`. */ -struct ErrorEvent { +struct error_event { template>> - explicit ErrorEvent(U val) noexcept + explicit error_event(U val) noexcept : ec{static_cast(val)} {} /** @@ -79,215 +79,75 @@ private: * Almost everything in `uvw` is an event emitter.
* This is the base class from which resources and loops inherit. */ -template -class Emitter { - struct BaseHandler { - virtual ~BaseHandler() noexcept = default; - virtual bool empty() const noexcept = 0; - virtual void clear() noexcept = 0; - }; +template +class emitter { +public: + template + using listener_t = std::function; - template - struct Handler final: BaseHandler { - using Listener = std::function; - using Element = std::pair; - using ListenerList = std::list; - using Connection = typename ListenerList::iterator; +private: + template + const auto &handler() const noexcept { + return std::get>(handlers); + } - bool empty() const noexcept override { - auto pred = [](auto &&element) { return element.first; }; - - return std::all_of(onceL.cbegin(), onceL.cend(), pred) && std::all_of(onL.cbegin(), onL.cend(), pred); - } - - void clear() noexcept override { - if(publishing) { - auto func = [](auto &&element) { element.first = true; }; - std::for_each(onceL.begin(), onceL.end(), func); - std::for_each(onL.begin(), onL.end(), func); - } else { - onceL.clear(); - onL.clear(); - } - } - - Connection once(Listener f) { - return onceL.emplace(onceL.cend(), false, std::move(f)); - } - - Connection on(Listener f) { - return onL.emplace(onL.cend(), false, std::move(f)); - } - - void erase(Connection conn) noexcept { - conn->first = true; - - if(!publishing) { - auto pred = [](auto &&element) { return element.first; }; - onceL.remove_if(pred); - onL.remove_if(pred); - } - } - - void publish(E event, T &ref) { - ListenerList currentL; - onceL.swap(currentL); - - auto func = [&event, &ref](auto &&element) { - return element.first ? void() : element.second(event, ref); - }; - - publishing = true; - - std::for_each(onL.rbegin(), onL.rend(), func); - std::for_each(currentL.rbegin(), currentL.rend(), func); - - publishing = false; - - onL.remove_if([](auto &&element) { return element.first; }); - } - - private: - bool publishing{false}; - ListenerList onceL{}; - ListenerList onL{}; - }; - - template - Handler &handler() noexcept { - auto id = type(); - - if(!handlers.count(id)) { - handlers[id] = std::make_unique>(); - } - - return static_cast &>(*handlers.at(id)); + template + auto &handler() noexcept { + return std::get>(handlers); } protected: - template - void publish(E event) { - handler().publish(std::move(event), *static_cast(this)); + template + void publish(U event) { + if(auto &listener = handler(); listener) { + listener(event, *static_cast(this)); + } } public: - template - using Listener = typename Handler::Listener; - - /** - * @brief Connection type for a given event type. - * - * Given an event type `E`, `Connection` is the type of the connection - * object returned by the event emitter whenever a listener for the given - * type is registered. - */ - template - struct Connection: private Handler::Connection { - template - friend class Emitter; - - Connection() = default; - Connection(const Connection &) = default; - Connection(Connection &&) = default; - - Connection(typename Handler::Connection conn) - : Handler::Connection{std::move(conn)} {} - - Connection &operator=(const Connection &) = default; - Connection &operator=(Connection &&) = default; - }; - - virtual ~Emitter() noexcept { - static_assert(std::is_base_of_v, T>); + virtual ~emitter() noexcept { + static_assert(std::is_base_of_v, T>); } /** * @brief Registers a long-lived listener with the event emitter. * - * This method can be used to register a listener that is meant to be - * invoked more than once for the given event type.
- * The Connection object returned by the method can be freely discarded. It - * can be used later to disconnect the listener, if needed. - * - * Listener is usually defined as a callable object assignable to a + * This method is used to register a listener with the emitter.
+ * A listener is usually defined as a callable object assignable to a * `std::function - Connection on(Listener f) { - return handler().on(std::move(f)); + template + void on(listener_t f) { + handler() = std::move(f); + } + + /*! @brief Disconnects the listener for the given event type. */ + template + void reset() noexcept { + handler() = nullptr; + } + + /*! @brief Disconnects all listeners. */ + void reset() noexcept { + reset(); + (reset(), ...); } /** - * @brief Registers a short-lived listener with the event emitter. - * - * This method can be used to register a listener that is meant to be - * invoked only once for the given event type.
- * The Connection object returned by the method can be freely discarded. It - * can be used later to disconnect the listener, if needed. - * - * Listener is usually defined as a callable object assignable to a - * `std::function - Connection once(Listener f) { - return handler().once(std::move(f)); - } - - /** - * @brief Disconnects a listener from the event emitter. - * @param conn A valid Connection object - */ - template - void erase(Connection conn) noexcept { - handler().erase(std::move(conn)); - } - - /** - * @brief Disconnects all the listeners for the given event type. - */ - template - void clear() noexcept { - handler().clear(); - } - - /** - * @brief Disconnects all the listeners. - */ - void clear() noexcept { - std::for_each(handlers.begin(), handlers.end(), [](auto &&hdlr) { if(hdlr.second) { hdlr.second->clear(); } }); - } - - /** - * @brief Checks if there are listeners registered for the specific event. - * @return True if there are no listeners registered for the specific event, + * @brief Checks if there is a listener registered for the specific event. + * @return True if there is a listener registered for the specific event, * false otherwise. */ - template - bool empty() const noexcept { - auto id = type(); - - return (!handlers.count(id) || static_cast &>(*handlers.at(id)).empty()); - } - - /** - * @brief Checks if there are listeners registered with the event emitter. - * @return True if there are no listeners registered with the event emitter, - * false otherwise. - */ - bool empty() const noexcept { - return std::all_of(handlers.cbegin(), handlers.cend(), [](auto &&hdlr) { return !hdlr.second || hdlr.second->empty(); }); + template + bool has() const noexcept { + return static_cast(handler()); } private: - std::unordered_map> handlers{}; + std::tuple, listener_t...> handlers{}; }; } // namespace uvw diff --git a/src/uvw/enum.hpp b/src/uvw/enum.hpp new file mode 100644 index 00000000..12bc1a50 --- /dev/null +++ b/src/uvw/enum.hpp @@ -0,0 +1,76 @@ +#ifndef UVW_ENUM_INCLUDE_HPP +#define UVW_ENUM_INCLUDE_HPP + +#include +#include "config.h" + +/** + * @brief Operator available for enums for which bitmask support is enabled. + * @tparam Type Enum class type. + * @param lhs The first value to use. + * @param rhs The second value to use. + * @return The result of invoking the operator on the underlying types of the + * two values provided. + */ +template +[[nodiscard]] constexpr std::enable_if_t, decltype(Type::_UVW_ENUM)> +operator|(const Type lhs, const Type rhs) noexcept { + return static_cast(static_cast>(lhs) | static_cast>(rhs)); +} + +/*! @copydoc operator| */ +template +[[nodiscard]] constexpr std::enable_if_t, decltype(Type::_UVW_ENUM)> +operator&(const Type lhs, const Type rhs) noexcept { + return static_cast(static_cast>(lhs) & static_cast>(rhs)); +} + +/*! @copydoc operator| */ +template +[[nodiscard]] constexpr std::enable_if_t, decltype(Type::_UVW_ENUM)> +operator^(const Type lhs, const Type rhs) noexcept { + return static_cast(static_cast>(lhs) ^ static_cast>(rhs)); +} + +/** + * @brief Operator available for enums for which bitmask support is enabled. + * @tparam Type Enum class type. + * @param value The value to use. + * @return The result of invoking the operator on the underlying types of the + * value provided. + */ +template +[[nodiscard]] constexpr std::enable_if_t, decltype(Type::_UVW_ENUM)> +operator~(const Type value) noexcept { + return static_cast(~static_cast>(value)); +} + +/*! @copydoc operator~ */ +template +[[nodiscard]] constexpr std::enable_if_t, decltype(Type::_UVW_ENUM, bool{})> +operator!(const Type value) noexcept { + return !static_cast>(value); +} + +/*! @copydoc operator| */ +template +constexpr std::enable_if_t, decltype(Type::_UVW_ENUM) &> +operator|=(Type &lhs, const Type rhs) noexcept { + return (lhs = (lhs | rhs)); +} + +/*! @copydoc operator| */ +template +constexpr std::enable_if_t, decltype(Type::_UVW_ENUM) &> +operator&=(Type &lhs, const Type rhs) noexcept { + return (lhs = (lhs & rhs)); +} + +/*! @copydoc operator| */ +template +constexpr std::enable_if_t, decltype(Type::_UVW_ENUM) &> +operator^=(Type &lhs, const Type rhs) noexcept { + return (lhs = (lhs ^ rhs)); +} + +#endif diff --git a/src/uvw/fs.cpp b/src/uvw/fs.cpp index 6e747e01..5921d818 100644 --- a/src/uvw/fs.cpp +++ b/src/uvw/fs.cpp @@ -6,50 +6,46 @@ namespace uvw { -UVW_INLINE void FileReq::fsOpenCallback(uv_fs_t *req) { - auto ptr = reserve(req); - - if(req->result < 0) { - ptr->publish(ErrorEvent{req->result}); +UVW_INLINE void file_req::fs_open_callback(uv_fs_t *req) { + if(auto ptr = reserve(req); req->result < 0) { + ptr->publish(error_event{req->result}); } else { ptr->file = static_cast(req->result); - ptr->publish(FsEvent{req->path}); + ptr->publish(fs_event{*req}); } } -UVW_INLINE void FileReq::fsCloseCallback(uv_fs_t *req) { - auto ptr = reserve(req); - - if(req->result < 0) { - ptr->publish(ErrorEvent{req->result}); +UVW_INLINE void file_req::fs_close_callback(uv_fs_t *req) { + if(auto ptr = reserve(req); req->result < 0) { + ptr->publish(error_event{req->result}); } else { ptr->file = BAD_FD; - ptr->publish(FsEvent{req->path}); + ptr->publish(fs_event{*req}); } } -UVW_INLINE void FileReq::fsReadCallback(uv_fs_t *req) { - auto ptr = reserve(req); - - if(req->result < 0) { - ptr->publish(ErrorEvent{req->result}); +UVW_INLINE void file_req::fs_read_callback(uv_fs_t *req) { + if(auto ptr = reserve(req); req->result < 0) { + ptr->publish(error_event{req->result}); } else { - ptr->publish(FsEvent{req->path, std::move(ptr->current), static_cast(req->result)}); + ptr->publish(fs_event{*req, std::move(ptr->current)}); } } -UVW_INLINE FileReq::~FileReq() noexcept { - uv_fs_req_cleanup(get()); +UVW_INLINE file_req::~file_req() noexcept { + uv_fs_req_cleanup(raw()); } -UVW_INLINE void FileReq::close() { - cleanupAndInvoke(&uv_fs_close, parent(), get(), file, &fsCloseCallback); +UVW_INLINE void file_req::close() { + uv_fs_req_cleanup(this->raw()); + uv_fs_close(parent().raw(), raw(), file, &fs_close_callback); } -UVW_INLINE bool FileReq::closeSync() { - auto req = get(); +UVW_INLINE bool file_req::close_sync() { + auto req = raw(); - cleanupAndInvokeSync(&uv_fs_close, parent(), req, file); + uv_fs_req_cleanup(this->raw()); + uv_fs_close(parent().raw(), req, file, nullptr); if(req->result >= 0) { file = BAD_FD; @@ -58,14 +54,16 @@ UVW_INLINE bool FileReq::closeSync() { return !(req->result < 0); } -UVW_INLINE void FileReq::open(const std::string &path, Flags flags, int mode) { - cleanupAndInvoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsOpenCallback); +UVW_INLINE void file_req::open(const std::string &path, file_open_flags flags, int mode) { + uv_fs_req_cleanup(this->raw()); + uv_fs_open(parent().raw(), raw(), path.data(), static_cast(flags), mode, &fs_open_callback); } -UVW_INLINE bool FileReq::openSync(const std::string &path, Flags flags, int mode) { - auto req = get(); +UVW_INLINE bool file_req::open_sync(const std::string &path, file_open_flags flags, int mode) { + auto req = raw(); - cleanupAndInvokeSync(&uv_fs_open, parent(), req, path.data(), flags, mode); + uv_fs_req_cleanup(this->raw()); + uv_fs_open(parent().raw(), req, path.data(), static_cast(flags), mode, nullptr); if(req->result >= 0) { file = static_cast(req->result); @@ -74,191 +72,199 @@ UVW_INLINE bool FileReq::openSync(const std::string &path, Flags flags return !(req->result < 0); } -UVW_INLINE void FileReq::read(int64_t offset, unsigned int len) { +UVW_INLINE void file_req::read(int64_t offset, unsigned int len) { current = std::unique_ptr{new char[len]}; buffer = uv_buf_init(current.get(), len); uv_buf_t bufs[] = {buffer}; - cleanupAndInvoke(&uv_fs_read, parent(), get(), file, bufs, 1, offset, &fsReadCallback); + uv_fs_req_cleanup(this->raw()); + uv_fs_read(parent().raw(), raw(), file, bufs, 1, offset, &fs_read_callback); } -UVW_INLINE std::pair, std::size_t>> FileReq::readSync(int64_t offset, unsigned int len) { +UVW_INLINE std::pair, std::size_t>> file_req::read_sync(int64_t offset, unsigned int len) { current = std::unique_ptr{new char[len]}; buffer = uv_buf_init(current.get(), len); uv_buf_t bufs[] = {buffer}; - auto req = get(); - cleanupAndInvokeSync(&uv_fs_read, parent(), req, file, bufs, 1, offset); + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_read(parent().raw(), req, file, bufs, 1, offset, nullptr); bool err = req->result < 0; return std::make_pair(!err, std::make_pair(std::move(current), err ? 0 : std::size_t(req->result))); } -UVW_INLINE void FileReq::write(std::unique_ptr buf, unsigned int len, int64_t offset) { +UVW_INLINE void file_req::write(std::unique_ptr buf, unsigned int len, int64_t offset) { current = std::move(buf); uv_buf_t bufs[] = {uv_buf_init(current.get(), len)}; - cleanupAndInvoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsResultCallback); + uv_fs_req_cleanup(this->raw()); + uv_fs_write(parent().raw(), raw(), file, bufs, 1, offset, &fs_request_callback); } -UVW_INLINE void FileReq::write(char *buf, unsigned int len, int64_t offset) { +UVW_INLINE void file_req::write(char *buf, unsigned int len, int64_t offset) { uv_buf_t bufs[] = {uv_buf_init(buf, len)}; - cleanupAndInvoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsResultCallback); + uv_fs_req_cleanup(this->raw()); + uv_fs_write(parent().raw(), raw(), file, bufs, 1, offset, &fs_request_callback); } -UVW_INLINE std::pair FileReq::writeSync(std::unique_ptr buf, unsigned int len, int64_t offset) { +UVW_INLINE std::pair file_req::write_sync(std::unique_ptr buf, unsigned int len, int64_t offset) { current = std::move(buf); uv_buf_t bufs[] = {uv_buf_init(current.get(), len)}; - auto req = get(); - cleanupAndInvokeSync(&uv_fs_write, parent(), req, file, bufs, 1, offset); + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_write(parent().raw(), req, file, bufs, 1, offset, nullptr); bool err = req->result < 0; return std::make_pair(!err, err ? 0 : std::size_t(req->result)); } -UVW_INLINE void FileReq::stat() { - cleanupAndInvoke(&uv_fs_fstat, parent(), get(), file, &fsStatCallback); +UVW_INLINE void file_req::stat() { + uv_fs_req_cleanup(this->raw()); + uv_fs_fstat(parent().raw(), raw(), file, &fs_request_callback); } -UVW_INLINE std::pair FileReq::statSync() { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file); +UVW_INLINE std::pair file_req::stat_sync() { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_fstat(parent().raw(), req, file, nullptr); return std::make_pair(!(req->result < 0), req->statbuf); } -UVW_INLINE void FileReq::sync() { - cleanupAndInvoke(&uv_fs_fsync, parent(), get(), file, &fsGenericCallback); +UVW_INLINE void file_req::sync() { + uv_fs_req_cleanup(this->raw()); + uv_fs_fsync(parent().raw(), raw(), file, &fs_request_callback); } -UVW_INLINE bool FileReq::syncSync() { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_fsync, parent(), req, file); +UVW_INLINE bool file_req::sync_sync() { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_fsync(parent().raw(), req, file, nullptr); return !(req->result < 0); } -UVW_INLINE void FileReq::datasync() { - cleanupAndInvoke(&uv_fs_fdatasync, parent(), get(), file, &fsGenericCallback); +UVW_INLINE void file_req::datasync() { + uv_fs_req_cleanup(this->raw()); + uv_fs_fdatasync(parent().raw(), raw(), file, &fs_request_callback); } -UVW_INLINE bool FileReq::datasyncSync() { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), req, file); +UVW_INLINE bool file_req::datasync_sync() { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_fdatasync(parent().raw(), req, file, nullptr); return !(req->result < 0); } -UVW_INLINE void FileReq::truncate(int64_t offset) { - cleanupAndInvoke(&uv_fs_ftruncate, parent(), get(), file, offset, &fsGenericCallback); +UVW_INLINE void file_req::truncate(int64_t offset) { + uv_fs_req_cleanup(this->raw()); + uv_fs_ftruncate(parent().raw(), raw(), file, offset, &fs_request_callback); } -UVW_INLINE bool FileReq::truncateSync(int64_t offset) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), req, file, offset); +UVW_INLINE bool file_req::truncate_sync(int64_t offset) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_ftruncate(parent().raw(), req, file, offset, nullptr); return !(req->result < 0); } -UVW_INLINE void FileReq::sendfile(FileHandle out, int64_t offset, std::size_t length) { - cleanupAndInvoke(&uv_fs_sendfile, parent(), get(), out, file, offset, length, &fsResultCallback); +UVW_INLINE void file_req::sendfile(file_handle out, int64_t offset, std::size_t length) { + uv_fs_req_cleanup(this->raw()); + uv_fs_sendfile(parent().raw(), raw(), out, file, offset, length, &fs_request_callback); } -UVW_INLINE std::pair FileReq::sendfileSync(FileHandle out, int64_t offset, std::size_t length) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, file, offset, length); +UVW_INLINE std::pair file_req::sendfile_sync(file_handle out, int64_t offset, std::size_t length) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_sendfile(parent().raw(), req, out, file, offset, length, nullptr); bool err = req->result < 0; return std::make_pair(!err, err ? 0 : std::size_t(req->result)); } -UVW_INLINE void FileReq::chmod(int mode) { - cleanupAndInvoke(&uv_fs_fchmod, parent(), get(), file, mode, &fsGenericCallback); +UVW_INLINE void file_req::chmod(int mode) { + uv_fs_req_cleanup(this->raw()); + uv_fs_fchmod(parent().raw(), raw(), file, mode, &fs_request_callback); } -UVW_INLINE bool FileReq::chmodSync(int mode) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_fchmod, parent(), req, file, mode); +UVW_INLINE bool file_req::chmod_sync(int mode) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_fchmod(parent().raw(), req, file, mode, nullptr); return !(req->result < 0); } -UVW_INLINE void FileReq::futime(FsRequest::Time atime, FsRequest::Time mtime) { - cleanupAndInvoke(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), &fsGenericCallback); +UVW_INLINE void file_req::futime(fs_request::time atime, fs_request::time mtime) { + uv_fs_req_cleanup(this->raw()); + uv_fs_futime(parent().raw(), raw(), file, atime.count(), mtime.count(), &fs_request_callback); } -UVW_INLINE bool FileReq::futimeSync(FsRequest::Time atime, FsRequest::Time mtime) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_futime, parent(), req, file, atime.count(), mtime.count()); +UVW_INLINE bool file_req::futime_sync(fs_request::time atime, fs_request::time mtime) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_futime(parent().raw(), req, file, atime.count(), mtime.count(), nullptr); return !(req->result < 0); } -UVW_INLINE void FileReq::chown(Uid uid, Gid gid) { - cleanupAndInvoke(&uv_fs_fchown, parent(), get(), file, uid, gid, &fsGenericCallback); +UVW_INLINE void file_req::chown(uid_type uid, gid_type gid) { + uv_fs_req_cleanup(this->raw()); + uv_fs_fchown(parent().raw(), raw(), file, uid, gid, &fs_request_callback); } -UVW_INLINE bool FileReq::chownSync(Uid uid, Gid gid) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid); +UVW_INLINE bool file_req::chown_sync(uid_type uid, gid_type gid) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_fchown(parent().raw(), req, file, uid, gid, nullptr); return !(req->result < 0); } -UVW_INLINE FileReq::operator FileHandle() const noexcept { +UVW_INLINE file_req::operator file_handle() const noexcept { return file; } -UVW_INLINE void FsReq::fsReadlinkCallback(uv_fs_t *req) { - auto ptr = reserve(req); - - if(req->result < 0) { - ptr->publish(ErrorEvent{req->result}); - } else { - ptr->publish(FsEvent{req->path, static_cast(req->ptr), static_cast(req->result)}); - } +UVW_INLINE fs_req::~fs_req() noexcept { + uv_fs_req_cleanup(raw()); } -UVW_INLINE void FsReq::fsReaddirCallback(uv_fs_t *req) { - auto ptr = reserve(req); - - if(req->result < 0) { - ptr->publish(ErrorEvent{req->result}); - } else { - auto *dir = static_cast(req->ptr); - ptr->publish(FsEvent{dir->dirents[0].name, static_cast(dir->dirents[0].type), !req->result}); - } +UVW_INLINE void fs_req::unlink(const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_unlink(parent().raw(), raw(), path.data(), &fs_request_callback); } -UVW_INLINE FsReq::~FsReq() noexcept { - uv_fs_req_cleanup(get()); -} - -UVW_INLINE void FsReq::unlink(const std::string &path) { - cleanupAndInvoke(&uv_fs_unlink, parent(), get(), path.data(), &fsGenericCallback); -} - -UVW_INLINE bool FsReq::unlinkSync(const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_unlink, parent(), req, path.data()); +UVW_INLINE bool fs_req::unlink_sync(const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_unlink(parent().raw(), req, path.data(), nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::mkdir(const std::string &path, int mode) { - cleanupAndInvoke(&uv_fs_mkdir, parent(), get(), path.data(), mode, &fsGenericCallback); +UVW_INLINE void fs_req::mkdir(const std::string &path, int mode) { + uv_fs_req_cleanup(this->raw()); + uv_fs_mkdir(parent().raw(), raw(), path.data(), mode, &fs_request_callback); } -UVW_INLINE bool FsReq::mkdirSync(const std::string &path, int mode) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_mkdir, parent(), req, path.data(), mode); +UVW_INLINE bool fs_req::mkdir_sync(const std::string &path, int mode) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_mkdir(parent().raw(), req, path.data(), mode, nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::mkdtemp(const std::string &tpl) { - cleanupAndInvoke(&uv_fs_mkdtemp, parent(), get(), tpl.data(), &fsGenericCallback); +UVW_INLINE void fs_req::mkdtemp(const std::string &tpl) { + uv_fs_req_cleanup(this->raw()); + uv_fs_mkdtemp(parent().raw(), raw(), tpl.data(), &fs_request_callback); } -UVW_INLINE std::pair FsReq::mkdtempSync(const std::string &tpl) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), req, tpl.data()); +UVW_INLINE std::pair fs_req::mkdtemp_sync(const std::string &tpl) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_mkdtemp(parent().raw(), req, tpl.data(), nullptr); return std::make_pair(!(req->result < 0), req->path); } -UVW_INLINE void FsReq::mkstemp(const std::string &tpl) { - cleanupAndInvoke(&uv_fs_mkstemp, parent(), get(), tpl.data(), &fsResultCallback); +UVW_INLINE void fs_req::mkstemp(const std::string &tpl) { + uv_fs_req_cleanup(this->raw()); + uv_fs_mkstemp(parent().raw(), raw(), tpl.data(), &fs_request_callback); } -UVW_INLINE std::pair> FsReq::mkstempSync(const std::string &tpl) { +UVW_INLINE std::pair> fs_req::mkstemp_sync(const std::string &tpl) { std::pair> ret{false, {}}; - auto req = get(); - cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), req, tpl.data()); + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_mkstemp(parent().raw(), req, tpl.data(), nullptr); ret.first = !(req->result < 0); if(ret.first) { @@ -269,46 +275,51 @@ UVW_INLINE std::pair> FsReq::mkstempSy return ret; } -UVW_INLINE void FsReq::lutime(const std::string &path, Time atime, Time mtime) { - cleanupAndInvoke(&uv_fs_lutime, parent(), get(), path.data(), atime.count(), mtime.count(), &fsGenericCallback); +UVW_INLINE void fs_req::lutime(const std::string &path, time atime, time mtime) { + uv_fs_req_cleanup(this->raw()); + uv_fs_lutime(parent().raw(), raw(), path.data(), atime.count(), mtime.count(), &fs_request_callback); } -UVW_INLINE bool FsReq::lutimeSync(const std::string &path, Time atime, Time mtime) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_lutime, parent(), req, path.data(), atime.count(), mtime.count()); +UVW_INLINE bool fs_req::lutime_sync(const std::string &path, time atime, time mtime) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_lutime(parent().raw(), req, path.data(), atime.count(), mtime.count(), nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::rmdir(const std::string &path) { - cleanupAndInvoke(&uv_fs_rmdir, parent(), get(), path.data(), &fsGenericCallback); +UVW_INLINE void fs_req::rmdir(const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_rmdir(parent().raw(), raw(), path.data(), &fs_request_callback); } -UVW_INLINE bool FsReq::rmdirSync(const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_rmdir, parent(), req, path.data()); +UVW_INLINE bool fs_req::rmdir_sync(const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_rmdir(parent().raw(), req, path.data(), nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::scandir(const std::string &path, int flags) { - cleanupAndInvoke(&uv_fs_scandir, parent(), get(), path.data(), flags, &fsResultCallback); +UVW_INLINE void fs_req::scandir(const std::string &path, int flags) { + uv_fs_req_cleanup(this->raw()); + uv_fs_scandir(parent().raw(), raw(), path.data(), flags, &fs_request_callback); } -UVW_INLINE std::pair FsReq::scandirSync(const std::string &path, int flags) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_scandir, parent(), req, path.data(), flags); +UVW_INLINE std::pair fs_req::scandir_sync(const std::string &path, int flags) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_scandir(parent().raw(), req, path.data(), flags, nullptr); bool err = req->result < 0; return std::make_pair(!err, err ? 0 : std::size_t(req->result)); } -UVW_INLINE std::pair> FsReq::scandirNext() { - std::pair> ret{false, {EntryType::UNKNOWN, nullptr}}; +UVW_INLINE std::pair> fs_req::scandir_next() { + std::pair> ret{false, {entry_type::UNKNOWN, nullptr}}; - // we cannot use cleanupAndInvokeSync because of the return value of uv_fs_scandir_next - uv_fs_req_cleanup(get()); - auto res = uv_fs_scandir_next(get(), dirents); + uv_fs_req_cleanup(raw()); + auto res = uv_fs_scandir_next(raw(), dirents); if(UV_EOF != res) { - ret.second.first = static_cast(dirents[0].type); + ret.second.first = static_cast(dirents[0].type); ret.second.second = dirents[0].name; ret.first = true; } @@ -316,192 +327,226 @@ UVW_INLINE std::pair> FsReq::sca return ret; } -UVW_INLINE void FsReq::stat(const std::string &path) { - cleanupAndInvoke(&uv_fs_stat, parent(), get(), path.data(), &fsStatCallback); +UVW_INLINE void fs_req::stat(const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_stat(parent().raw(), raw(), path.data(), &fs_request_callback); } -UVW_INLINE std::pair FsReq::statSync(const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_stat, parent(), req, path.data()); +UVW_INLINE std::pair fs_req::stat_sync(const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_stat(parent().raw(), req, path.data(), nullptr); return std::make_pair(!(req->result < 0), req->statbuf); } -UVW_INLINE void FsReq::lstat(const std::string &path) { - cleanupAndInvoke(&uv_fs_lstat, parent(), get(), path.data(), &fsStatCallback); +UVW_INLINE void fs_req::lstat(const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_lstat(parent().raw(), raw(), path.data(), &fs_request_callback); } -UVW_INLINE std::pair FsReq::lstatSync(const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_lstat, parent(), req, path.data()); +UVW_INLINE std::pair fs_req::lstat_sync(const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_lstat(parent().raw(), req, path.data(), nullptr); return std::make_pair(!(req->result < 0), req->statbuf); } -UVW_INLINE void FsReq::statfs(const std::string &path) { - cleanupAndInvoke(&uv_fs_statfs, parent(), get(), path.data(), &fsStatfsCallback); +UVW_INLINE void fs_req::statfs(const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_statfs(parent().raw(), raw(), path.data(), &fs_request_callback); } -UVW_INLINE std::pair FsReq::statfsSync(const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_statfs, parent(), req, path.data()); +UVW_INLINE std::pair fs_req::statfs_sync(const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_statfs(parent().raw(), req, path.data(), nullptr); return std::make_pair(!(req->result < 0), *static_cast(req->ptr)); } -UVW_INLINE void FsReq::rename(const std::string &old, const std::string &path) { - cleanupAndInvoke(&uv_fs_rename, parent(), get(), old.data(), path.data(), &fsGenericCallback); +UVW_INLINE void fs_req::rename(const std::string &old, const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_rename(parent().raw(), raw(), old.data(), path.data(), &fs_request_callback); } -UVW_INLINE bool FsReq::renameSync(const std::string &old, const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_rename, parent(), req, old.data(), path.data()); +UVW_INLINE bool fs_req::rename_sync(const std::string &old, const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_rename(parent().raw(), req, old.data(), path.data(), nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::copyfile(const std::string &old, const std::string &path, Flags flags) { - cleanupAndInvoke(&uv_fs_copyfile, parent(), get(), old.data(), path.data(), flags, &fsGenericCallback); +UVW_INLINE void fs_req::copyfile(const std::string &old, const std::string &path, copy_file_flags flags) { + uv_fs_req_cleanup(this->raw()); + uv_fs_copyfile(parent().raw(), raw(), old.data(), path.data(), static_cast(flags), &fs_request_callback); } -UVW_INLINE bool FsReq::copyfileSync(const std::string &old, const std::string &path, Flags flags) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_copyfile, parent(), get(), old.data(), path.data(), flags); +UVW_INLINE bool fs_req::copyfile_sync(const std::string &old, const std::string &path, copy_file_flags flags) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_copyfile(parent().raw(), raw(), old.data(), path.data(), static_cast(flags), nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::access(const std::string &path, int mode) { - cleanupAndInvoke(&uv_fs_access, parent(), get(), path.data(), mode, &fsGenericCallback); +UVW_INLINE void fs_req::access(const std::string &path, int mode) { + uv_fs_req_cleanup(this->raw()); + uv_fs_access(parent().raw(), raw(), path.data(), mode, &fs_request_callback); } -UVW_INLINE bool FsReq::accessSync(const std::string &path, int mode) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_access, parent(), req, path.data(), mode); +UVW_INLINE bool fs_req::access_sync(const std::string &path, int mode) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_access(parent().raw(), req, path.data(), mode, nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::chmod(const std::string &path, int mode) { - cleanupAndInvoke(&uv_fs_chmod, parent(), get(), path.data(), mode, &fsGenericCallback); +UVW_INLINE void fs_req::chmod(const std::string &path, int mode) { + uv_fs_req_cleanup(this->raw()); + uv_fs_chmod(parent().raw(), raw(), path.data(), mode, &fs_request_callback); } -UVW_INLINE bool FsReq::chmodSync(const std::string &path, int mode) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_chmod, parent(), req, path.data(), mode); +UVW_INLINE bool fs_req::chmod_sync(const std::string &path, int mode) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_chmod(parent().raw(), req, path.data(), mode, nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::utime(const std::string &path, FsRequest::Time atime, FsRequest::Time mtime) { - cleanupAndInvoke(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), &fsGenericCallback); +UVW_INLINE void fs_req::utime(const std::string &path, fs_request::time atime, fs_request::time mtime) { + uv_fs_req_cleanup(this->raw()); + uv_fs_utime(parent().raw(), raw(), path.data(), atime.count(), mtime.count(), &fs_request_callback); } -UVW_INLINE bool FsReq::utimeSync(const std::string &path, FsRequest::Time atime, FsRequest::Time mtime) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_utime, parent(), req, path.data(), atime.count(), mtime.count()); +UVW_INLINE bool fs_req::utime_sync(const std::string &path, fs_request::time atime, fs_request::time mtime) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_utime(parent().raw(), req, path.data(), atime.count(), mtime.count(), nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::link(const std::string &old, const std::string &path) { - cleanupAndInvoke(&uv_fs_link, parent(), get(), old.data(), path.data(), &fsGenericCallback); +UVW_INLINE void fs_req::link(const std::string &old, const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_link(parent().raw(), raw(), old.data(), path.data(), &fs_request_callback); } -UVW_INLINE bool FsReq::linkSync(const std::string &old, const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_link, parent(), req, old.data(), path.data()); +UVW_INLINE bool fs_req::link_sync(const std::string &old, const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_link(parent().raw(), req, old.data(), path.data(), nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::symlink(const std::string &old, const std::string &path, Flags flags) { - cleanupAndInvoke(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, &fsGenericCallback); +UVW_INLINE void fs_req::symlink(const std::string &old, const std::string &path, symlink_flags flags) { + uv_fs_req_cleanup(this->raw()); + uv_fs_symlink(parent().raw(), raw(), old.data(), path.data(), static_cast(flags), &fs_request_callback); } -UVW_INLINE bool FsReq::symlinkSync(const std::string &old, const std::string &path, Flags flags) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_symlink, parent(), req, old.data(), path.data(), flags); +UVW_INLINE bool fs_req::symlink_sync(const std::string &old, const std::string &path, symlink_flags flags) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_symlink(parent().raw(), req, old.data(), path.data(), static_cast(flags), nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::readlink(const std::string &path) { - cleanupAndInvoke(&uv_fs_readlink, parent(), get(), path.data(), &fsReadlinkCallback); +UVW_INLINE void fs_req::readlink(const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_readlink(parent().raw(), raw(), path.data(), &fs_request_callback); } -UVW_INLINE std::pair> FsReq::readlinkSync(const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_readlink, parent(), req, path.data()); +UVW_INLINE std::pair> fs_req::readlink_sync(const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_readlink(parent().raw(), req, path.data(), nullptr); bool err = req->result < 0; return std::make_pair(!err, std::make_pair(static_cast(req->ptr), err ? 0 : std::size_t(req->result))); } -UVW_INLINE void FsReq::realpath(const std::string &path) { - cleanupAndInvoke(&uv_fs_realpath, parent(), get(), path.data(), &fsGenericCallback); +UVW_INLINE void fs_req::realpath(const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_realpath(parent().raw(), raw(), path.data(), &fs_request_callback); } -UVW_INLINE std::pair FsReq::realpathSync(const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_realpath, parent(), req, path.data()); +UVW_INLINE std::pair fs_req::realpath_sync(const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_realpath(parent().raw(), req, path.data(), nullptr); return std::make_pair(!(req->result < 0), req->path); } -UVW_INLINE void FsReq::chown(const std::string &path, Uid uid, Gid gid) { - cleanupAndInvoke(&uv_fs_chown, parent(), get(), path.data(), uid, gid, &fsGenericCallback); +UVW_INLINE void fs_req::chown(const std::string &path, uid_type uid, gid_type gid) { + uv_fs_req_cleanup(this->raw()); + uv_fs_chown(parent().raw(), raw(), path.data(), uid, gid, &fs_request_callback); } -UVW_INLINE bool FsReq::chownSync(const std::string &path, Uid uid, Gid gid) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_chown, parent(), req, path.data(), uid, gid); +UVW_INLINE bool fs_req::chown_sync(const std::string &path, uid_type uid, gid_type gid) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_chown(parent().raw(), req, path.data(), uid, gid, nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::lchown(const std::string &path, Uid uid, Gid gid) { - cleanupAndInvoke(&uv_fs_lchown, parent(), get(), path.data(), uid, gid, &fsGenericCallback); +UVW_INLINE void fs_req::lchown(const std::string &path, uid_type uid, gid_type gid) { + uv_fs_req_cleanup(this->raw()); + uv_fs_lchown(parent().raw(), raw(), path.data(), uid, gid, &fs_request_callback); } -UVW_INLINE bool FsReq::lchownSync(const std::string &path, Uid uid, Gid gid) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_lchown, parent(), req, path.data(), uid, gid); +UVW_INLINE bool fs_req::lchown_sync(const std::string &path, uid_type uid, gid_type gid) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_lchown(parent().raw(), req, path.data(), uid, gid, nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::opendir(const std::string &path) { - cleanupAndInvoke(&uv_fs_opendir, parent(), get(), path.data(), &fsGenericCallback); +UVW_INLINE void fs_req::opendir(const std::string &path) { + uv_fs_req_cleanup(this->raw()); + uv_fs_opendir(parent().raw(), raw(), path.data(), &fs_request_callback); } -UVW_INLINE bool FsReq::opendirSync(const std::string &path) { - auto req = get(); - cleanupAndInvokeSync(&uv_fs_opendir, parent(), req, path.data()); +UVW_INLINE bool fs_req::opendir_sync(const std::string &path) { + auto req = raw(); + uv_fs_req_cleanup(this->raw()); + uv_fs_opendir(parent().raw(), req, path.data(), nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::closedir() { - auto req = get(); +UVW_INLINE void fs_req::closedir() { + auto req = raw(); auto *dir = static_cast(req->ptr); - cleanupAndInvoke(&uv_fs_closedir, parent(), req, dir, &fsGenericCallback); + uv_fs_req_cleanup(this->raw()); + uv_fs_closedir(parent().raw(), req, dir, &fs_request_callback); } -UVW_INLINE bool FsReq::closedirSync() { - auto req = get(); +UVW_INLINE bool fs_req::closedir_sync() { + auto req = raw(); auto *dir = static_cast(req->ptr); - cleanupAndInvokeSync(&uv_fs_closedir, parent(), req, dir); + uv_fs_req_cleanup(this->raw()); + uv_fs_closedir(parent().raw(), req, dir, nullptr); return !(req->result < 0); } -UVW_INLINE void FsReq::readdir() { - auto req = get(); +UVW_INLINE void fs_req::readdir() { + auto req = raw(); auto *dir = static_cast(req->ptr); dir->dirents = dirents; dir->nentries = 1; - cleanupAndInvoke(&uv_fs_readdir, parent(), req, dir, &fsReaddirCallback); + uv_fs_req_cleanup(this->raw()); + uv_fs_readdir(parent().raw(), req, dir, &fs_request_callback); } -UVW_INLINE std::pair> FsReq::readdirSync() { - auto req = get(); +UVW_INLINE std::pair> fs_req::readdir_sync() { + auto req = raw(); auto *dir = static_cast(req->ptr); dir->dirents = dirents; dir->nentries = 1; - cleanupAndInvokeSync(&uv_fs_readdir, parent(), req, dir); - return {req->result != 0, {static_cast(dirents[0].type), dirents[0].name}}; + uv_fs_req_cleanup(this->raw()); + uv_fs_readdir(parent().raw(), req, dir, nullptr); + return {req->result != 0, {static_cast(dirents[0].type), dirents[0].name}}; } -UVW_INLINE OSFileDescriptor FsHelper::handle(FileHandle file) noexcept { +UVW_INLINE os_file_descriptor fs_helper::handle(file_handle file) noexcept { return uv_get_osfhandle(file); } -UVW_INLINE FileHandle FsHelper::open(OSFileDescriptor descriptor) noexcept { +UVW_INLINE file_handle fs_helper::open(os_file_descriptor descriptor) noexcept { return uv_open_osfhandle(descriptor); } diff --git a/src/uvw/fs.h b/src/uvw/fs.h index 3d00aea4..878ad643 100644 --- a/src/uvw/fs.h +++ b/src/uvw/fs.h @@ -6,6 +6,8 @@ #include #include #include +#include "config.h" +#include "enum.hpp" #include "loop.h" #include "request.hpp" #include "util.h" @@ -14,7 +16,7 @@ namespace uvw { namespace details { -enum class UVFsType : std::underlying_type_t { +enum class uvw_fs_type : std::underlying_type_t { UNKNOWN = UV_FS_UNKNOWN, CUSTOM = UV_FS_CUSTOM, OPEN = UV_FS_OPEN, @@ -55,7 +57,7 @@ enum class UVFsType : std::underlying_type_t { LUTIME = UV_FS_LUTIME }; -enum class UVDirentTypeT : std::underlying_type_t { +enum class uvw_dirent_type_t : std::underlying_type_t { UNKNOWN = UV_DIRENT_UNKNOWN, FILE = UV_DIRENT_FILE, DIR = UV_DIRENT_DIR, @@ -66,7 +68,7 @@ enum class UVDirentTypeT : std::underlying_type_t { BLOCK = UV_DIRENT_BLOCK }; -enum class UVFileOpenFlags : int { +enum class uvw_file_open_flags : int { APPEND = UV_FS_O_APPEND, CREAT = UV_FS_O_CREAT, DIRECT = UV_FS_O_DIRECT, @@ -88,345 +90,185 @@ enum class UVFileOpenFlags : int { SYNC = UV_FS_O_SYNC, TEMPORARY = UV_FS_O_TEMPORARY, TRUNC = UV_FS_O_TRUNC, - WRONLY = UV_FS_O_WRONLY + WRONLY = UV_FS_O_WRONLY, + _UVW_ENUM = 0 }; -enum class UVCopyFileFlags : int { +enum class uvw_copy_file_flags : int { EXCL = UV_FS_COPYFILE_EXCL, FICLONE = UV_FS_COPYFILE_FICLONE, - FICLONE_FORCE = UV_FS_COPYFILE_FICLONE_FORCE + FICLONE_FORCE = UV_FS_COPYFILE_FICLONE_FORCE, + _UVW_ENUM = 0 }; -enum class UVSymLinkFlags : int { +enum class uvw_symlink_flags : int { DIR = UV_FS_SYMLINK_DIR, - JUNCTION = UV_FS_SYMLINK_JUNCTION + JUNCTION = UV_FS_SYMLINK_JUNCTION, + _UVW_ENUM = 0 }; } // namespace details /** - * @brief Default FsEvent event. + * @brief Common fs event. * * Available types are: * - * * `FsRequest::Type::UNKNOWN` - * * `FsRequest::Type::CUSTOM` - * * `FsRequest::Type::OPEN` - * * `FsRequest::Type::CLOSE` - * * `FsRequest::Type::READ` - * * `FsRequest::Type::WRITE` - * * `FsRequest::Type::SENDFILE` - * * `FsRequest::Type::STAT` - * * `FsRequest::Type::LSTAT` - * * `FsRequest::Type::FSTAT` - * * `FsRequest::Type::FTRUNCATE` - * * `FsRequest::Type::UTIME` - * * `FsRequest::Type::FUTIME` - * * `FsRequest::Type::ACCESS` - * * `FsRequest::Type::CHMOD` - * * `FsRequest::Type::FCHMOD` - * * `FsRequest::Type::FSYNC` - * * `FsRequest::Type::FDATASYNC` - * * `FsRequest::Type::UNLINK` - * * `FsRequest::Type::RMDIR` - * * `FsRequest::Type::MKDIR` - * * `FsRequest::Type::MKDTEMP` - * * `FsRequest::Type::RENAME` - * * `FsRequest::Type::SCANDIR` - * * `FsRequest::Type::LINK` - * * `FsRequest::Type::SYMLINK` - * * `FsRequest::Type::READLINK` - * * `FsRequest::Type::CHOWN` - * * `FsRequest::Type::FCHOWN` - * * `FsRequest::Type::REALPATH` - * * `FsRequest::Type::COPYFILE` - * * `FsRequest::Type::LCHOWN` - * * `FsRequest::Type::OPENDIR` - * * `FsRequest::Type::READDIR` - * * `FsRequest::Type::CLOSEDIR` - * * `FsRequest::Type::STATFS` - * * `FsRequest::Type::MKSTEMP` - * * `FsRequest::Type::LUTIME` - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. + * * `fs_request::fs_type::UNKNOWN` + * * `fs_request::fs_type::CUSTOM` + * * `fs_request::fs_type::OPEN` + * * `fs_request::fs_type::CLOSE` + * * `fs_request::fs_type::READ` + * * `fs_request::fs_type::WRITE` + * * `fs_request::fs_type::SENDFILE` + * * `fs_request::fs_type::STAT` + * * `fs_request::fs_type::LSTAT` + * * `fs_request::fs_type::FSTAT` + * * `fs_request::fs_type::FTRUNCATE` + * * `fs_request::fs_type::UTIME` + * * `fs_request::fs_type::FUTIME` + * * `fs_request::fs_type::ACCESS` + * * `fs_request::fs_type::CHMOD` + * * `fs_request::fs_type::FCHMOD` + * * `fs_request::fs_type::FSYNC` + * * `fs_request::fs_type::FDATASYNC` + * * `fs_request::fs_type::UNLINK` + * * `fs_request::fs_type::RMDIR` + * * `fs_request::fs_type::MKDIR` + * * `fs_request::fs_type::MKDTEMP` + * * `fs_request::fs_type::RENAME` + * * `fs_request::fs_type::SCANDIR` + * * `fs_request::fs_type::LINK` + * * `fs_request::fs_type::SYMLINK` + * * `fs_request::fs_type::READLINK` + * * `fs_request::fs_type::CHOWN` + * * `fs_request::fs_type::FCHOWN` + * * `fs_request::fs_type::REALPATH` + * * `fs_request::fs_type::COPYFILE` + * * `fs_request::fs_type::LCHOWN` + * * `fs_request::fs_type::OPENDIR` + * * `fs_request::fs_type::READDIR` + * * `fs_request::fs_type::CLOSEDIR` + * * `fs_request::fs_type::STATFS` + * * `fs_request::fs_type::MKSTEMP` + * * `fs_request::fs_type::LUTIME` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs.html#c.uv_fs_type) * for further details. */ -template -struct FsEvent { - FsEvent(const char *pathname) noexcept - : path{pathname} {} +struct fs_event { + using fs_type = details::uvw_fs_type; + using entry_type = details::uvw_dirent_type_t; - const char *path; /*!< The path affecting the request. */ + fs_event(const uv_fs_t &req, std::unique_ptr data) + : fs_event{req} { + read.data = std::move(data); + } + + fs_event(const uv_fs_t &req) + : type{req.fs_type}, + path{req.path}, + result{static_cast(req.result)} { + switch(type) { + case fs_type::STAT: + case fs_type::LSTAT: + case fs_type::FSTAT: + stat = *static_cast(req.ptr); + break; + case fs_type::READLINK: + readlink.data = static_cast(req.ptr); + break; + case fs_type::READDIR: + dirent.name = static_cast(req.ptr)->dirents[0].name; + dirent.type = static_cast(static_cast(req.ptr)->dirents[0].type); + dirent.eos = !req.result; + break; + case fs_type::STATFS: + statfs = *static_cast(req.ptr); + break; + default: + // nothing to do here + break; + } + } + + fs_type type; /*!< Actual event type. */ + const char *path; /*!< The path affecting the request. */ + std::size_t result; /*!< Result value for the specific type. */ + + struct { + std::unique_ptr data; /*!< A bunch of data read from the given path. */ + } read; + + struct { + const char *data; /*!< The content of a symbolic link. */ + } readlink; + + file_info stat; /*!< An initialized instance of file_info. */ + fs_info statfs; /*!< An initialized instance of fs_info. */ + + struct { + const char *name; /*!< The name of the last entry. */ + entry_type type; /*!< The entry type. */ + bool eos; /*!< True if there a no more entries to read. */ + } dirent; }; /** - * @brief FsEvent event specialization for `FsRequest::Type::READ`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - FsEvent(const char *pathname, std::unique_ptr buf, std::size_t sz) noexcept - : path{pathname}, data{std::move(buf)}, size{sz} {} - - const char *path; /*!< The path affecting the request. */ - std::unique_ptr data; /*!< A bunch of data read from the given path. */ - std::size_t size; /*!< The amount of data read from the given path. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::WRITE`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - FsEvent(const char *pathname, std::size_t sz) noexcept - : path{pathname}, size{sz} {} - - const char *path; /*!< The path affecting the request. */ - std::size_t size; /*!< The amount of data written to the given path. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::SENDFILE`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - FsEvent(const char *pathname, std::size_t sz) noexcept - : path{pathname}, size{sz} {} - - const char *path; /*!< The path affecting the request. */ - std::size_t size; /*!< The amount of data transferred. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::STAT`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - FsEvent(const char *pathname, Stat curr) noexcept - : path{pathname}, stat{std::move(curr)} {} - - const char *path; /*!< The path affecting the request. */ - Stat stat; /*!< An initialized instance of Stat. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::FSTAT`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - FsEvent(const char *pathname, Stat curr) noexcept - : path{pathname}, stat{std::move(curr)} {} - - const char *path; /*!< The path affecting the request. */ - Stat stat; /*!< An initialized instance of Stat. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::LSTAT`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - FsEvent(const char *pathname, Stat curr) noexcept - : path{pathname}, stat{std::move(curr)} {} - - const char *path; /*!< The path affecting the request. */ - Stat stat; /*!< An initialized instance of Stat. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::STATFS`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - FsEvent(const char *pathname, Statfs curr) noexcept - : path{pathname}, statfs{std::move(curr)} {} - - const char *path; /*!< The path affecting the request. */ - Statfs statfs; /*!< An initialized instance of Statfs. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::MKSTEMP`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - FsEvent(const char *pathname, std::size_t desc) noexcept - : path{pathname}, descriptor{desc} {} - - const char *path; /*!< The created file path. */ - std::size_t descriptor; /*!< The file descriptor as an integer. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::SCANDIR`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - FsEvent(const char *pathname, std::size_t sz) noexcept - : path{pathname}, size{sz} {} - - const char *path; /*!< The path affecting the request. */ - std::size_t size; /*!< The number of directory entries selected. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::READLINK`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - explicit FsEvent(const char *pathname, const char *buf, std::size_t sz) noexcept - : path{pathname}, data{buf}, size{sz} {} - - const char *path; /*!< The path affecting the request. */ - const char *data; /*!< A bunch of data read from the given path. */ - std::size_t size; /*!< The amount of data read from the given path. */ -}; - -/** - * @brief FsEvent event specialization for `FsRequest::Type::READDIR`. - * - * It will be emitted by FsReq and/or FileReq according with their - * functionalities. - */ -template<> -struct FsEvent { - using EntryType = details::UVDirentTypeT; - - FsEvent(const char *name, EntryType type, bool eos) noexcept - : name{name}, type{type}, eos{eos} {} - - const char *name; /*!< The name of the last entry. */ - EntryType type; /*!< The entry type. */ - bool eos; /*!< True if there a no more entries to read. */ -}; - -/** - * @brief Base class for FsReq and/or FileReq. + * @brief Base class for fs/file request. * * Not directly instantiable, should not be used by the users of the library. */ template -class FsRequest: public Request { +class fs_request: public request { protected: - template - static void fsGenericCallback(uv_fs_t *req) { - if(auto ptr = Request::reserve(req); req->result < 0) { - ptr->publish(ErrorEvent{req->result}); + static void fs_request_callback(uv_fs_t *req) { + if(auto ptr = request::reserve(req); req->result < 0) { + ptr->publish(error_event{req->result}); } else { - ptr->publish(FsEvent{req->path}); + ptr->publish(fs_event{*req}); } } - template - static void fsResultCallback(uv_fs_t *req) { - if(auto ptr = Request::reserve(req); req->result < 0) { - ptr->publish(ErrorEvent{req->result}); - } else { - ptr->publish(FsEvent{req->path, static_cast(req->result)}); - } - } - - template - static void fsStatCallback(uv_fs_t *req) { - if(auto ptr = Request::reserve(req); req->result < 0) { - ptr->publish(ErrorEvent{req->result}); - } else { - ptr->publish(FsEvent{req->path, req->statbuf}); - } - } - - static void fsStatfsCallback(uv_fs_t *req) { - if(auto ptr = Request::reserve(req); req->result < 0) { - ptr->publish(ErrorEvent{req->result}); - } else { - ptr->publish(FsEvent{req->path, *static_cast(req->ptr)}); - } - } - - template - void cleanupAndInvoke(Args &&...args) { - uv_fs_req_cleanup(this->get()); - this->invoke(std::forward(args)...); - } - - template - void cleanupAndInvokeSync(F &&f, Args &&...args) { - uv_fs_req_cleanup(this->get()); - std::forward(f)(std::forward(args)..., nullptr); - } - public: - using Time = std::chrono::duration; - using Type = details::UVFsType; - using EntryType = details::UVDirentTypeT; + using time = std::chrono::duration; + using fs_type = details::uvw_fs_type; + using entry_type = details::uvw_dirent_type_t; - using Request::Request; + using request::request; }; /** - * @brief The FileReq request. + * @brief The file request. * * Cross-platform sync and async filesystem operations.
* All file operations are run on the threadpool. * - * To create a `FileReq` through a `Loop`, no arguments are required. + * To create a `file_req` through a `loop`, no arguments are required. * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs.html) * for further details. */ -class FileReq final: public FsRequest { +class file_req final: public fs_request { static constexpr uv_file BAD_FD = -1; - static void fsOpenCallback(uv_fs_t *req); - static void fsCloseCallback(uv_fs_t *req); - static void fsReadCallback(uv_fs_t *req); + static void fs_open_callback(uv_fs_t *req); + static void fs_close_callback(uv_fs_t *req); + static void fs_read_callback(uv_fs_t *req); public: - using FileOpen = details::UVFileOpenFlags; + using file_open_flags = details::uvw_file_open_flags; - using FsRequest::FsRequest; + using fs_request::fs_request; - ~FileReq() noexcept; + ~file_req() noexcept; /** * @brief Async [close](http://linux.die.net/man/2/close). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. */ void close(); @@ -434,38 +276,37 @@ public: * @brief Sync [close](http://linux.die.net/man/2/close). * @return True in case of success, false otherwise. */ - bool closeSync(); + bool close_sync(); /** * @brief Async [open](http://linux.die.net/man/2/open). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * Available flags are: * - * * `FileReq::FileOpen::APPEND` - * * `FileReq::FileOpen::CREAT` - * * `FileReq::FileOpen::DIRECT` - * * `FileReq::FileOpen::DIRECTORY` - * * `FileReq::FileOpen::DSYNC` - * * `FileReq::FileOpen::EXCL` - * * `FileReq::FileOpen::EXLOCK` - * * `FileReq::FileOpen::FILEMAP` - * * `FileReq::FileOpen::NOATIME` - * * `FileReq::FileOpen::NOCTTY` - * * `FileReq::FileOpen::NOFOLLOW` - * * `FileReq::FileOpen::NONBLOCK` - * * `FileReq::FileOpen::RANDOM` - * * `FileReq::FileOpen::RDONLY` - * * `FileReq::FileOpen::RDWR` - * * `FileReq::FileOpen::SEQUENTIAL` - * * `FileReq::FileOpen::SHORT_LIVED` - * * `FileReq::FileOpen::SYMLINK` - * * `FileReq::FileOpen::SYNC` - * * `FileReq::FileOpen::TEMPORARY` - * * `FileReq::FileOpen::TRUNC` - * * `FileReq::FileOpen::WRONLY` + * * `file_req::file_open_flags::APPEND` + * * `file_req::file_open_flags::CREAT` + * * `file_req::file_open_flags::DIRECT` + * * `file_req::file_open_flags::DIRECTORY` + * * `file_req::file_open_flags::DSYNC` + * * `file_req::file_open_flags::EXCL` + * * `file_req::file_open_flags::EXLOCK` + * * `file_req::file_open_flags::FILEMAP` + * * `file_req::file_open_flags::NOATIME` + * * `file_req::file_open_flags::NOCTTY` + * * `file_req::file_open_flags::NOFOLLOW` + * * `file_req::file_open_flags::NONBLOCK` + * * `file_req::file_open_flags::RANDOM` + * * `file_req::file_open_flags::RDONLY` + * * `file_req::file_open_flags::RDWR` + * * `file_req::file_open_flags::SEQUENTIAL` + * * `file_req::file_open_flags::SHORT_LIVED` + * * `file_req::file_open_flags::SYMLINK` + * * `file_req::file_open_flags::SYNC` + * * `file_req::file_open_flags::TEMPORARY` + * * `file_req::file_open_flags::TRUNC` + * * `file_req::file_open_flags::WRONLY` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs.html#file-open-constants) @@ -475,35 +316,35 @@ public: * @param flags Flags made out of underlying constants. * @param mode Mode, as described in the official documentation. */ - void open(const std::string &path, Flags flags, int mode); + void open(const std::string &path, file_open_flags flags, int mode); /** * @brief Sync [open](http://linux.die.net/man/2/open). * * Available flags are: * - * * `FileReq::FileOpen::APPEND` - * * `FileReq::FileOpen::CREAT` - * * `FileReq::FileOpen::DIRECT` - * * `FileReq::FileOpen::DIRECTORY` - * * `FileReq::FileOpen::DSYNC` - * * `FileReq::FileOpen::EXCL` - * * `FileReq::FileOpen::EXLOCK` - * * `FileReq::FileOpen::FILEMAP` - * * `FileReq::FileOpen::NOATIME` - * * `FileReq::FileOpen::NOCTTY` - * * `FileReq::FileOpen::NOFOLLOW` - * * `FileReq::FileOpen::NONBLOCK` - * * `FileReq::FileOpen::RANDOM` - * * `FileReq::FileOpen::RDONLY` - * * `FileReq::FileOpen::RDWR` - * * `FileReq::FileOpen::SEQUENTIAL` - * * `FileReq::FileOpen::SHORT_LIVED` - * * `FileReq::FileOpen::SYMLINK` - * * `FileReq::FileOpen::SYNC` - * * `FileReq::FileOpen::TEMPORARY` - * * `FileReq::FileOpen::TRUNC` - * * `FileReq::FileOpen::WRONLY` + * * `file_req::file_open_flags::APPEND` + * * `file_req::file_open_flags::CREAT` + * * `file_req::file_open_flags::DIRECT` + * * `file_req::file_open_flags::DIRECTORY` + * * `file_req::file_open_flags::DSYNC` + * * `file_req::file_open_flags::EXCL` + * * `file_req::file_open_flags::EXLOCK` + * * `file_req::file_open_flags::FILEMAP` + * * `file_req::file_open_flags::NOATIME` + * * `file_req::file_open_flags::NOCTTY` + * * `file_req::file_open_flags::NOFOLLOW` + * * `file_req::file_open_flags::NONBLOCK` + * * `file_req::file_open_flags::RANDOM` + * * `file_req::file_open_flags::RDONLY` + * * `file_req::file_open_flags::RDWR` + * * `file_req::file_open_flags::SEQUENTIAL` + * * `file_req::file_open_flags::SHORT_LIVED` + * * `file_req::file_open_flags::SYMLINK` + * * `file_req::file_open_flags::SYNC` + * * `file_req::file_open_flags::TEMPORARY` + * * `file_req::file_open_flags::TRUNC` + * * `file_req::file_open_flags::WRONLY` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs.html#file-open-constants) @@ -514,13 +355,12 @@ public: * @param mode Mode, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool openSync(const std::string &path, Flags flags, int mode); + bool open_sync(const std::string &path, file_open_flags flags, int mode); /** * @brief Async [read](http://linux.die.net/man/2/preadv). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param offset Offset, as described in the official documentation. * @param len Length, as described in the official documentation. @@ -539,7 +379,7 @@ public: * * A bunch of data read from the given path. * * The amount of data read from the given path. */ - std::pair, std::size_t>> readSync(int64_t offset, unsigned int len); + std::pair, std::size_t>> read_sync(int64_t offset, unsigned int len); /** * @brief Async [write](http://linux.die.net/man/2/pwritev). @@ -547,8 +387,7 @@ public: * The request takes the ownership of the data and it is in charge of delete * them. * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param buf The data to be written. * @param len The lenght of the submitted data. @@ -562,8 +401,7 @@ public: * The request doesn't take the ownership of the data. Be sure that their * lifetime overcome the one of the request. * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param buf The data to be written. * @param len The lenght of the submitted data. @@ -582,13 +420,12 @@ public: * * A boolean value that is true in case of success, false otherwise. * * The amount of data written to the given path. */ - std::pair writeSync(std::unique_ptr buf, unsigned int len, int64_t offset); + std::pair write_sync(std::unique_ptr buf, unsigned int len, int64_t offset); /** * @brief Async [fstat](http://linux.die.net/man/2/fstat). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. */ void stat(); @@ -597,15 +434,14 @@ public: * * @return A `std::pair` composed as it follows: * * A boolean value that is true in case of success, false otherwise. - * * An initialized instance of Stat. + * * An initialized instance of file_info. */ - std::pair statSync(); + std::pair stat_sync(); /** * @brief Async [fsync](http://linux.die.net/man/2/fsync). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. */ void sync(); @@ -613,13 +449,12 @@ public: * @brief Sync [fsync](http://linux.die.net/man/2/fsync). * @return True in case of success, false otherwise. */ - bool syncSync(); + bool sync_sync(); /** * @brief Async [fdatasync](http://linux.die.net/man/2/fdatasync). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. */ void datasync(); @@ -627,13 +462,12 @@ public: * @brief Sync [fdatasync](http://linux.die.net/man/2/fdatasync). * @return True in case of success, false otherwise. */ - bool datasyncSync(); + bool datasync_sync(); /** * @brief Async [ftruncate](http://linux.die.net/man/2/ftruncate). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param offset Offset, as described in the official documentation. */ @@ -644,24 +478,23 @@ public: * @param offset Offset, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool truncateSync(int64_t offset); + bool truncate_sync(int64_t offset); /** * @brief Async [sendfile](http://linux.die.net/man/2/sendfile). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * - * @param out A valid instance of FileHandle. + * @param out A valid instance of file_handle. * @param offset Offset, as described in the official documentation. * @param length Length, as described in the official documentation. */ - void sendfile(FileHandle out, int64_t offset, std::size_t length); + void sendfile(file_handle out, int64_t offset, std::size_t length); /** * @brief Sync [sendfile](http://linux.die.net/man/2/sendfile). * - * @param out A valid instance of FileHandle. + * @param out A valid instance of file_handle. * @param offset Offset, as described in the official documentation. * @param length Length, as described in the official documentation. * @@ -669,13 +502,12 @@ public: * * A boolean value that is true in case of success, false otherwise. * * The amount of data transferred. */ - std::pair sendfileSync(FileHandle out, int64_t offset, std::size_t length); + std::pair sendfile_sync(file_handle out, int64_t offset, std::size_t length); /** * @brief Async [fchmod](http://linux.die.net/man/2/fchmod). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param mode Mode, as described in the official documentation. */ @@ -686,20 +518,19 @@ public: * @param mode Mode, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool chmodSync(int mode); + bool chmod_sync(int mode); /** * @brief Async [futime](http://linux.die.net/man/3/futimes). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param atime `std::chrono::duration`, having the same meaning as * described in the official documentation. * @param mtime `std::chrono::duration`, having the same meaning as * described in the official documentation. */ - void futime(Time atime, Time mtime); + void futime(time atime, time mtime); /** * @brief Sync [futime](http://linux.die.net/man/3/futimes). @@ -709,18 +540,17 @@ public: * described in the official documentation. * @return True in case of success, false otherwise. */ - bool futimeSync(Time atime, Time mtime); + bool futime_sync(time atime, time mtime); /** * @brief Async [fchown](http://linux.die.net/man/2/fchown). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param uid UID, as described in the official documentation. * @param gid GID, as described in the official documentation. */ - void chown(Uid uid, Gid gid); + void chown(uid_type uid, gid_type gid); /** * @brief Sync [fchown](http://linux.die.net/man/2/fchown). @@ -728,17 +558,17 @@ public: * @param gid GID, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool chownSync(Uid uid, Gid gid); + bool chown_sync(uid_type uid, gid_type gid); /** - * @brief Cast operator to FileHandle. + * @brief Cast operator to file_handle. * * Cast operator to an internal representation of the underlying file * handle. * - * @return A valid instance of FileHandle (the descriptor can be invalid). + * @return A valid instance of file_handle (the descriptor can be invalid). */ - operator FileHandle() const noexcept; + operator file_handle() const noexcept; private: std::unique_ptr current{nullptr}; @@ -747,34 +577,30 @@ private: }; /** - * @brief The FsReq request. + * @brief The fs request. * * Cross-platform sync and async filesystem operations.
* All file operations are run on the threadpool. * - * To create a `FsReq` through a `Loop`, no arguments are required. + * To create a `fs_req` through a `loop`, no arguments are required. * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs.html) * for further details. */ -class FsReq final: public FsRequest { - static void fsReadlinkCallback(uv_fs_t *req); - static void fsReaddirCallback(uv_fs_t *req); - +class fs_req final: public fs_request { public: - using CopyFile = details::UVCopyFileFlags; - using SymLink = details::UVSymLinkFlags; + using copy_file_flags = details::uvw_copy_file_flags; + using symlink_flags = details::uvw_symlink_flags; - using FsRequest::FsRequest; + using fs_request::fs_request; - ~FsReq() noexcept; + ~fs_req() noexcept; /** * @brief Async [unlink](http://linux.die.net/man/2/unlink). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. */ @@ -785,13 +611,12 @@ public: * @param path Path, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool unlinkSync(const std::string &path); + bool unlink_sync(const std::string &path); /** * @brief Async [mkdir](http://linux.die.net/man/2/mkdir). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. * @param mode Mode, as described in the official documentation. @@ -804,13 +629,12 @@ public: * @param mode Mode, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool mkdirSync(const std::string &path, int mode); + bool mkdir_sync(const std::string &path, int mode); /** * @brief Async [mktemp](http://linux.die.net/man/3/mkdtemp). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param tpl Template, as described in the official documentation. */ @@ -825,13 +649,12 @@ public: * * A boolean value that is true in case of success, false otherwise. * * The actual path of the newly created directory. */ - std::pair mkdtempSync(const std::string &tpl); + std::pair mkdtemp_sync(const std::string &tpl); /** * @brief Async [mkstemp](https://linux.die.net/man/3/mkstemp). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param tpl Template, as described in the official documentation. */ @@ -857,13 +680,12 @@ public: * false otherwise. * * The second parameter is a composed value (see above). */ - std::pair> mkstempSync(const std::string &tpl); + std::pair> mkstemp_sync(const std::string &tpl); /** * @brief Async [lutime](http://linux.die.net/man/3/lutimes). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. * @param atime `std::chrono::duration`, having the same meaning as @@ -871,7 +693,7 @@ public: * @param mtime `std::chrono::duration`, having the same meaning as * described in the official documentation. */ - void lutime(const std::string &path, Time atime, Time mtime); + void lutime(const std::string &path, time atime, time mtime); /** * @brief Sync [lutime](http://linux.die.net/man/3/lutimes). @@ -882,13 +704,12 @@ public: * described in the official documentation. * @return True in case of success, false otherwise. */ - bool lutimeSync(const std::string &path, Time atime, Time mtime); + bool lutime_sync(const std::string &path, time atime, time mtime); /** * @brief Async [rmdir](http://linux.die.net/man/2/rmdir). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. */ @@ -899,13 +720,12 @@ public: * @param path Path, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool rmdirSync(const std::string &path); + bool rmdir_sync(const std::string &path); /** * @brief Async [scandir](http://linux.die.net/man/3/scandir). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. * @param flags Flags, as described in the official documentation. @@ -922,7 +742,7 @@ public: * * A boolean value that is true in case of success, false otherwise. * * The number of directory entries selected. */ - std::pair scandirSync(const std::string &path, int flags); + std::pair scandir_sync(const std::string &path, int flags); /** * @brief Gets entries populated with the next directory entry data. @@ -934,14 +754,14 @@ public: * * Available entry types are: * - * * `FsReq::EntryType::UNKNOWN` - * * `FsReq::EntryType::FILE` - * * `FsReq::EntryType::DIR` - * * `FsReq::EntryType::LINK` - * * `FsReq::EntryType::FIFO` - * * `FsReq::EntryType::SOCKET` - * * `FsReq::EntryType::CHAR` - * * `FsReq::EntryType::BLOCK` + * * `fs_req::entry_type::UNKNOWN` + * * `fs_req::entry_type::FILE` + * * `fs_req::entry_type::DIR` + * * `fs_req::entry_type::LINK` + * * `fs_req::entry_type::FIFO` + * * `fs_req::entry_type::SOCKET` + * * `fs_req::entry_type::CHAR` + * * `fs_req::entry_type::BLOCK` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs.html#c.uv_dirent_t) @@ -953,13 +773,12 @@ public: * entry is still valid. * * The second parameter is a composed value (see above). */ - std::pair> scandirNext(); + std::pair> scandir_next(); /** * @brief Async [stat](http://linux.die.net/man/2/stat). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. */ @@ -972,15 +791,14 @@ public: * * @return A `std::pair` composed as it follows: * * A boolean value that is true in case of success, false otherwise. - * * An initialized instance of Stat. + * * An initialized instance of file_info. */ - std::pair statSync(const std::string &path); + std::pair stat_sync(const std::string &path); /** * @brief Async [lstat](http://linux.die.net/man/2/lstat). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. */ @@ -993,15 +811,14 @@ public: * * @return A `std::pair` composed as it follows: * * A boolean value that is true in case of success, false otherwise. - * * An initialized instance of Stat. + * * An initialized instance of file_info. */ - std::pair lstatSync(const std::string &path); + std::pair lstat_sync(const std::string &path); /** * @brief Async [statfs](http://linux.die.net/man/2/statfs). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * Any fields in the resulting object that are not supported by the * underlying operating system are set to zero. @@ -1020,15 +837,14 @@ public: * * @return A `std::pair` composed as it follows: * * A boolean value that is true in case of success, false otherwise. - * * An initialized instance of Statfs. + * * An initialized instance of fs_info. */ - std::pair statfsSync(const std::string &path); + std::pair statfs_sync(const std::string &path); /** * @brief Async [rename](http://linux.die.net/man/2/rename). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param old Old path, as described in the official documentation. * @param path New path, as described in the official documentation. @@ -1041,26 +857,24 @@ public: * @param path New path, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool renameSync(const std::string &old, const std::string &path); + bool rename_sync(const std::string &old, const std::string &path); /** * @brief Copies a file asynchronously from a path to a new one. * - * Emit a `FsEvent` event when - * completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * Available flags are: * - * * `FsReq::CopyFile::EXCL`: it fails if the destination path + * * `fs_req::copy_file_flags::EXCL`: it fails if the destination path * already exists (the default behavior is to overwrite the destination if * it exists). - * * `FsReq::CopyFile::FICLONE`: If present, it will attempt to create a - * copy-on-write reflink. If the underlying platform does not support - * copy-on-write, then a fallback copy mechanism is used. - * * `FsReq::CopyFile::FICLONE_FORCE`: If present, it will attempt to create - * a copy-on-write reflink. If the underlying platform does not support - * copy-on-write, then an error is returned. + * * `fs_req::copy_file_flags::FICLONE`: If present, it will attempt to + * create a copy-on-write reflink. If the underlying platform does not + * support copy-on-write, then a fallback copy mechanism is used. + * * `fs_req::copy_file_flags::FICLONE_FORCE`: If present, it will attempt + * to create a copy-on-write reflink. If the underlying platform does not + * support copy-on-write, then an error is returned. * * @warning * If the destination path is created, but an error occurs while copying the @@ -1072,14 +886,14 @@ public: * @param path New path, as described in the official documentation. * @param flags Optional additional flags. */ - void copyfile(const std::string &old, const std::string &path, Flags flags = Flags{}); + void copyfile(const std::string &old, const std::string &path, copy_file_flags flags = copy_file_flags::_UVW_ENUM); /** * @brief Copies a file synchronously from a path to a new one. * * Available flags are: * - * * `FsReq::CopyFile::EXCL`: it fails if the destination path + * * `fs_req::copy_file_flags::EXCL`: it fails if the destination path * already exists (the default behavior is to overwrite the destination if * it exists). * @@ -1093,13 +907,12 @@ public: * @param flags Optional additional flags. * @return True in case of success, false otherwise. */ - bool copyfileSync(const std::string &old, const std::string &path, Flags flags = Flags{}); + bool copyfile_sync(const std::string &old, const std::string &path, copy_file_flags flags = copy_file_flags::_UVW_ENUM); /** * @brief Async [access](http://linux.die.net/man/2/access). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. * @param mode Mode, as described in the official documentation. @@ -1112,13 +925,12 @@ public: * @param mode Mode, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool accessSync(const std::string &path, int mode); + bool access_sync(const std::string &path, int mode); /** * @brief Async [chmod](http://linux.die.net/man/2/chmod). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. * @param mode Mode, as described in the official documentation. @@ -1131,13 +943,12 @@ public: * @param mode Mode, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool chmodSync(const std::string &path, int mode); + bool chmod_sync(const std::string &path, int mode); /** * @brief Async [utime](http://linux.die.net/man/2/utime). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. * @param atime `std::chrono::duration`, having the same meaning as @@ -1145,7 +956,7 @@ public: * @param mtime `std::chrono::duration`, having the same meaning as * described in the official documentation. */ - void utime(const std::string &path, Time atime, Time mtime); + void utime(const std::string &path, time atime, time mtime); /** * @brief Sync [utime](http://linux.die.net/man/2/utime). @@ -1156,13 +967,12 @@ public: * described in the official documentation. * @return True in case of success, false otherwise. */ - bool utimeSync(const std::string &path, Time atime, Time mtime); + bool utime_sync(const std::string &path, time atime, time mtime); /** * @brief Async [link](http://linux.die.net/man/2/link). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param old Old path, as described in the official documentation. * @param path New path, as described in the official documentation. @@ -1175,49 +985,47 @@ public: * @param path New path, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool linkSync(const std::string &old, const std::string &path); + bool link_sync(const std::string &old, const std::string &path); /** * @brief Async [symlink](http://linux.die.net/man/2/symlink). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * Available flags are: * - * * `FsReq::SymLink::DIR`: it indicates that the old path points to a - * directory. - * * `FsReq::SymLink::JUNCTION`: it requests that the symlink is created - * using junction points. + * * `fs_req::symlink_flags::DIR`: it indicates that the old path points to + * a directory. + * * `fs_req::symlink_flags::JUNCTION`: it requests that the symlink is + * created using junction points. * * @param old Old path, as described in the official documentation. * @param path New path, as described in the official documentation. * @param flags Optional additional flags. */ - void symlink(const std::string &old, const std::string &path, Flags flags = Flags{}); + void symlink(const std::string &old, const std::string &path, symlink_flags flags = symlink_flags::_UVW_ENUM); /** * @brief Sync [symlink](http://linux.die.net/man/2/symlink). * * Available flags are: * - * * `FsReq::SymLink::DIR`: it indicates that the old path points to a - * directory. - * * `FsReq::SymLink::JUNCTION`: it requests that the symlink is created - * using junction points. + * * `fs_req::symlink_flags::DIR`: it indicates that the old path points to + * a directory. + * * `fs_req::symlink_flags::JUNCTION`: it requests that the symlink is + * created using junction points. * * @param old Old path, as described in the official documentation. * @param path New path, as described in the official documentation. * @param flags Flags, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool symlinkSync(const std::string &old, const std::string &path, Flags flags = Flags{}); + bool symlink_sync(const std::string &old, const std::string &path, symlink_flags flags = symlink_flags::_UVW_ENUM); /** * @brief Async [readlink](http://linux.die.net/man/2/readlink). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. */ @@ -1234,13 +1042,12 @@ public: * * A bunch of data read from the given path. * * The amount of data read from the given path. */ - std::pair> readlinkSync(const std::string &path); + std::pair> readlink_sync(const std::string &path); /** * @brief Async [realpath](http://linux.die.net/man/3/realpath). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. */ @@ -1255,19 +1062,18 @@ public: * * A boolean value that is true in case of success, false otherwise. * * The canonicalized absolute pathname. */ - std::pair realpathSync(const std::string &path); + std::pair realpath_sync(const std::string &path); /** * @brief Async [chown](http://linux.die.net/man/2/chown). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. * @param uid UID, as described in the official documentation. * @param gid GID, as described in the official documentation. */ - void chown(const std::string &path, Uid uid, Gid gid); + void chown(const std::string &path, uid_type uid, gid_type gid); /** * @brief Sync [chown](http://linux.die.net/man/2/chown). @@ -1276,19 +1082,18 @@ public: * @param gid GID, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool chownSync(const std::string &path, Uid uid, Gid gid); + bool chown_sync(const std::string &path, uid_type uid, gid_type gid); /** * @brief Async [lchown](https://linux.die.net/man/2/lchown). * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * @param path Path, as described in the official documentation. * @param uid UID, as described in the official documentation. * @param gid GID, as described in the official documentation. */ - void lchown(const std::string &path, Uid uid, Gid gid); + void lchown(const std::string &path, uid_type uid, gid_type gid); /** * @brief Sync [lchown](https://linux.die.net/man/2/lchown). @@ -1297,17 +1102,16 @@ public: * @param gid GID, as described in the official documentation. * @return True in case of success, false otherwise. */ - bool lchownSync(const std::string &path, Uid uid, Gid gid); + bool lchown_sync(const std::string &path, uid_type uid, gid_type gid); /** * @brief Opens a path asynchronously as a directory stream. * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * The contents of the directory can be iterated over by means of the - * `readdir` od `readdirSync` member functions. The memory allocated by this - * function must be freed by calling `closedir` or `closedirSync`. + * `readdir` od `readdir_sync` member functions. The memory allocated by + * this function must be freed by calling `closedir` or `closedir_sync`. * * @param path The path to open as a directory stream. */ @@ -1317,19 +1121,18 @@ public: * @brief Opens a path synchronously as a directory stream. * * The contents of the directory can be iterated over by means of the - * `readdir` od `readdirSync` member functions. The memory allocated by this - * function must be freed by calling `closedir` or `closedirSync`. + * `readdir` od `readdir_sync` member functions. The memory allocated by + * this function must be freed by calling `closedir` or `closedir_sync`. * * @param path The path to open as a directory stream. * @return True in case of success, false otherwise. */ - bool opendirSync(const std::string &path); + bool opendir_sync(const std::string &path); /** * @brief Closes asynchronously a directory stream. * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * It frees also the memory allocated internally when a path has been opened * as a directory stream. @@ -1344,14 +1147,13 @@ public: * * @return True in case of success, false otherwise. */ - bool closedirSync(); + bool closedir_sync(); /** * @brief Iterates asynchronously over a directory stream one entry at a * time. * - * Emit a `FsEvent` event when completed.
- * Emit an ErrorEvent event in case of errors. + * Emit a `fs_event` event when completed. * * This function isn't thread safe. Moreover, it doesn't return the `.` and * `..` entries. @@ -1369,14 +1171,14 @@ public: * * Available entry types are: * - * * `FsReq::EntryType::UNKNOWN` - * * `FsReq::EntryType::FILE` - * * `FsReq::EntryType::DIR` - * * `FsReq::EntryType::LINK` - * * `FsReq::EntryType::FIFO` - * * `FsReq::EntryType::SOCKET` - * * `FsReq::EntryType::CHAR` - * * `FsReq::EntryType::BLOCK` + * * `fs_req::entry_type::UNKNOWN` + * * `fs_req::entry_type::FILE` + * * `fs_req::entry_type::DIR` + * * `fs_req::entry_type::LINK` + * * `fs_req::entry_type::FIFO` + * * `fs_req::entry_type::SOCKET` + * * `fs_req::entry_type::CHAR` + * * `fs_req::entry_type::BLOCK` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs.html#c.uv_dirent_t) @@ -1391,14 +1193,14 @@ public: * entry is still valid. * * The second parameter is a composed value (see above). */ - std::pair> readdirSync(); + std::pair> readdir_sync(); private: uv_dirent_t dirents[1]; }; /*! @brief Helper functions. */ -struct FsHelper { +struct fs_helper { /** * @brief Gets the OS dependent handle. * @@ -1409,7 +1211,7 @@ struct FsHelper { * to close it or to use it after closing the file descriptor may lead to * malfunction. */ - static OSFileDescriptor handle(FileHandle file) noexcept; + static os_file_descriptor handle(file_handle file) noexcept; /** * @brief Gets the file descriptor. @@ -1421,7 +1223,7 @@ struct FsHelper { * to close it or to use it after closing the handle may lead to * malfunction. */ - static FileHandle open(OSFileDescriptor descriptor) noexcept; + static file_handle open(os_file_descriptor descriptor) noexcept; }; } // namespace uvw diff --git a/src/uvw/fs_event.cpp b/src/uvw/fs_event.cpp index e26d5397..19a25743 100644 --- a/src/uvw/fs_event.cpp +++ b/src/uvw/fs_event.cpp @@ -7,37 +7,31 @@ namespace uvw { -UVW_INLINE FsEventEvent::FsEventEvent(const char *pathname, Flags events) +UVW_INLINE fs_event_event::fs_event_event(const char *pathname, details::uvw_fs_event events) : filename{pathname}, flags{std::move(events)} {} -UVW_INLINE void FsEventHandle::startCallback(uv_fs_event_t *handle, const char *filename, int events, int status) { - FsEventHandle &fsEvent = *(static_cast(handle->data)); - - if(status) { - fsEvent.publish(ErrorEvent{status}); +UVW_INLINE void fs_event_handle::start_callback(uv_fs_event_t *hndl, const char *filename, int events, int status) { + if(fs_event_handle &fsEvent = *(static_cast(hndl->data)); status) { + fsEvent.publish(error_event{status}); } else { - fsEvent.publish(FsEventEvent{filename, static_cast>(events)}); + fsEvent.publish(fs_event_event{filename, details::uvw_fs_event(events)}); } } -UVW_INLINE bool FsEventHandle::init() { - return initialize(&uv_fs_event_init); +UVW_INLINE int fs_event_handle::init() { + return leak_if(uv_fs_event_init(parent().raw(), raw())); } -UVW_INLINE void FsEventHandle::start(const std::string &path, Flags flags) { - invoke(&uv_fs_event_start, get(), &startCallback, path.data(), flags); +UVW_INLINE int fs_event_handle::start(const std::string &path, event_flags flags) { + return uv_fs_event_start(raw(), &start_callback, path.data(), static_cast(flags)); } -UVW_INLINE void FsEventHandle::start(const std::string &path, FsEventHandle::Event flag) { - start(std::move(path), Flags{flag}); +UVW_INLINE int fs_event_handle::stop() { + return uv_fs_event_stop(raw()); } -UVW_INLINE void FsEventHandle::stop() { - invoke(&uv_fs_event_stop, get()); -} - -UVW_INLINE std::string FsEventHandle::path() noexcept { - return details::tryRead(&uv_fs_event_getpath, get()); +UVW_INLINE std::string fs_event_handle::path() noexcept { + return details::try_read(&uv_fs_event_getpath, raw()); } } // namespace uvw diff --git a/src/uvw/fs_event.h b/src/uvw/fs_event.h index 845dbed1..07659781 100644 --- a/src/uvw/fs_event.h +++ b/src/uvw/fs_event.h @@ -4,6 +4,8 @@ #include #include #include +#include "config.h" +#include "enum.hpp" #include "handle.hpp" #include "loop.h" #include "util.h" @@ -12,26 +14,23 @@ namespace uvw { namespace details { -enum class UVFsEventFlags : std::underlying_type_t { +enum class uvw_fs_event_flags : std::underlying_type_t { WATCH_ENTRY = UV_FS_EVENT_WATCH_ENTRY, STAT = UV_FS_EVENT_STAT, - RECURSIVE = UV_FS_EVENT_RECURSIVE + RECURSIVE = UV_FS_EVENT_RECURSIVE, + _UVW_ENUM = 0 }; -enum class UVFsEvent : std::underlying_type_t { +enum class uvw_fs_event : std::underlying_type_t { RENAME = UV_RENAME, CHANGE = UV_CHANGE }; } // namespace details -/** - * @brief FsEventEvent event. - * - * It will be emitted by FsEventHandle according with its functionalities. - */ -struct FsEventEvent { - FsEventEvent(const char *pathname, Flags events); +/*! @brief Fs event event. */ +struct fs_event_event { + fs_event_event(const char *pathname, details::uvw_fs_event events); /** * @brief The path to the file being monitored. @@ -46,82 +45,64 @@ struct FsEventEvent { * * Available flags are: * - * * `FsEventHandle::Watch::RENAME` - * * `FsEventHandle::Watch::CHANGE` + * * `fs_event_handle::watch::RENAME` + * * `fs_event_handle::watch::CHANGE` */ - Flags flags; + details::uvw_fs_event flags; }; /** - * @brief The FsEventHandle handle. + * @brief The fs event handle. * * These handles allow the user to monitor a given path for changes, for * example, if the file was renamed or there was a generic change in it. The * best backend for the job on each platform is chosen by the handle. * - * To create a `FsEventHandle` through a `Loop`, no arguments are required. + * To create a `fs_event_handle` through a `loop`, no arguments are required. * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs_event.html) * for further details. */ -class FsEventHandle final: public Handle { - static void startCallback(uv_fs_event_t *handle, const char *filename, int events, int status); +class fs_event_handle final: public handle { + static void start_callback(uv_fs_event_t *hndl, const char *filename, int events, int status); public: - using Watch = details::UVFsEvent; - using Event = details::UVFsEventFlags; + using watch = details::uvw_fs_event; + using event_flags = details::uvw_fs_event_flags; - using Handle::Handle; + using handle::handle; /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Starts watching the specified path. * * It will watch the specified path for changes.
- * As soon as a change is observed, a FsEventEvent is emitted by the - * handle.
- * It could happen that ErrorEvent events are emitted while running. + * As soon as a change is observed, a fs_event_event is emitted by the + * handle. * * Available flags are: * - * * `FsEventHandle::Event::WATCH_ENTRY` - * * `FsEventHandle::Event::STAT` - * * `FsEventHandle::Event::RECURSIVE` + * * `fs_event_handle::event_flags::WATCH_ENTRY` + * * `fs_event_handle::event_flags::STAT` + * * `fs_event_handle::event_flags::RECURSIVE` * * @param path The file or directory to be monitored. * @param flags Additional flags to control the behavior. + * @return Underlying return value. */ - void start(const std::string &path, Flags flags = Flags{}); - - /** - * @brief Starts watching the specified path. - * - * It will watch the specified path for changes.
- * As soon as a change is observed, a FsEventEvent is emitted by the - * handle.
- * It could happen that ErrorEvent events are emitted while running. - * - * Available flags are: - * - * * `FsEventHandle::Event::WATCH_ENTRY` - * * `FsEventHandle::Event::STAT` - * * `FsEventHandle::Event::RECURSIVE` - * - * @param path The file or directory to be monitored. - * @param flag Additional flag to control the behavior. - */ - void start(const std::string &path, Event flag); + int start(const std::string &path, event_flags flags = event_flags::_UVW_ENUM); /** * @brief Stops polling the file descriptor. + * @return Underlying return value. */ - void stop(); + int stop(); /** * @brief Gets the path being monitored. diff --git a/src/uvw/fs_poll.cpp b/src/uvw/fs_poll.cpp index 8c44be6a..fe00e680 100644 --- a/src/uvw/fs_poll.cpp +++ b/src/uvw/fs_poll.cpp @@ -3,38 +3,35 @@ #endif #include - #include "config.h" namespace uvw { -UVW_INLINE FsPollEvent::FsPollEvent(Stat previous, Stat current) noexcept +UVW_INLINE fs_poll_event::fs_poll_event(file_info previous, file_info current) noexcept : prev{std::move(previous)}, curr{std::move(current)} {} -UVW_INLINE void FsPollHandle::startCallback(uv_fs_poll_t *handle, int status, const uv_stat_t *prev, const uv_stat_t *curr) { - FsPollHandle &fsPoll = *(static_cast(handle->data)); - - if(status) { - fsPoll.publish(ErrorEvent{status}); +UVW_INLINE void fs_poll_handle::start_callback(uv_fs_poll_t *hndl, int status, const uv_stat_t *prev, const uv_stat_t *curr) { + if(fs_poll_handle &fsPoll = *(static_cast(hndl->data)); status) { + fsPoll.publish(error_event{status}); } else { - fsPoll.publish(FsPollEvent{*prev, *curr}); + fsPoll.publish(fs_poll_event{*prev, *curr}); } } -UVW_INLINE bool FsPollHandle::init() { - return initialize(&uv_fs_poll_init); +UVW_INLINE int fs_poll_handle::init() { + return leak_if(uv_fs_poll_init(parent().raw(), raw())); } -UVW_INLINE void FsPollHandle::start(const std::string &file, FsPollHandle::Time interval) { - invoke(&uv_fs_poll_start, get(), &startCallback, file.data(), interval.count()); +UVW_INLINE int fs_poll_handle::start(const std::string &file, fs_poll_handle::time interval) { + return uv_fs_poll_start(raw(), &start_callback, file.data(), interval.count()); } -UVW_INLINE void FsPollHandle::stop() { - invoke(&uv_fs_poll_stop, get()); +UVW_INLINE int fs_poll_handle::stop() { + return uv_fs_poll_stop(raw()); } -UVW_INLINE std::string FsPollHandle::path() noexcept { - return details::tryRead(&uv_fs_poll_getpath, get()); +UVW_INLINE std::string fs_poll_handle::path() noexcept { + return details::try_read(&uv_fs_poll_getpath, raw()); } } // namespace uvw diff --git a/src/uvw/fs_poll.h b/src/uvw/fs_poll.h index 764fcb75..0e683656 100644 --- a/src/uvw/fs_poll.h +++ b/src/uvw/fs_poll.h @@ -4,61 +4,60 @@ #include #include #include +#include "config.h" #include "handle.hpp" #include "loop.h" #include "util.h" namespace uvw { -/** - * @brief FsPollEvent event. - * - * It will be emitted by FsPollHandle according with its functionalities. - */ -struct FsPollEvent { - explicit FsPollEvent(Stat previous, Stat current) noexcept; +/*! @brief Fs pos event. */ +struct fs_poll_event { + explicit fs_poll_event(file_info previous, file_info current) noexcept; - Stat prev; /*!< The old Stat struct. */ - Stat curr; /*!< The new Stat struct. */ + file_info prev; /*!< The old file_info struct. */ + file_info curr; /*!< The new file_info struct. */ }; /** - * @brief The FsPollHandle handle. + * @brief The fs poll handle. * - * It allows the user to monitor a given path for changes. Unlike FsEventHandle - * handles, FsPollHandle handles use stat to detect when a file has changed so - * they can work on file systems where FsEventHandle handles can’t. + * It allows users to monitor a given path for changes. Unlike fs_event_handle, + * fs_poll_handle uses stat to detect when a file has changed so it can work on + * file systems where fs_event_handle handles can’t. * - * To create a `FsPollHandle` through a `Loop`, no arguments are required. + * To create a `fs_poll_handle` through a `loop`, no arguments are required. */ -class FsPollHandle final: public Handle { - static void startCallback(uv_fs_poll_t *handle, int status, const uv_stat_t *prev, const uv_stat_t *curr); +class fs_poll_handle final: public handle { + static void start_callback(uv_fs_poll_t *hndl, int status, const uv_stat_t *prev, const uv_stat_t *curr); public: - using Time = std::chrono::duration; + using time = std::chrono::duration; - using Handle::Handle; + using handle::handle; /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Starts the handle. * - * The handle will start emitting FsPollEvent when needed. + * The handle will start emitting fs_poll_event when needed. * * @param file The path to the file to be checked. * @param interval Milliseconds between successive checks. + * @return Underlying return value. */ - void start(const std::string &file, Time interval); + int start(const std::string &file, time interval); /** * @brief Stops the handle. + * @return Underlying return value. */ - void stop(); + int stop(); /** * @brief Gets the path being monitored by the handle. diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index 004af6f8..b1c223f2 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -5,59 +5,40 @@ #include #include #include +#include "config.h" #include "resource.hpp" #include "util.h" namespace uvw { -/** - * @brief CloseEvent event. - * - * It will be emitted by the handles according with their functionalities. - */ -struct CloseEvent {}; +/*! @brief Close event. */ +struct close_event {}; /** * @brief Handle base class. * * Base type for all `uvw` handle types. */ -template -class Handle: public Resource { +template +class handle: public resource { protected: - static void closeCallback(uv_handle_t *handle) { - Handle &ref = *(static_cast(handle->data)); + static void close_callback(uv_handle_t *hndl) { + handle &ref = *(static_cast(hndl->data)); [[maybe_unused]] auto ptr = ref.shared_from_this(); - ref.reset(); - ref.publish(CloseEvent{}); + ref.self_reset(); + ref.publish(close_event{}); } - static void allocCallback(uv_handle_t *, std::size_t suggested, uv_buf_t *buf) { - auto size = static_cast(suggested); - *buf = uv_buf_init(new char[size], size); + uv_handle_t *as_uv_handle() { + return reinterpret_cast(this->raw()); } - template - bool initialize(F &&f, Args &&...args) { - if(!this->self()) { - if(auto err = std::forward(f)(this->parent(), this->get(), std::forward(args)...); err) { - this->publish(ErrorEvent{err}); - } else { - this->leak(); - } - } - - return this->self(); - } - - template - void invoke(F &&f, Args &&...args) { - auto err = std::forward(f)(std::forward(args)...); - if(err) { Emitter::publish(ErrorEvent{err}); } + const uv_handle_t *as_uv_handle() const { + return reinterpret_cast(this->raw()); } public: - using Resource::Resource; + using resource::resource; /** * @brief Gets the category of the handle. @@ -68,8 +49,8 @@ public: * * @return The actual category of the handle. */ - HandleCategory category() const noexcept { - return HandleCategory{this->template get()->type}; + handle_category category() const noexcept { + return handle_category{as_uv_handle()->type}; } /** @@ -77,12 +58,12 @@ public: * * A base handle offers no functionality to promote it to the actual handle * type. By means of this function, the type of the underlying handle as - * specified by HandleType is made available to the users. + * specified by handle_type is made available to the users. * * @return The actual type of the handle. */ - HandleType type() const noexcept { - return Utilities::guessHandle(category()); + handle_type type() const noexcept { + return utilities::guess_handle(category()); } /** @@ -90,22 +71,22 @@ public: * * What _active_ means depends on the type of handle: * - * * An AsyncHandle handle is always active and cannot be deactivated, + * * An async_handle handle is always active and cannot be deactivated, * except by closing it with uv_close(). - * * A PipeHandle, TCPHandle, UDPHandle, etc. handle - basically any handle - * that deals with I/O - is active when it is doing something that involves - * I/O, like reading, writing, connecting, accepting new connections, etc. - * * A CheckHandle, IdleHandle, TimerHandle, etc. handle is active when it - * has been started with a call to `start()`. + * * A pipe, tcp, udp, etc. handle - basically any handle that deals with + * I/O - is active when it is doing something that involves I/O, like + * reading, writing, connecting, accepting new connections, etc. + * * A check, idle, timer, etc. handle is active when it has been started + * with a call to `start()`. * - * Rule of thumb: if a handle of type `FooHandle` has a `start()` member + * Rule of thumb: if a handle of type `foo_handle` has a `start()` member * method, then it’s active from the moment that method is called. Likewise, * `stop()` deactivates the handle again. * * @return True if the handle is active, false otherwise. */ bool active() const noexcept { - return !(uv_is_active(this->template get()) == 0); + return !!uv_is_active(as_uv_handle()); } /** @@ -117,21 +98,20 @@ public: * @return True if the handle is closing or closed, false otherwise. */ bool closing() const noexcept { - return !(uv_is_closing(this->template get()) == 0); + return !!uv_is_closing(as_uv_handle()); } /** * @brief Request handle to be closed. * * This **must** be called on each handle before memory is released.
- * In-progress requests are cancelled and this can result in an ErrorEvent - * emitted. + * In-progress requests are cancelled and this can result in errors. * - * The handle will emit a CloseEvent when finished. + * The handle will emit a close event when finished. */ void close() noexcept { if(!closing()) { - uv_close(this->template get(), &Handle::closeCallback); + uv_close(as_uv_handle(), &handle::close_callback); } } @@ -142,7 +122,7 @@ public: * calling this function again will have no effect. */ void reference() noexcept { - uv_ref(this->template get()); + uv_ref(as_uv_handle()); } /** @@ -152,7 +132,7 @@ public: * this function again will have no effect. */ void unreference() noexcept { - uv_unref(this->template get()); + uv_unref(as_uv_handle()); } /** @@ -160,7 +140,7 @@ public: * @return True if the handle referenced, false otherwise. */ bool referenced() const noexcept { - return !(uv_has_ref(this->template get()) == 0); + return !!uv_has_ref(as_uv_handle()); } /** @@ -168,7 +148,7 @@ public: * @return The size of the underlying handle type. */ std::size_t size() const noexcept { - return uv_handle_size(this->template get()->type); + return uv_handle_size(as_uv_handle()->type); } /** @@ -176,16 +156,17 @@ public: * * Gets the size of the send buffer that the operating system uses for the * socket.
- * This function works for TCPHandle, PipeHandle and UDPHandle handles on - * Unix and for TCPHandle and UDPHandle handles on Windows.
+ * This function works for tcp, pipeand udp handles on Unix and for tcp and + * udp handles on Windows.
* Note that Linux will return double the size of the original set value. * - * @return The size of the send buffer, 0 in case of errors. + * @return The size of the send buffer, the underlying return value in case + * of errors. */ - int sendBufferSize() { + int send_buffer_size() { int value = 0; - auto err = uv_send_buffer_size(this->template get(), &value); - return err ? 0 : value; + auto err = uv_send_buffer_size(as_uv_handle(), &value); + return err ? err : value; } /** @@ -193,14 +174,14 @@ public: * * Sets the size of the send buffer that the operating system uses for the * socket.
- * This function works for TCPHandle, PipeHandle and UDPHandle handles on - * Unix and for TCPHandle and UDPHandle handles on Windows.
+ * This function works for tcp, pipe and udp handles on Unix and for tcp and + * udp handles on Windows.
* Note that Linux will set double the size. * - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool sendBufferSize(int value) { - return (0 == uv_send_buffer_size(this->template get(), &value)); + int send_buffer_size(int value) { + return uv_send_buffer_size(as_uv_handle(), &value); } /** @@ -208,16 +189,17 @@ public: * * Gets the size of the receive buffer that the operating system uses for * the socket.
- * This function works for TCPHandle, PipeHandle and UDPHandle handles on - * Unix and for TCPHandle and UDPHandle handles on Windows.
+ * This function works for tcp, pipe and udp handles on Unix and for tcp and + * udp handles on Windows.
* Note that Linux will return double the size of the original set value. * - * @return The size of the receive buffer, 0 in case of errors. + * @return The size of the receive buffer, the underlying return value in + * case of errors. */ - int recvBufferSize() { + int recv_buffer_size() { int value = 0; - auto err = uv_recv_buffer_size(this->template get(), &value); - return err ? 0 : value; + auto err = uv_recv_buffer_size(as_uv_handle(), &value); + return err ? err : value; } /** @@ -225,14 +207,14 @@ public: * * Sets the size of the receive buffer that the operating system uses for * the socket.
- * This function works for TCPHandle, PipeHandle and UDPHandle handles on - * Unix and for TCPHandle and UDPHandle handles on Windows.
+ * This function works for tcp, pipe and udp handles on Unix and for tcp and + * udp handles on Windows.
* Note that Linux will set double the size. * - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool recvBufferSize(int value) { - return (0 == uv_recv_buffer_size(this->template get(), &value)); + int recv_buffer_size(int value) { + return uv_recv_buffer_size(as_uv_handle(), &value); } /** @@ -240,15 +222,14 @@ public: * * Supported handles: * - * * TCPHandle - * * PipeHandle - * * TTYHandle - * * UDPHandle - * * PollHandle + * * tcp_handle + * * pipe_handle + * * tty_handle + * * udp_handle + * * poll_handle * - * It will emit an ErrorEvent event if invoked on any other handle.
- * If a handle doesn’t have an attached file descriptor yet or the handle - * itself has been closed, an ErrorEvent event will be emitted. + * If invoked on a different handle, one that doesn’t have an attached file + * descriptor yet or one which was closed, an invalid value is returned. * * See the official * [documentation](http://docs.libuv.org/en/v1.x/handle.html#c.uv_fileno) @@ -257,9 +238,9 @@ public: * @return The file descriptor attached to the hande or a negative value in * case of errors. */ - OSFileDescriptor fd() const { + os_file_descriptor fd() const { uv_os_fd_t fd; - uv_fileno(this->template get(), &fd); + uv_fileno(as_uv_handle(), &fd); return fd; } }; diff --git a/src/uvw/idle.cpp b/src/uvw/idle.cpp index b2856717..03a0025b 100644 --- a/src/uvw/idle.cpp +++ b/src/uvw/idle.cpp @@ -6,21 +6,21 @@ namespace uvw { -UVW_INLINE void IdleHandle::startCallback(uv_idle_t *handle) { - IdleHandle &idle = *(static_cast(handle->data)); - idle.publish(IdleEvent{}); +UVW_INLINE void idle_handle::start_callback(uv_idle_t *hndl) { + idle_handle &idle = *(static_cast(hndl->data)); + idle.publish(idle_event{}); } -UVW_INLINE bool IdleHandle::init() { - return initialize(&uv_idle_init); +UVW_INLINE int idle_handle::init() { + return leak_if(uv_idle_init(parent().raw(), raw())); } -UVW_INLINE void IdleHandle::start() { - invoke(&uv_idle_start, get(), &startCallback); +UVW_INLINE int idle_handle::start() { + return uv_idle_start(raw(), &start_callback); } -UVW_INLINE void IdleHandle::stop() { - invoke(&uv_idle_stop, get()); +UVW_INLINE int idle_handle::stop() { + return uv_idle_stop(raw()); } } // namespace uvw diff --git a/src/uvw/idle.h b/src/uvw/idle.h index 7917cf8e..ff36ca18 100644 --- a/src/uvw/idle.h +++ b/src/uvw/idle.h @@ -7,18 +7,14 @@ namespace uvw { -/** - * @brief IdleEvent event. - * - * It will be emitted by IdleHandle according with its functionalities. - */ -struct IdleEvent {}; +/*! @brief Idle event. */ +struct idle_event {}; /** - * @brief The IdleHandle handle. + * @brief The idle handle. * - * Idle handles will emit a IdleEvent event once per loop iteration, right - * before the PrepareHandle handles. + * Idle handles will emit a idle event once per loop iteration, right before the + * prepare handles. * * The notable difference with prepare handles is that when there are active * idle handles, the loop will perform a zero timeout poll instead of blocking @@ -28,32 +24,36 @@ struct IdleEvent {}; * Despite the name, idle handles will emit events on every loop iteration, not * when the loop is actually _idle_. * - * To create an `IdleHandle` through a `Loop`, no arguments are required. + * To create an `idle_handle` through a `loop`, no arguments are required. */ -class IdleHandle final: public Handle { - static void startCallback(uv_idle_t *handle); +class idle_handle final: public handle { + static void start_callback(uv_idle_t *hndl); public: - using Handle::Handle; + using handle::handle; /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Starts the handle. * - * A IdleEvent event will be emitted once per loop iteration, right before - * polling the PrepareHandle handles. + * An idle event will be emitted once per loop iteration, right before + * polling the prepare handles. + * + * @return Underlying return value. */ - void start(); + int start(); /** * @brief Stops the handle. + * + * @return Underlying return value. */ - void stop(); + int stop(); }; } // namespace uvw diff --git a/src/uvw/lib.cpp b/src/uvw/lib.cpp index 1f7dd24a..5322a7c8 100644 --- a/src/uvw/lib.cpp +++ b/src/uvw/lib.cpp @@ -3,26 +3,25 @@ #endif #include - #include "config.h" namespace uvw { -UVW_INLINE SharedLib::SharedLib(UnderlyingType::ConstructorAccess ca, std::shared_ptr ref, const std::string &filename) noexcept - : UnderlyingType{ca, std::move(ref)} { - opened = (0 == uv_dlopen(filename.data(), get())); +UVW_INLINE shared_lib::shared_lib(loop::token token, std::shared_ptr ref, const std::string &filename) noexcept + : uv_type{token, std::move(ref)} { + opened = (0 == uv_dlopen(filename.data(), raw())); } -UVW_INLINE SharedLib::~SharedLib() noexcept { - uv_dlclose(get()); +UVW_INLINE shared_lib::~shared_lib() noexcept { + uv_dlclose(raw()); } -UVW_INLINE SharedLib::operator bool() const noexcept { +UVW_INLINE shared_lib::operator bool() const noexcept { return opened; } -UVW_INLINE const char *SharedLib::error() const noexcept { - return uv_dlerror(get()); +UVW_INLINE const char *shared_lib::error() const noexcept { + return uv_dlerror(raw()); } } // namespace uvw diff --git a/src/uvw/lib.h b/src/uvw/lib.h index 9e2f9c81..7bb720ca 100644 --- a/src/uvw/lib.h +++ b/src/uvw/lib.h @@ -5,22 +5,23 @@ #include #include #include +#include "config.h" #include "loop.h" -#include "underlying_type.hpp" +#include "uv_type.hpp" namespace uvw { /** - * @brief The SharedLib class. + * @brief The shared lib class. * * `uvw` provides cross platform utilities for loading shared libraries and * retrieving symbols from them, by means of the API offered by `libuv`. */ -class SharedLib final: public UnderlyingType { +class shared_lib final: public uv_type { public: - explicit SharedLib(ConstructorAccess ca, std::shared_ptr ref, const std::string &filename) noexcept; + explicit shared_lib(loop::token token, std::shared_ptr ref, const std::string &filename) noexcept; - ~SharedLib() noexcept; + ~shared_lib() noexcept; /** * @brief Checks if the library has been correctly opened. @@ -41,7 +42,7 @@ public: F *sym(const std::string &name) { static_assert(std::is_function_v); F *func; - auto err = uv_dlsym(get(), name.data(), reinterpret_cast(&func)); + auto err = uv_dlsym(raw(), name.data(), reinterpret_cast(&func)); if(err) { func = nullptr; } return func; } diff --git a/src/uvw/loop.cpp b/src/uvw/loop.cpp index bad6ad75..304b8f6b 100644 --- a/src/uvw/loop.cpp +++ b/src/uvw/loop.cpp @@ -6,120 +6,110 @@ namespace uvw { -UVW_INLINE Loop::Loop(std::unique_ptr ptr) noexcept - : loop{std::move(ptr)} {} +UVW_INLINE loop::loop(std::unique_ptr ptr) noexcept + : uv_loop{std::move(ptr)} {} -UVW_INLINE std::shared_ptr Loop::create() { - auto ptr = std::unique_ptr{new uv_loop_t, [](uv_loop_t *l) { - delete l; - }}; +UVW_INLINE std::shared_ptr loop::create() { + auto ptr = std::unique_ptr{new uv_loop_t, [](uv_loop_t *l) { delete l; }}; + auto curr = std::shared_ptr{new loop{std::move(ptr)}}; - auto loop = std::shared_ptr{new Loop{std::move(ptr)}}; - - if(uv_loop_init(loop->loop.get())) { - loop = nullptr; + if(uv_loop_init(curr->uv_loop.get())) { + curr = nullptr; } - return loop; + return curr; } -UVW_INLINE std::shared_ptr Loop::create(uv_loop_t *loop) { - auto ptr = std::unique_ptr{loop, [](uv_loop_t *) {}}; - return std::shared_ptr{new Loop{std::move(ptr)}}; +UVW_INLINE std::shared_ptr loop::create(uv_loop_t *res) { + auto ptr = std::unique_ptr{res, [](uv_loop_t *) {}}; + return std::shared_ptr{new loop{std::move(ptr)}}; } -UVW_INLINE std::shared_ptr Loop::getDefault() { - static std::weak_ptr ref; - std::shared_ptr loop; +UVW_INLINE std::shared_ptr loop::get_default() { + static std::weak_ptr ref; + std::shared_ptr curr; if(ref.expired()) { auto def = uv_default_loop(); if(def) { - auto ptr = std::unique_ptr(def, [](uv_loop_t *) {}); - loop = std::shared_ptr{new Loop{std::move(ptr)}}; + auto ptr = std::unique_ptr(def, [](uv_loop_t *) {}); + curr = std::shared_ptr{new loop{std::move(ptr)}}; } - ref = loop; + ref = curr; } else { - loop = ref.lock(); + curr = ref.lock(); } - return loop; + return curr; } -UVW_INLINE Loop::~Loop() noexcept { - if(loop) { +UVW_INLINE loop::~loop() noexcept { + if(uv_loop) { close(); } } -UVW_INLINE void Loop::close() { - auto err = uv_loop_close(loop.get()); - return err ? publish(ErrorEvent{err}) : loop.reset(); -} +UVW_INLINE int loop::close() { + int ret = 0; -template -bool Loop::run() noexcept { - auto utm = static_cast>(mode); - auto uvrm = static_cast(utm); - return (uv_run(loop.get(), uvrm) == 0); -} - -UVW_INLINE bool Loop::alive() const noexcept { - return !(uv_loop_alive(loop.get()) == 0); -} - -UVW_INLINE void Loop::stop() noexcept { - uv_stop(loop.get()); -} - -UVW_INLINE int Loop::descriptor() const noexcept { - return uv_backend_fd(loop.get()); -} - -UVW_INLINE std::pair Loop::timeout() const noexcept { - auto to = uv_backend_timeout(loop.get()); - return std::make_pair(to == -1, Time{to}); -} - -UVW_INLINE Loop::Time Loop::idleTime() const noexcept { - return Time{uv_metrics_idle_time(loop.get())}; -} - -UVW_INLINE Loop::Time Loop::now() const noexcept { - return Time{uv_now(loop.get())}; -} - -UVW_INLINE void Loop::update() const noexcept { - return uv_update_time(loop.get()); -} - -UVW_INLINE void Loop::fork() noexcept { - auto err = uv_loop_fork(loop.get()); - - if(err) { - publish(ErrorEvent{err}); + if(uv_loop) { + ret = uv_loop_close(uv_loop.get()); + uv_loop.reset(); } + + + return ret; } -UVW_INLINE void Loop::data(std::shared_ptr uData) { - userData = std::move(uData); +int loop::run(run_mode mode) noexcept { + return uv_run(uv_loop.get(), static_cast(mode)); } -UVW_INLINE const uv_loop_t *Loop::raw() const noexcept { - return loop.get(); +UVW_INLINE bool loop::alive() const noexcept { + return !!uv_loop_alive(uv_loop.get()); } -UVW_INLINE uv_loop_t *Loop::raw() noexcept { - return const_cast(const_cast(this)->raw()); +UVW_INLINE void loop::stop() noexcept { + uv_stop(uv_loop.get()); } -// explicit instantiations -#ifdef UVW_AS_LIB -template bool Loop::run() noexcept; -template bool Loop::run() noexcept; -template bool Loop::run() noexcept; -#endif // UVW_AS_LIB +UVW_INLINE int loop::descriptor() const noexcept { + return uv_backend_fd(uv_loop.get()); +} + +UVW_INLINE std::pair loop::timeout() const noexcept { + auto to = uv_backend_timeout(uv_loop.get()); + return std::make_pair(to == -1, time{to}); +} + +UVW_INLINE loop::time loop::idle_time() const noexcept { + return time{uv_metrics_idle_time(uv_loop.get())}; +} + +UVW_INLINE loop::time loop::now() const noexcept { + return time{uv_now(uv_loop.get())}; +} + +UVW_INLINE void loop::update() const noexcept { + return uv_update_time(uv_loop.get()); +} + +UVW_INLINE int loop::fork() noexcept { + return uv_loop_fork(uv_loop.get()); +} + +UVW_INLINE void loop::data(std::shared_ptr ud) { + user_data = std::move(ud); +} + +UVW_INLINE const uv_loop_t *loop::raw() const noexcept { + return uv_loop.get(); +} + +UVW_INLINE uv_loop_t *loop::raw() noexcept { + return const_cast(const_cast(this)->raw()); +} } // namespace uvw diff --git a/src/uvw/loop.h b/src/uvw/loop.h index d85ed15a..7cd97757 100644 --- a/src/uvw/loop.h +++ b/src/uvw/loop.h @@ -11,34 +11,35 @@ #include #include #include +#include "config.h" #include "emitter.h" #include "util.h" namespace uvw { -class AsyncHandle; -class CheckHandle; -class FsEventHandle; -class FsPollHandle; -class IdleHandle; -class PipeHandle; -class PollHandle; -class PrepareHandle; -class ProcessHandle; -class SignalHandle; -class TCPHandle; -class TimerHandle; -class TTYHandle; -class UDPHandle; +class async_handle; +class check_handle; +class fs_event_handle; +class fs_poll_handle; +class idle_handle; +class pipe_handle; +class poll_handle; +class prepare_handle; +class process_handle; +class signal_handle; +class tcp_handle; +class timer_handle; +class tty_handle; +class udp_handle; namespace details { -enum class UVLoopOption : std::underlying_type_t { +enum class uvw_loop_option : std::underlying_type_t { BLOCK_SIGNAL = UV_LOOP_BLOCK_SIGNAL, IDLE_TIME = UV_METRICS_IDLE_TIME }; -enum class UVRunMode : std::underlying_type_t { +enum class uvw_run_mode : std::underlying_type_t { DEFAULT = UV_RUN_DEFAULT, ONCE = UV_RUN_ONCE, NOWAIT = UV_RUN_NOWAIT @@ -47,55 +48,49 @@ enum class UVRunMode : std::underlying_type_t { } // namespace details /** - * @brief The Loop class. + * @brief The loop class. * * The event loop is the central part of `uvw`'s functionalities, as well as * `libuv`'s ones.
* It takes care of polling for I/O and scheduling callbacks to be run based on * different sources of events. */ -class Loop final: public Emitter, public std::enable_shared_from_this { - using Deleter = void (*)(uv_loop_t *); +class loop final: public emitter, public std::enable_shared_from_this { + using deleter = void (*)(uv_loop_t *); - template - friend class Resource; + template + friend class resource; - template - auto create_resource(int, Args &&...args) -> decltype(std::declval().init(), std::shared_ptr{}) { - auto ptr = R::create(shared_from_this(), std::forward(args)...); - ptr = ptr->init() ? ptr : nullptr; - return ptr; - } + class uv_token { + friend class loop; + explicit uv_token(int) {} + }; - template - std::shared_ptr create_resource(char, Args &&...args) { - return R::create(shared_from_this(), std::forward(args)...); - } - - Loop(std::unique_ptr ptr) noexcept; + loop(std::unique_ptr ptr) noexcept; public: - using Time = std::chrono::duration; - using Configure = details::UVLoopOption; - using Mode = details::UVRunMode; + using token = uv_token; + using time = std::chrono::duration; + using option = details::uvw_loop_option; + using run_mode = details::uvw_run_mode; /** - * @brief Initializes a new Loop instance. + * @brief Initializes a new loop instance. * @return A pointer to the newly created loop. */ - static std::shared_ptr create(); + static std::shared_ptr create(); /** - * @brief Initializes a new Loop instance from an existing resource. + * @brief Initializes a new loop instance from an existing resource. * * The lifetime of the resource must exceed that of the instance to which * it's associated. Management of the memory associated with the resource is * in charge of the user. * - * @param loop A valid pointer to a correctly initialized resource. + * @param res A valid pointer to a correctly initialized resource. * @return A pointer to the newly created loop. */ - static std::shared_ptr create(uv_loop_t *loop); + static std::shared_ptr create(uv_loop_t *res); /** * @brief Gets the initialized default loop. @@ -109,15 +104,15 @@ public: * * @return The initialized default loop. */ - static std::shared_ptr getDefault(); + static std::shared_ptr get_default(); - Loop(const Loop &) = delete; - Loop(Loop &&other) = delete; + loop(const loop &) = delete; + loop(loop &&other) = delete; - Loop &operator=(const Loop &) = delete; - Loop &operator=(Loop &&other) = delete; + loop &operator=(const loop &) = delete; + loop &operator=(loop &&other) = delete; - ~Loop() noexcept; + ~loop() noexcept; /** * @brief Sets additional loop options. @@ -126,23 +121,21 @@ public: * mentioned otherwise.
* Supported options: * - * * `Loop::Configure::BLOCK_SIGNAL`: Block a signal when polling for new + * * `loop::option::BLOCK_SIGNAL`: Block a signal when polling for new * events. A second argument is required and it is the signal number. - * * `Loop::Configure::IDLE_TIME`: Accumulate the amount of idle time the - * event loop spends in the event provider. This option is necessary to use - * `idleTime()`. - * - * An ErrorEvent will be emitted in case of errors. + * * `loop::option::IDLE_TIME`: Accumulate the amount of idle time the event + * loop spends in the event provider. This option is necessary to use + * `idle_time()`. * * See the official * [documentation](http://docs.libuv.org/en/v1.x/loop.html#c.uv_loop_configure) * for further details. + * + * @return Underlying return value. */ template - void configure(Configure flag, Args &&...args) { - auto option = static_cast>(flag); - auto err = uv_loop_configure(loop.get(), static_cast(option), std::forward(args)...); - if(err) { publish(ErrorEvent{err}); } + int configure(option flag, Args &&...args) { + return uv_loop_configure(uv_loop.get(), static_cast(flag), std::forward(args)...); } /** @@ -151,45 +144,55 @@ public: * This should be used as a default method to create resources.
* The arguments are the ones required for the specific resource. * - * Use it as `loop->resource()`. + * Use it as `loop->resource()`. * * @return A pointer to the newly created resource. */ template std::shared_ptr resource(Args &&...args) { - return create_resource(0, std::forward(args)...); + auto ptr = uninitialized_resource(std::forward(args)...); + ptr = (ptr->init() == 0) ? ptr : nullptr; + return ptr; + } + + /** + * @brief Creates uninitialized resources of any type. + * @return A pointer to the newly created resource. + */ + template + std::shared_ptr uninitialized_resource(Args &&...args) { + return std::make_shared(token{0}, shared_from_this(), std::forward(args)...); } /** * @brief Releases all internal loop resources. * * Call this function only when the loop has finished executing and all open - * handles and requests have been closed, or the loop will emit an error. + * handles and requests have been closed, or the loop will error. * - * An ErrorEvent will be emitted in case of errors. + * @return Underlying return value. */ - void close(); + int close(); /** * @brief Runs the event loop. * * Available modes are: * - * * `Loop::Mode::DEFAULT`: Runs the event loop until there are no more + * * `loop::run_mode::DEFAULT`: Runs the event loop until there are no more * active and referenced handles or requests. - * * `Loop::Mode::ONCE`: Poll for i/o once. Note that this function blocks - * if there are no pending callbacks. - * * `Loop::Mode::NOWAIT`: Poll for i/o once but don’t block if there are no - * pending callbacks. + * * `loop::run_mode::ONCE`: Poll for i/o once. Note that this function + * blocks if there are no pending callbacks. + * * `loop::run_mode::NOWAIT`: Poll for i/o once but don’t block if there + * are no pending callbacks. * * See the official * [documentation](http://docs.libuv.org/en/v1.x/loop.html#c.uv_run) * for further details. * - * @return True when done, false in all other cases. + * @return Underlying return value. */ - template - bool run() noexcept; + int run(run_mode mode = run_mode::DEFAULT) noexcept; /** * @brief Checks if there are active resources. @@ -211,8 +214,8 @@ public: * @brief Get backend file descriptor. * * Only kqueue, epoll and event ports are supported.
- * This can be used in conjunction with `run()` to poll - * in one thread and run the event loop’s callbacks in another. + * This can be used in conjunction with `run(loop::run_mode::NOWAIT)` to + * poll in one thread and run the event loop’s callbacks in another. * * @return The backend file descriptor. */ @@ -224,14 +227,14 @@ public: * * A boolean value that is true in case of valid timeout, false otherwise. * * Milliseconds (`std::chrono::duration`). */ - std::pair timeout() const noexcept; + std::pair timeout() const noexcept; /** * @brief Returns the amount of time the event loop has been idle. The call * is thread safe. * @return The accumulated time spent idle. */ - Time idleTime() const noexcept; + time idle_time() const noexcept; /** * @brief Returns the current timestamp in milliseconds. @@ -245,7 +248,7 @@ public: * @return The current timestamp in milliseconds (actual type is * `std::chrono::duration`). */ - Time now() const noexcept; + time now() const noexcept; /** * @brief Updates the event loop’s concept of _now_. @@ -261,58 +264,58 @@ public: /** * @brief Walks the list of handles. * - * The callback will be executed once for each handle that is still active. + * The callback is invoked once for each handle that is still active. * - * @param callback A function to be invoked once for each active handle. + * @param callback A function to invoke once for each active handle. */ template void walk(Func callback) { - auto func = [](uv_handle_t *handle, void *func) { - if(handle->data) { + auto func = [](uv_handle_t *hndl, void *func) { + if(hndl->data) { auto &cb = *static_cast(func); - switch(Utilities::guessHandle(HandleCategory{handle->type})) { - case HandleType::ASYNC: - cb(*static_cast(handle->data)); + switch(utilities::guess_handle(handle_category{hndl->type})) { + case handle_type::ASYNC: + cb(*static_cast(hndl->data)); break; - case HandleType::CHECK: - cb(*static_cast(handle->data)); + case handle_type::CHECK: + cb(*static_cast(hndl->data)); break; - case HandleType::FS_EVENT: - cb(*static_cast(handle->data)); + case handle_type::FS_EVENT: + cb(*static_cast(hndl->data)); break; - case HandleType::FS_POLL: - cb(*static_cast(handle->data)); + case handle_type::FS_POLL: + cb(*static_cast(hndl->data)); break; - case HandleType::IDLE: - cb(*static_cast(handle->data)); + case handle_type::IDLE: + cb(*static_cast(hndl->data)); break; - case HandleType::PIPE: - cb(*static_cast(handle->data)); + case handle_type::PIPE: + cb(*static_cast(hndl->data)); break; - case HandleType::POLL: - cb(*static_cast(handle->data)); + case handle_type::POLL: + cb(*static_cast(hndl->data)); break; - case HandleType::PREPARE: - cb(*static_cast(handle->data)); + case handle_type::PREPARE: + cb(*static_cast(hndl->data)); break; - case HandleType::PROCESS: - cb(*static_cast(handle->data)); + case handle_type::PROCESS: + cb(*static_cast(hndl->data)); break; - case HandleType::SIGNAL: - cb(*static_cast(handle->data)); + case handle_type::SIGNAL: + cb(*static_cast(hndl->data)); break; - case HandleType::TCP: - cb(*static_cast(handle->data)); + case handle_type::TCP: + cb(*static_cast(hndl->data)); break; - case HandleType::TIMER: - cb(*static_cast(handle->data)); + case handle_type::TIMER: + cb(*static_cast(hndl->data)); break; - case HandleType::TTY: - cb(*static_cast(handle->data)); + case handle_type::TTY: + cb(*static_cast(hndl->data)); break; - case HandleType::UDP: - cb(*static_cast(handle->data)); + case handle_type::UDP: + cb(*static_cast(hndl->data)); break; default: // this handle isn't managed by uvw, let it be... @@ -321,7 +324,7 @@ public: } }; - uv_walk(loop.get(), func, &callback); + uv_walk(uv_loop.get(), func, &callback); } /** @@ -348,13 +351,13 @@ public: * bugs, and is subject to change or removal. API and ABI stability is not * guaranteed. * - * An ErrorEvent will be emitted in case of errors. - * * See the official * [documentation](http://docs.libuv.org/en/v1.x/loop.html#c.uv_loop_fork) * for further details. + * + * @return Underlying return value. */ - void fork() noexcept; + int fork() noexcept; /** * @brief Gets user-defined data. `uvw` won't use this field in any case. @@ -362,14 +365,14 @@ public: */ template std::shared_ptr data() const { - return std::static_pointer_cast(userData); + return std::static_pointer_cast(user_data); } /** * @brief Sets arbitrary data. `uvw` won't use this field in any case. - * @param uData User-defined arbitrary data. + * @param ud User-defined arbitrary data. */ - void data(std::shared_ptr uData); + void data(std::shared_ptr ud); /** * @brief Gets the underlying raw data structure. @@ -406,17 +409,10 @@ public: uv_loop_t *raw() noexcept; private: - std::unique_ptr loop; - std::shared_ptr userData{nullptr}; + std::unique_ptr uv_loop; + std::shared_ptr user_data{nullptr}; }; -// (extern) explicit instantiations -#ifdef UVW_AS_LIB -extern template bool Loop::run() noexcept; -extern template bool Loop::run() noexcept; -extern template bool Loop::run() noexcept; -#endif // UVW_AS_LIB - } // namespace uvw #ifndef UVW_AS_LIB diff --git a/src/uvw/pipe.cpp b/src/uvw/pipe.cpp index 0a6ab9a9..0032ba9b 100644 --- a/src/uvw/pipe.cpp +++ b/src/uvw/pipe.cpp @@ -7,55 +7,56 @@ namespace uvw { -UVW_INLINE PipeHandle::PipeHandle(ConstructorAccess ca, std::shared_ptr ref, bool pass) - : StreamHandle{ca, std::move(ref)}, ipc{pass} {} +UVW_INLINE pipe_handle::pipe_handle(loop::token token, std::shared_ptr ref, bool pass) + : stream_handle{token, std::move(ref)}, ipc{pass} {} -UVW_INLINE bool PipeHandle::init() { - return initialize(&uv_pipe_init, ipc); +UVW_INLINE int pipe_handle::init() { + return leak_if(uv_pipe_init(parent().raw(), raw(), ipc)); } -UVW_INLINE void PipeHandle::open(FileHandle file) { - invoke(&uv_pipe_open, get(), file); +UVW_INLINE int pipe_handle::open(file_handle file) { + return uv_pipe_open(raw(), file); } -UVW_INLINE void PipeHandle::bind(const std::string &name) { - invoke(&uv_pipe_bind, get(), name.data()); +UVW_INLINE int pipe_handle::bind(const std::string &name) { + return uv_pipe_bind(raw(), name.data()); } -UVW_INLINE void PipeHandle::connect(const std::string &name) { +UVW_INLINE int pipe_handle::connect(const std::string &name) { auto listener = [ptr = shared_from_this()](const auto &event, const auto &) { ptr->publish(event); }; - auto connect = loop().resource(); - connect->once(listener); - connect->once(listener); - connect->connect(&uv_pipe_connect, get(), name.data()); + auto connect = parent().resource(); + connect->on(listener); + connect->on(listener); + + return connect->connect(&uv_pipe_connect, raw(), name.data()); } -UVW_INLINE std::string PipeHandle::sock() const noexcept { - return details::tryRead(&uv_pipe_getsockname, get()); +UVW_INLINE std::string pipe_handle::sock() const noexcept { + return details::try_read(&uv_pipe_getsockname, raw()); } -UVW_INLINE std::string PipeHandle::peer() const noexcept { - return details::tryRead(&uv_pipe_getpeername, get()); +UVW_INLINE std::string pipe_handle::peer() const noexcept { + return details::try_read(&uv_pipe_getpeername, raw()); } -UVW_INLINE void PipeHandle::pending(int count) noexcept { - uv_pipe_pending_instances(get(), count); +UVW_INLINE void pipe_handle::pending(int count) noexcept { + uv_pipe_pending_instances(raw(), count); } -UVW_INLINE int PipeHandle::pending() noexcept { - return uv_pipe_pending_count(get()); +UVW_INLINE int pipe_handle::pending() noexcept { + return uv_pipe_pending_count(raw()); } -UVW_INLINE HandleType PipeHandle::receive() noexcept { - HandleCategory category = uv_pipe_pending_type(get()); - return Utilities::guessHandle(category); +UVW_INLINE handle_type pipe_handle::receive() noexcept { + handle_category category = uv_pipe_pending_type(raw()); + return utilities::guess_handle(category); } -UVW_INLINE bool PipeHandle::chmod(Flags flags) noexcept { - return (0 == uv_pipe_chmod(get(), flags)); +UVW_INLINE int pipe_handle::chmod(chmod_flags flags) noexcept { + return uv_pipe_chmod(raw(), static_cast(flags)); } } // namespace uvw diff --git a/src/uvw/pipe.h b/src/uvw/pipe.h index 2ec25d2e..eaea5ebf 100644 --- a/src/uvw/pipe.h +++ b/src/uvw/pipe.h @@ -5,6 +5,8 @@ #include #include #include +#include "config.h" +#include "enum.hpp" #include "loop.h" #include "request.hpp" #include "stream.h" @@ -14,68 +16,69 @@ namespace uvw { namespace details { -enum class UVChmodFlags : std::underlying_type_t { +enum class uvw_chmod_flags : std::underlying_type_t { READABLE = UV_READABLE, - WRITABLE = UV_WRITABLE + WRITABLE = UV_WRITABLE, + _UVW_ENUM = 0 }; } /** - * @brief The PipeHandle handle. + * @brief The pipe handle. * * Pipe handles provide an abstraction over local domain sockets on Unix and * named pipes on Windows. * - * To create a `PipeHandle` through a `Loop`, arguments follow: + * To create a `pipe_handle` through a `loop`, arguments follow: * * * An optional boolean value that indicates if this pipe will be used for * handle passing between processes. */ -class PipeHandle final: public StreamHandle { +class pipe_handle final: public stream_handle { public: - using Chmod = details::UVChmodFlags; + using chmod_flags = details::uvw_chmod_flags; - explicit PipeHandle(ConstructorAccess ca, std::shared_ptr ref, bool pass = false); + explicit pipe_handle(loop::token token, std::shared_ptr ref, bool pass = false); /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Opens an existing file descriptor or HANDLE as a pipe. * * The passed file descriptor or HANDLE is not checked for its type, but - * it’s required that it represents a valid pipe.
- * An ErrorEvent event is emitted in case of errors. + * it’s required that it represents a valid pipe. * * @param file A valid file handle (either a file descriptor or a HANDLE). + * @return Underlying return value. */ - void open(FileHandle file); + int open(file_handle file); /** * @brief bind Binds the pipe to a file path (Unix) or a name (Windows). * - * Paths on Unix get truncated typically between 92 and 108 bytes.
- * An ErrorEvent event is emitted in case of errors. + * Paths on Unix get truncated typically between 92 and 108 bytes. * * @param name A valid file path. + * @return Underlying return value. */ - void bind(const std::string &name); + int bind(const std::string &name); /** * @brief Connects to the Unix domain socket or the named pipe. * * Paths on Unix get truncated typically between 92 and 108 bytes.
- * A ConnectEvent event is emitted when the connection has been - * established.
- * An ErrorEvent event is emitted in case of errors during the connection. + * A connect event is emitted when the connection has been + * established. * * @param name A valid domain socket or named pipe. + * @return Underlying return value. */ - void connect(const std::string &name); + int connect(const std::string &name); /** * @brief Gets the name of the Unix domain socket or the named pipe. @@ -120,12 +123,12 @@ public: * * @return The type of the pending handle. Possible values are: * - * * `HandleType::PIPE` - * * `HandleType::TCP` - * * `HandleType::UDP` - * * `HandleType::UNKNOWN` + * * `handle_type::PIPE` + * * `handle_type::TCP` + * * `handle_type::UDP` + * * `handle_type::UNKNOWN` */ - HandleType receive() noexcept; + handle_type receive() noexcept; /** * @brief Alters pipe permissions. @@ -134,17 +137,17 @@ public: * * Available flags are: * - * * `PipeHandle::Chmod::READABLE` - * * `PipeHandle::Chmod::WRITABLE` + * * `pipe_handle::chmod_flags::READABLE` + * * `pipe_handle::chmod_flags::WRITABLE` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/pipe.html#c.uv_pipe_chmod) * for further details. * * @param flags A valid set of flags. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool chmod(Flags flags) noexcept; + int chmod(chmod_flags flags) noexcept; private: bool ipc; diff --git a/src/uvw/poll.cpp b/src/uvw/poll.cpp index f33af2d8..79e508fc 100644 --- a/src/uvw/poll.cpp +++ b/src/uvw/poll.cpp @@ -3,44 +3,41 @@ #endif #include - #include "config.h" namespace uvw { -UVW_INLINE PollEvent::PollEvent(Flags events) noexcept +UVW_INLINE poll_event::poll_event(details::uvw_poll_event events) noexcept : flags{std::move(events)} {} -UVW_INLINE PollHandle::PollHandle(ConstructorAccess ca, std::shared_ptr ref, int desc) - : Handle{ca, std::move(ref)}, tag{FD}, file_desc{desc} {} +UVW_INLINE poll_handle::poll_handle(loop::token token, std::shared_ptr ref, int desc) + : handle{token, std::move(ref)}, tag{FD}, file_desc{desc} {} -UVW_INLINE PollHandle::PollHandle(ConstructorAccess ca, std::shared_ptr ref, OSSocketHandle sock) - : Handle{ca, std::move(ref)}, tag{SOCKET}, socket{sock} {} +UVW_INLINE poll_handle::poll_handle(loop::token token, std::shared_ptr ref, os_socket_handle sock) + : handle{token, std::move(ref)}, tag{SOCKET}, socket{sock} {} -UVW_INLINE void PollHandle::startCallback(uv_poll_t *handle, int status, int events) { - PollHandle &poll = *(static_cast(handle->data)); - - if(status) { - poll.publish(ErrorEvent{status}); +UVW_INLINE void poll_handle::start_callback(uv_poll_t *hndl, int status, int events) { + if(poll_handle &poll = *(static_cast(hndl->data)); status) { + poll.publish(error_event{status}); } else { - poll.publish(PollEvent{static_cast>(events)}); + poll.publish(poll_event{poll_event(events)}); } } -UVW_INLINE bool PollHandle::init() { - return (tag == SOCKET) ? initialize(&uv_poll_init_socket, socket) : initialize(&uv_poll_init, file_desc); +UVW_INLINE int poll_handle::init() { + if(tag == SOCKET) { + return leak_if(uv_poll_init_socket(parent().raw(), raw(), socket)); + } else { + return leak_if(uv_poll_init(parent().raw(), raw(), file_desc)); + } } -UVW_INLINE void PollHandle::start(Flags flags) { - invoke(&uv_poll_start, get(), flags, &startCallback); +UVW_INLINE int poll_handle::start(poll_handle::poll_event flags) { + return uv_poll_start(raw(), static_cast(flags), &start_callback); } -UVW_INLINE void PollHandle::start(PollHandle::Event event) { - start(Flags{event}); -} - -UVW_INLINE void PollHandle::stop() { - invoke(&uv_poll_stop, get()); +UVW_INLINE int poll_handle::stop() { + return uv_poll_stop(raw()); } } // namespace uvw diff --git a/src/uvw/poll.h b/src/uvw/poll.h index 1c94c04e..94eddf65 100644 --- a/src/uvw/poll.h +++ b/src/uvw/poll.h @@ -4,6 +4,8 @@ #include #include #include +#include "config.h" +#include "enum.hpp" #include "handle.hpp" #include "util.h" @@ -11,113 +13,90 @@ namespace uvw { namespace details { -enum class UVPollEvent : std::underlying_type_t { +enum class uvw_poll_event : std::underlying_type_t { READABLE = UV_READABLE, WRITABLE = UV_WRITABLE, DISCONNECT = UV_DISCONNECT, - PRIORITIZED = UV_PRIORITIZED + PRIORITIZED = UV_PRIORITIZED, + _UVW_ENUM = 0 }; } -/** - * @brief PollEvent event. - * - * It will be emitted by PollHandle according with its functionalities. - */ -struct PollEvent { - explicit PollEvent(Flags events) noexcept; +/*! @brief Poll event. */ +struct poll_event { + explicit poll_event(details::uvw_poll_event events) noexcept; /** * @brief Detected events all in one. * * Available flags are: * - * * `PollHandle::Event::READABLE` - * * `PollHandle::Event::WRITABLE` - * * `PollHandle::Event::DISCONNECT` - * * `PollHandle::Event::PRIORITIZED` + * * `poll_handle::event::READABLE` + * * `poll_handle::event::WRITABLE` + * * `poll_handle::event::DISCONNECT` + * * `poll_handle::event::PRIORITIZED` */ - Flags flags; + details::uvw_poll_event flags; }; /** - * @brief The PollHandle handle. + * @brief The poll handle. * * Poll handles are used to watch file descriptors for readability, writability * and disconnection. * - * To create a `PollHandle` through a `Loop`, arguments follow: + * To create a `poll_handle` through a `loop`, arguments follow: * * * A descriptor that can be: * * either an `int` file descriptor - * * or a `OSSocketHandle` socket descriptor + * * or a `os_socket_handle` socket descriptor * * See the official * [documentation](http://docs.libuv.org/en/v1.x/poll.html) * for further details. */ -class PollHandle final: public Handle { - static void startCallback(uv_poll_t *handle, int status, int events); +class poll_handle final: public handle { + static void start_callback(uv_poll_t *hndl, int status, int events); public: - using Event = details::UVPollEvent; + using poll_event = details::uvw_poll_event; - explicit PollHandle(ConstructorAccess ca, std::shared_ptr ref, int desc); - explicit PollHandle(ConstructorAccess ca, std::shared_ptr ref, OSSocketHandle sock); + explicit poll_handle(loop::token token, std::shared_ptr ref, int desc); + explicit poll_handle(loop::token token, std::shared_ptr ref, os_socket_handle sock); /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Starts polling the file descriptor. * * Available flags are: * - * * `PollHandle::Event::READABLE` - * * `PollHandle::Event::WRITABLE` - * * `PollHandle::Event::DISCONNECT` - * * `PollHandle::Event::PRIORITIZED` + * * `poll_handle::event::READABLE` + * * `poll_handle::event::WRITABLE` + * * `poll_handle::event::DISCONNECT` + * * `poll_handle::event::PRIORITIZED` * - * As soon as an event is detected, a PollEvent is emitted by the - * handle.
- * It could happen that ErrorEvent events are emitted while running. + * As soon as an event is detected, a poll event is emitted by the + * handle. * * Calling more than once this method will update the flags to which the * caller is interested. * * @param flags The events to which the caller is interested. + * @return Underlying return value. */ - void start(Flags flags); - - /** - * @brief Starts polling the file descriptor. - * - * Available flags are: - * - * * `PollHandle::Event::READABLE` - * * `PollHandle::Event::WRITABLE` - * * `PollHandle::Event::DISCONNECT` - * * `PollHandle::Event::PRIORITIZED` - * - * As soon as an event is detected, a PollEvent is emitted by the - * handle.
- * It could happen that ErrorEvent events are emitted while running. - * - * Calling more than once this method will update the flags to which the - * caller is interested. - * - * @param event The event to which the caller is interested. - */ - void start(Event event); + int start(poll_event flags); /** * @brief Stops polling the file descriptor. + * @return Underlying return value. */ - void stop(); + int stop(); private: enum { @@ -127,7 +106,7 @@ private: union { int file_desc; - OSSocketHandle::Type socket; + os_socket_handle socket; }; }; diff --git a/src/uvw/prepare.cpp b/src/uvw/prepare.cpp index 22aa2e91..dee7186e 100644 --- a/src/uvw/prepare.cpp +++ b/src/uvw/prepare.cpp @@ -6,21 +6,21 @@ namespace uvw { -UVW_INLINE void PrepareHandle::startCallback(uv_prepare_t *handle) { - PrepareHandle &prepare = *(static_cast(handle->data)); - prepare.publish(PrepareEvent{}); +UVW_INLINE void prepare_handle::start_callback(uv_prepare_t *hndl) { + prepare_handle &prepare = *(static_cast(hndl->data)); + prepare.publish(prepare_event{}); } -UVW_INLINE bool PrepareHandle::init() { - return initialize(&uv_prepare_init); +UVW_INLINE int prepare_handle::init() { + return leak_if(uv_prepare_init(parent().raw(), raw())); } -UVW_INLINE void PrepareHandle::start() { - invoke(&uv_prepare_start, get(), &startCallback); +UVW_INLINE int prepare_handle::start() { + return uv_prepare_start(raw(), &start_callback); } -UVW_INLINE void PrepareHandle::stop() { - invoke(&uv_prepare_stop, get()); +UVW_INLINE int prepare_handle::stop() { + return uv_prepare_stop(raw()); } } // namespace uvw diff --git a/src/uvw/prepare.h b/src/uvw/prepare.h index e2de9c09..891e1bc8 100644 --- a/src/uvw/prepare.h +++ b/src/uvw/prepare.h @@ -7,47 +7,46 @@ namespace uvw { -/** - * @brief PrepareEvent event. - * - * It will be emitted by PrepareHandle according with its functionalities. - */ -struct PrepareEvent {}; +/*! @brief Prepare event. */ +struct prepare_event {}; /** - * @brief The PrepareHandle handle. + * @brief The prepare handle. * - * Prepare handles will emit a PrepareEvent event once per loop iteration, right + * Prepare handles will emit a prepare event once per loop iteration, right * before polling for I/O. * - * To create a `PrepareHandle` through a `Loop`, no arguments are required. + * To create a `prepare_handle` through a `loop`, no arguments are required. */ -class PrepareHandle final: public Handle { - static void startCallback(uv_prepare_t *handle); +class prepare_handle final: public handle { + static void start_callback(uv_prepare_t *hndl); public: - using Handle::Handle; + using handle::handle; /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Starts the handle. * - * A PrepareEvent event will be emitted once per loop iteration, right - * before polling for I/O. + * A prepare event will be emitted once per loop iteration, right before + * polling for I/O. * - * The handle will start emitting PrepareEvent when needed. + * The handle will start emitting prepare events when needed. + * + * @return Underlying return value. */ - void start(); + int start(); /** * @brief Stops the handle. + * @return Underlying return value. */ - void stop(); + int stop(); }; } // namespace uvw diff --git a/src/uvw/process.cpp b/src/uvw/process.cpp index c09e0969..b9d20770 100644 --- a/src/uvw/process.cpp +++ b/src/uvw/process.cpp @@ -1,98 +1,95 @@ #ifdef UVW_AS_LIB # include "process.h" #endif -#include +#include #include "config.h" namespace uvw { -UVW_INLINE ExitEvent::ExitEvent(int64_t code, int sig) noexcept +UVW_INLINE exit_event::exit_event(int64_t code, int sig) noexcept : status{code}, signal{sig} {} -UVW_INLINE void ProcessHandle::exitCallback(uv_process_t *handle, int64_t exitStatus, int termSignal) { - ProcessHandle &process = *(static_cast(handle->data)); - process.publish(ExitEvent{exitStatus, termSignal}); +UVW_INLINE void process_handle::exit_callback(uv_process_t *hndl, int64_t exit_status, int term_signal) { + process_handle &process = *(static_cast(hndl->data)); + process.publish(exit_event{exit_status, term_signal}); } -UVW_INLINE ProcessHandle::ProcessHandle(ConstructorAccess ca, std::shared_ptr ref) - : Handle{ca, std::move(ref)} {} +UVW_INLINE process_handle::process_handle(loop::token token, std::shared_ptr ref) + : handle{token, std::move(ref)} {} -UVW_INLINE void ProcessHandle::disableStdIOInheritance() noexcept { +UVW_INLINE void process_handle::disable_stdio_inheritance() noexcept { uv_disable_stdio_inheritance(); } -UVW_INLINE bool ProcessHandle::kill(int pid, int signum) noexcept { +UVW_INLINE bool process_handle::kill(int pid, int signum) noexcept { return (0 == uv_kill(pid, signum)); } -UVW_INLINE bool ProcessHandle::init() { +UVW_INLINE int process_handle::init() { // deferred initialization: libuv initializes process handles only when // uv_spawn is invoked and uvw stays true to the underlying library - return true; + return 0; } -UVW_INLINE void ProcessHandle::spawn(const char *file, char **args, char **env) { +UVW_INLINE int process_handle::spawn(const char *file, char **args, char **env) { uv_process_options_t po; - po.exit_cb = &exitCallback; + po.exit_cb = &exit_callback; po.file = file; po.args = args; po.env = env; - po.cwd = poCwd.empty() ? nullptr : poCwd.data(); - po.flags = poFlags; - po.uid = poUid; - po.gid = poGid; + po.cwd = po_cwd.empty() ? nullptr : po_cwd.data(); + po.flags = static_cast(po_flags); + po.uid = po_uid; + po.gid = po_gid; std::vector poStdio; - poStdio.reserve(poFdStdio.size() + poStreamStdio.size()); - poStdio.insert(poStdio.begin(), poFdStdio.cbegin(), poFdStdio.cend()); - poStdio.insert(poStdio.end(), poStreamStdio.cbegin(), poStreamStdio.cend()); + poStdio.reserve(po_fd_stdio.size() + po_stream_stdio.size()); + poStdio.insert(poStdio.begin(), po_fd_stdio.cbegin(), po_fd_stdio.cend()); + poStdio.insert(poStdio.end(), po_stream_stdio.cbegin(), po_stream_stdio.cend()); po.stdio_count = static_cast(poStdio.size()); po.stdio = poStdio.data(); - // fake initialization so as to have leak invoked // see init member function for more details - initialize([](auto...) { - return 0; - }); + leak_if(0); - invoke(&uv_spawn, parent(), get(), &po); + return uv_spawn(parent().raw(), raw(), &po); } -UVW_INLINE void ProcessHandle::kill(int signum) { - invoke(&uv_process_kill, get(), signum); +UVW_INLINE int process_handle::kill(int signum) { + return uv_process_kill(raw(), signum); } -UVW_INLINE int ProcessHandle::pid() noexcept { - return get()->pid; +UVW_INLINE int process_handle::pid() noexcept { + return raw()->pid; } -UVW_INLINE ProcessHandle &ProcessHandle::cwd(const std::string &path) noexcept { - poCwd = path; +UVW_INLINE process_handle &process_handle::cwd(const std::string &path) noexcept { + po_cwd = path; return *this; } -UVW_INLINE ProcessHandle &ProcessHandle::flags(Flags flags) noexcept { - poFlags = flags; +UVW_INLINE process_handle &process_handle::flags(process_flags flags) noexcept { + po_flags = flags; return *this; } -UVW_INLINE ProcessHandle &ProcessHandle::stdio(FileHandle fd, Flags flags) { - auto fgs = static_cast(Flags::Type{flags}); +UVW_INLINE process_handle &process_handle::stdio(file_handle fd, stdio_flags flags) { + auto fgs = static_cast(flags); - auto actual = FileHandle::Type{fd}; + auto actual = uvw::file_handle{fd}; - auto it = std::find_if(poFdStdio.begin(), poFdStdio.end(), [actual](auto &&container) { + auto it = std::find_if(po_fd_stdio.begin(), po_fd_stdio.end(), [actual](auto &&container) { return container.data.fd == actual; }); - if(it == poFdStdio.cend()) { + if(it == po_fd_stdio.cend()) { uv_stdio_container_t container; container.flags = fgs; container.data.fd = actual; - poFdStdio.push_back(std::move(container)); + po_fd_stdio.push_back(std::move(container)); } else { it->flags = fgs; it->data.fd = actual; @@ -101,13 +98,13 @@ UVW_INLINE ProcessHandle &ProcessHandle::stdio(FileHandle fd, Flags flags return *this; } -UVW_INLINE ProcessHandle &ProcessHandle::uid(Uid id) { - poUid = id; +UVW_INLINE process_handle &process_handle::uid(uid_type id) { + po_uid = id; return *this; } -UVW_INLINE ProcessHandle &ProcessHandle::gid(Gid id) { - poGid = id; +UVW_INLINE process_handle &process_handle::gid(gid_type id) { + po_gid = id; return *this; } diff --git a/src/uvw/process.h b/src/uvw/process.h index f28ceb87..38f76c96 100644 --- a/src/uvw/process.h +++ b/src/uvw/process.h @@ -6,6 +6,8 @@ #include #include #include +#include "config.h" +#include "enum.hpp" #include "handle.hpp" #include "loop.h" #include "stream.h" @@ -15,54 +17,52 @@ namespace uvw { namespace details { -enum class UVProcessFlags : std::underlying_type_t { +enum class uvw_process_flags : std::underlying_type_t { SETUID = UV_PROCESS_SETUID, SETGID = UV_PROCESS_SETGID, WINDOWS_VERBATIM_ARGUMENTS = UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS, DETACHED = UV_PROCESS_DETACHED, WINDOWS_HIDE = UV_PROCESS_WINDOWS_HIDE, WINDOWS_HIDE_CONSOLE = UV_PROCESS_WINDOWS_HIDE_CONSOLE, - WINDOWS_HIDE_GUI = UV_PROCESS_WINDOWS_HIDE_GUI + WINDOWS_HIDE_GUI = UV_PROCESS_WINDOWS_HIDE_GUI, + _UVW_ENUM = 0 }; -enum class UVStdIOFlags : std::underlying_type_t { +enum class uvw_stdio_flags : std::underlying_type_t { IGNORE_STREAM = UV_IGNORE, CREATE_PIPE = UV_CREATE_PIPE, INHERIT_FD = UV_INHERIT_FD, INHERIT_STREAM = UV_INHERIT_STREAM, READABLE_PIPE = UV_READABLE_PIPE, WRITABLE_PIPE = UV_WRITABLE_PIPE, - OVERLAPPED_PIPE = UV_OVERLAPPED_PIPE + OVERLAPPED_PIPE = UV_OVERLAPPED_PIPE, + _UVW_ENUM = 0 }; } // namespace details -/** - * @brief ExitEvent event. - * - * It will be emitted by ProcessHandle according with its functionalities. - */ -struct ExitEvent { - explicit ExitEvent(int64_t code, int sig) noexcept; +/*! @brief Exit event. */ +struct exit_event { + explicit exit_event(int64_t code, int sig) noexcept; int64_t status; /*!< The exit status. */ int signal; /*!< The signal that caused the process to terminate, if any. */ }; /** - * @brief The ProcessHandle handle. + * @brief The process handle. * * Process handles will spawn a new process and allow the user to control it and * establish communication channels with it using streams. */ -class ProcessHandle final: public Handle { - static void exitCallback(uv_process_t *handle, int64_t exitStatus, int termSignal); +class process_handle final: public handle { + static void exit_callback(uv_process_t *hndl, int64_t exit_status, int term_signal); public: - using Process = details::UVProcessFlags; - using StdIO = details::UVStdIOFlags; + using process_flags = details::uvw_process_flags; + using stdio_flags = details::uvw_stdio_flags; - ProcessHandle(ConstructorAccess ca, std::shared_ptr ref); + process_handle(loop::token token, std::shared_ptr ref); /** * @brief Disables inheritance for file descriptors/handles. @@ -78,7 +78,7 @@ public: * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_disable_stdio_inheritance) * for further details. */ - static void disableStdIOInheritance() noexcept; + static void disable_stdio_inheritance() noexcept; /** * @brief kill Sends the specified signal to the given PID. @@ -90,16 +90,13 @@ public: /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief spawn Starts the process. * - * If the process isn't successfully spawned, an ErrorEvent event will be - * emitted by the handle. - * * See the official * [documentation](http://docs.libuv.org/en/v1.x/process.html) * for further details. @@ -107,14 +104,16 @@ public: * @param file Path pointing to the program to be executed. * @param args Command line arguments. * @param env Optional environment for the new process. + * @return Underlying return value. */ - void spawn(const char *file, char **args, char **env = nullptr); + int spawn(const char *file, char **args, char **env = nullptr); /** * @brief Sends the specified signal to the internal process handle. * @param signum A valid signal identifier. + * @return Underlying return value. */ - void kill(int signum); + int kill(int signum); /** * @brief Gets the PID of the spawned process. @@ -130,20 +129,20 @@ public: * @param path The working directory to be used when `spawn()` is invoked. * @return A reference to this process handle. */ - ProcessHandle &cwd(const std::string &path) noexcept; + process_handle &cwd(const std::string &path) noexcept; /** * @brief Sets flags that control how `spawn()` behaves. * * Available flags are: * - * * `ProcessHandle::Process::SETUID` - * * `ProcessHandle::Process::SETGID` - * * `ProcessHandle::Process::WINDOWS_VERBATIM_ARGUMENTS` - * * `ProcessHandle::Process::DETACHED` - * * `ProcessHandle::Process::WINDOWS_HIDE` - * * `ProcessHandle::Process::WINDOWS_HIDE_CONSOLE` - * * `ProcessHandle::Process::WINDOWS_HIDE_GUI` + * * `process_handle::process_flags::SETUID` + * * `process_handle::process_flags::SETGID` + * * `process_handle::process_flags::WINDOWS_VERBATIM_ARGUMENTS` + * * `process_handle::process_flags::DETACHED` + * * `process_handle::process_flags::WINDOWS_HIDE` + * * `process_handle::process_flags::WINDOWS_HIDE_CONSOLE` + * * `process_handle::process_flags::WINDOWS_HIDE_GUI` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_process_flags) @@ -152,20 +151,20 @@ public: * @param flags A valid set of flags. * @return A reference to this process handle. */ - ProcessHandle &flags(Flags flags) noexcept; + process_handle &flags(process_flags flags) noexcept; /** * @brief Makes a `stdio` handle available to the child process. * * Available flags are: * - * * `ProcessHandle::StdIO::IGNORE_STREAM` - * * `ProcessHandle::StdIO::CREATE_PIPE` - * * `ProcessHandle::StdIO::INHERIT_FD` - * * `ProcessHandle::StdIO::INHERIT_STREAM` - * * `ProcessHandle::StdIO::READABLE_PIPE` - * * `ProcessHandle::StdIO::WRITABLE_PIPE` - * * `ProcessHandle::StdIO::OVERLAPPED_PIPE` + * * `process_handle::stdio_flags::IGNORE_STREAM` + * * `process_handle::stdio_flags::CREATE_PIPE` + * * `process_handle::stdio_flags::INHERIT_FD` + * * `process_handle::stdio_flags::INHERIT_STREAM` + * * `process_handle::stdio_flags::READABLE_PIPE` + * * `process_handle::stdio_flags::WRITABLE_PIPE` + * * `process_handle::stdio_flags::OVERLAPPED_PIPE` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_stdio_flags) @@ -175,13 +174,12 @@ public: * @param flags A valid set of flags. * @return A reference to this process handle. */ - template - ProcessHandle &stdio(StreamHandle &stream, Flags flags) { + template + process_handle &stdio(stream_handle &stream, stdio_flags flags) { uv_stdio_container_t container; - Flags::Type fgs = flags; - container.flags = static_cast(fgs); - container.data.stream = get(stream); - poStreamStdio.push_back(std::move(container)); + container.flags = static_cast(flags); + container.data.stream = reinterpret_cast(stream.raw()); + po_stream_stdio.push_back(std::move(container)); return *this; } @@ -190,18 +188,18 @@ public: * * Available flags are: * - * * `ProcessHandle::StdIO::IGNORE_STREAM` - * * `ProcessHandle::StdIO::CREATE_PIPE` - * * `ProcessHandle::StdIO::INHERIT_FD` - * * `ProcessHandle::StdIO::INHERIT_STREAM` - * * `ProcessHandle::StdIO::READABLE_PIPE` - * * `ProcessHandle::StdIO::WRITABLE_PIPE` - * * `ProcessHandle::StdIO::OVERLAPPED_PIPE` + * * `process_handle::stdio_flags::IGNORE_STREAM` + * * `process_handle::stdio_flags::CREATE_PIPE` + * * `process_handle::stdio_flags::INHERIT_FD` + * * `process_handle::stdio_flags::INHERIT_STREAM` + * * `process_handle::stdio_flags::READABLE_PIPE` + * * `process_handle::stdio_flags::WRITABLE_PIPE` + * * `process_handle::stdio_flags::OVERLAPPED_PIPE` * * Default file descriptors are: - * * `uvw::StdIN` for `stdin` - * * `uvw::StdOUT` for `stdout` - * * `uvw::StdERR` for `stderr` + * * `uvw::std_in` for `stdin` + * * `uvw::std_out` for `stdout` + * * `uvw::std_err` for `stderr` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_stdio_flags) @@ -211,29 +209,29 @@ public: * @param flags A valid set of flags. * @return A reference to this process handle. */ - ProcessHandle &stdio(FileHandle fd, Flags flags); + process_handle &stdio(file_handle fd, stdio_flags flags); /** * @brief Sets the child process' user id. * @param id A valid user id to be used. * @return A reference to this process handle. */ - ProcessHandle &uid(Uid id); + process_handle &uid(uid_type id); /** * @brief Sets the child process' group id. * @param id A valid group id to be used. * @return A reference to this process handle. */ - ProcessHandle &gid(Gid id); + process_handle &gid(gid_type id); private: - std::string poCwd; - Flags poFlags; - std::vector poFdStdio; - std::vector poStreamStdio; - Uid poUid; - Gid poGid; + std::string po_cwd; + process_flags po_flags; + std::vector po_fd_stdio; + std::vector po_stream_stdio; + uid_type po_uid; + gid_type po_gid; }; } // namespace uvw diff --git a/src/uvw/request.hpp b/src/uvw/request.hpp index 47336451..39f50157 100644 --- a/src/uvw/request.hpp +++ b/src/uvw/request.hpp @@ -5,6 +5,7 @@ #include #include #include +#include "config.h" #include "resource.hpp" namespace uvw { @@ -14,56 +15,32 @@ namespace uvw { * * Base type for all `uvw` request types. */ -template -class Request: public Resource { +template +class request: public resource { protected: static auto reserve(U *req) { auto ptr = static_cast(req->data)->shared_from_this(); - ptr->reset(); + ptr->self_reset(); return ptr; } - template - static void defaultCallback(U *req, int status) { - if(auto ptr = reserve(req); status) { - ptr->publish(ErrorEvent{status}); - } else { - ptr->publish(E{}); - } - } - - template - auto invoke(F &&f, Args &&...args) { - if constexpr(std::is_void_v>) { - std::forward(f)(std::forward(args)...); - this->leak(); - } else { - if(auto err = std::forward(f)(std::forward(args)...); err) { - Emitter::publish(ErrorEvent{err}); - } else { - this->leak(); - } - } - } - public: - using Resource::Resource; + using resource::resource; /** * @brief Cancels a pending request. * * This method fails if the request is executing or has finished - * executing.
- * It can emit an ErrorEvent event in case of errors. + * executing. * * See the official * [documentation](http://docs.libuv.org/en/v1.x/request.html#c.uv_cancel) * for further details. * - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool cancel() { - return (0 == uv_cancel(this->template get())); + int cancel() { + return uv_cancel(reinterpret_cast(this->raw())); } /** @@ -71,7 +48,7 @@ public: * @return The size of the underlying request type. */ std::size_t size() const noexcept { - return uv_req_size(this->template get()->type); + return uv_req_size(reinterpret_cast(this->raw())->type); } }; diff --git a/src/uvw/resource.hpp b/src/uvw/resource.hpp index 49d556d7..07b929f4 100644 --- a/src/uvw/resource.hpp +++ b/src/uvw/resource.hpp @@ -3,8 +3,9 @@ #include #include +#include "config.h" #include "emitter.h" -#include "underlying_type.hpp" +#include "uv_type.hpp" namespace uvw { @@ -13,31 +14,29 @@ namespace uvw { * * This is the base class for handles and requests. */ -template -class Resource: public UnderlyingType, public Emitter, public std::enable_shared_from_this { +template +class resource: public uv_type, public emitter, public std::enable_shared_from_this { protected: - using ConstructorAccess = typename UnderlyingType::ConstructorAccess; + int leak_if(int err) noexcept { + if(err == 0) { + self_ptr = this->shared_from_this(); + } - auto parent() const noexcept { - return this->loop().loop.get(); + return err; } - void leak() noexcept { - sPtr = this->shared_from_this(); + void self_reset() noexcept { + self_ptr.reset(); } - void reset() noexcept { - sPtr.reset(); - } - - bool self() const noexcept { - return static_cast(sPtr); + bool has_self() const noexcept { + return static_cast(self_ptr); } public: - explicit Resource(ConstructorAccess ca, std::shared_ptr ref) - : UnderlyingType{ca, std::move(ref)} { - this->get()->data = this; + explicit resource(loop::token token, std::shared_ptr ref) + : uv_type{token, std::move(ref)} { + this->raw()->data = this; } /** @@ -46,20 +45,20 @@ public: */ template std::shared_ptr data() const { - return std::static_pointer_cast(userData); + return std::static_pointer_cast(user_data); } /** * @brief Sets arbitrary data. `uvw` won't use this field in any case. - * @param uData User-defined arbitrary data. + * @param udata User-defined arbitrary data. */ - void data(std::shared_ptr uData) { - userData = std::move(uData); + void data(std::shared_ptr udata) { + user_data = std::move(udata); } private: - std::shared_ptr userData{nullptr}; - std::shared_ptr sPtr{nullptr}; + std::shared_ptr user_data{nullptr}; + std::shared_ptr self_ptr{nullptr}; }; } // namespace uvw diff --git a/src/uvw/signal.cpp b/src/uvw/signal.cpp index 0b5bb4f9..3e04e62e 100644 --- a/src/uvw/signal.cpp +++ b/src/uvw/signal.cpp @@ -6,32 +6,32 @@ namespace uvw { -UVW_INLINE SignalEvent::SignalEvent(int sig) noexcept +UVW_INLINE signal_event::signal_event(int sig) noexcept : signum{sig} {} -UVW_INLINE void SignalHandle::startCallback(uv_signal_t *handle, int signum) { - SignalHandle &signal = *(static_cast(handle->data)); - signal.publish(SignalEvent{signum}); +UVW_INLINE void signal_handle::start_callback(uv_signal_t *hndl, int signum) { + signal_handle &signal = *(static_cast(hndl->data)); + signal.publish(signal_event{signum}); } -UVW_INLINE bool SignalHandle::init() { - return initialize(&uv_signal_init); +UVW_INLINE int signal_handle::init() { + return leak_if(uv_signal_init(parent().raw(), raw())); } -UVW_INLINE void SignalHandle::start(int signum) { - invoke(&uv_signal_start, get(), &startCallback, signum); +UVW_INLINE int signal_handle::start(int signum) { + return uv_signal_start(raw(), &start_callback, signum); } -UVW_INLINE void SignalHandle::oneShot(int signum) { - invoke(&uv_signal_start_oneshot, get(), &startCallback, signum); +UVW_INLINE int signal_handle::one_shot(int signum) { + return uv_signal_start_oneshot(raw(), &start_callback, signum); } -UVW_INLINE void SignalHandle::stop() { - invoke(&uv_signal_stop, get()); +UVW_INLINE int signal_handle::stop() { + return uv_signal_stop(raw()); } -UVW_INLINE int SignalHandle::signal() const noexcept { - return get()->signum; +UVW_INLINE int signal_handle::signal() const noexcept { + return raw()->signum; } } // namespace uvw diff --git a/src/uvw/signal.h b/src/uvw/signal.h index 0c97f775..4c09c43a 100644 --- a/src/uvw/signal.h +++ b/src/uvw/signal.h @@ -2,70 +2,70 @@ #define UVW_SIGNAL_INCLUDE_H #include +#include "config.h" #include "handle.hpp" #include "loop.h" namespace uvw { -/** - * @brief SignalEvent event. - * - * It will be emitted by SignalHandle according with its functionalities. - */ -struct SignalEvent { - explicit SignalEvent(int sig) noexcept; +/*! @brief Signal event. */ +struct signal_event { + explicit signal_event(int sig) noexcept; int signum; /*!< The signal being monitored by this handle. */ }; /** - * @brief The SignalHandle handle. + * @brief The signal handle. * * Signal handles implement Unix style signal handling on a per-event loop * bases.
* Reception of some signals is emulated on Windows. * - * To create a `SignalHandle` through a `Loop`, no arguments are required. + * To create a `signal_handle` through a `loop`, no arguments are required. * * See the official * [documentation](http://docs.libuv.org/en/v1.x/signal.html) * for further details. */ -class SignalHandle final: public Handle { - static void startCallback(uv_signal_t *handle, int signum); +class signal_handle final: public handle { + static void start_callback(uv_signal_t *hndl, int signum); public: - using Handle::Handle; + using handle::handle; /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Starts the handle. * - * The handle will start emitting SignalEvent when needed. + * The handle will start emitting signal events when needed. * * @param signum The signal to be monitored. + * @return Underlying return value. */ - void start(int signum); + int start(int signum); /** * @brief Starts the handle. * - * Same functionality as SignalHandle::start but the signal handler is reset - * the moment the signal is received. + * Same functionality as signal_handle::start but the signal handler is + * reset the moment the signal is received. * - * @param signum + * @param signum The signal to be monitored. + * @return Underlying return value. */ - void oneShot(int signum); + int one_shot(int signum); /** * @brief Stops the handle. + * @return Underlying return value. */ - void stop(); + int stop(); /** * @brief Gets the signal being monitored. diff --git a/src/uvw/stream.cpp b/src/uvw/stream.cpp index 81c2a9c7..12b041b1 100644 --- a/src/uvw/stream.cpp +++ b/src/uvw/stream.cpp @@ -6,11 +6,28 @@ namespace uvw { -UVW_INLINE DataEvent::DataEvent(std::unique_ptr buf, std::size_t len) noexcept - : data{std::move(buf)}, length{len} {} +UVW_INLINE data_event::data_event(std::unique_ptr buf, std::size_t len) noexcept + : data{std::move(buf)}, + length{len} {} -UVW_INLINE void details::ShutdownReq::shutdown(uv_stream_t *handle) { - invoke(&uv_shutdown, get(), handle, &defaultCallback); +UVW_INLINE void details::connect_req::connect_callback(uv_connect_t *req, int status) { + if(auto ptr = reserve(req); status) { + ptr->publish(error_event{status}); + } else { + ptr->publish(connect_event{}); + } +} + +UVW_INLINE void details::shutdown_req::shoutdown_callback(uv_shutdown_t *req, int status) { + if(auto ptr = reserve(req); status) { + ptr->publish(error_event{status}); + } else { + ptr->publish(shutdown_event{}); + } +} + +UVW_INLINE int details::shutdown_req::shutdown(uv_stream_t *hndl) { + return this->leak_if(uv_shutdown(raw(), hndl, &shoutdown_callback)); } } // namespace uvw diff --git a/src/uvw/stream.h b/src/uvw/stream.h index 8fc44f04..25ca887c 100644 --- a/src/uvw/stream.h +++ b/src/uvw/stream.h @@ -7,54 +7,31 @@ #include #include #include +#include "config.h" #include "handle.hpp" #include "loop.h" #include "request.hpp" namespace uvw { -/** - * @brief ConnectEvent event. - * - * It will be emitted by StreamHandle according with its functionalities. - */ -struct ConnectEvent {}; +/*! @brief Connect event. */ +struct connect_event {}; -/** - * @brief EndEvent event. - * - * It will be emitted by StreamHandle according with its functionalities. - */ -struct EndEvent {}; +/*! @brief End event. */ +struct end_event {}; -/** - * @brief ListenEvent event. - * - * It will be emitted by StreamHandle according with its functionalities. - */ -struct ListenEvent {}; +/*! @brief Listen event. */ +struct listen_event {}; -/** - * @brief ShutdownEvent event. - * - * It will be emitted by StreamHandle according with its functionalities. - */ -struct ShutdownEvent {}; +/*! @brief Shutdown event. */ +struct shutdown_event {}; -/** - * @brief WriteEvent event. - * - * It will be emitted by StreamHandle according with its functionalities. - */ -struct WriteEvent {}; +/*! @brief Write event. */ +struct write_event {}; -/** - * @brief DataEvent event. - * - * It will be emitted by StreamHandle according with its functionalities. - */ -struct DataEvent { - explicit DataEvent(std::unique_ptr buf, std::size_t len) noexcept; +/*! @brief Data event. */ +struct data_event { + explicit data_event(std::unique_ptr buf, std::size_t len) noexcept; std::unique_ptr data; /*!< A bunch of data read on the stream. */ std::size_t length; /*!< The amount of data read on the stream. */ @@ -62,37 +39,55 @@ struct DataEvent { namespace details { -struct ConnectReq final: public Request { - using Request::Request; +class connect_req final: public request { + static void connect_callback(uv_connect_t *req, int status); + +public: + using request::request; template - void connect(F &&f, Args &&...args) { - invoke(std::forward(f), get(), std::forward(args)..., &defaultCallback); + auto connect(F &&f, Args &&...args) -> std::enable_if_t(f)(raw(), std::forward(args)..., &connect_callback)), void>, int> { + std::forward(f)(raw(), std::forward(args)..., &connect_callback); + return this->leak_if(0); + } + + template + auto connect(F &&f, Args &&...args) -> std::enable_if_t(f)(raw(), std::forward(args)..., &connect_callback)), void>, int> { + return this->leak_if(std::forward(f)(raw(), std::forward(args)..., &connect_callback)); } }; -struct ShutdownReq final: public Request { - using Request::Request; +class shutdown_req final: public request { + static void shoutdown_callback(uv_shutdown_t *req, int status); - void shutdown(uv_stream_t *handle); +public: + using request::request; + + int shutdown(uv_stream_t *hndl); }; template -class WriteReq final: public Request, uv_write_t> { - using ConstructorAccess = typename Request, uv_write_t>::ConstructorAccess; +class write_req final: public request, uv_write_t, write_event> { + static void write_callback(uv_write_t *req, int status) { + if(auto ptr = request, uv_write_t, write_event>::reserve(req); status) { + ptr->publish(error_event{status}); + } else { + ptr->publish(write_event{}); + } + } public: - WriteReq(ConstructorAccess ca, std::shared_ptr loop, std::unique_ptr dt, unsigned int len) - : Request, uv_write_t>{ca, std::move(loop)}, + write_req(loop::token token, std::shared_ptr parent, std::unique_ptr dt, unsigned int len) + : request, uv_write_t, write_event>{token, std::move(parent)}, data{std::move(dt)}, buf{uv_buf_init(data.get(), len)} {} - void write(uv_stream_t *handle) { - this->invoke(&uv_write, this->get(), handle, &buf, 1, &this->template defaultCallback); + int write(uv_stream_t *hndl) { + return this->leak_if(uv_write(this->raw(), hndl, &buf, 1, &write_callback)); } - void write(uv_stream_t *handle, uv_stream_t *send) { - this->invoke(&uv_write2, this->get(), handle, &buf, 1, send, &this->template defaultCallback); + int write(uv_stream_t *hndl, uv_stream_t *send) { + return this->leak_if(uv_write2(this->raw(), hndl, &buf, 1, send, &write_callback)); } private: @@ -103,18 +98,23 @@ private: } // namespace details /** - * @brief The StreamHandle handle. + * @brief The stream handle. * * Stream handles provide an abstraction of a duplex communication channel. - * StreamHandle is an intermediate type, `uvw` provides three stream - * implementations: TCPHandle, PipeHandle and TTYHandle. + * The stream handle is an intermediate type, `uvw` provides three stream + * implementations: tcp, pipe and tty handles. */ -template -class StreamHandle: public Handle { +template +class stream_handle: public handle { + using base = handle; + + template + friend class stream_handle; + static constexpr unsigned int DEFAULT_BACKLOG = 128; - static void readCallback(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) { - T &ref = *(static_cast(handle->data)); + static void read_callback(uv_stream_t *hndl, ssize_t nread, const uv_buf_t *buf) { + T &ref = *(static_cast(hndl->data)); // data will be destroyed no matter of what the value of nread is std::unique_ptr data{buf->base}; @@ -124,30 +124,38 @@ class StreamHandle: public Handle { if(nread == UV_EOF) { // end of stream - ref.publish(EndEvent{}); + ref.publish(end_event{}); } else if(nread > 0) { // data available - ref.publish(DataEvent{std::move(data), static_cast(nread)}); + ref.publish(data_event{std::move(data), static_cast(nread)}); } else if(nread < 0) { // transmission error - ref.publish(ErrorEvent(nread)); + ref.publish(error_event(nread)); } } - static void listenCallback(uv_stream_t *handle, int status) { - if(T &ref = *(static_cast(handle->data)); status) { - ref.publish(ErrorEvent{status}); + static void listen_callback(uv_stream_t *hndl, int status) { + if(T &ref = *(static_cast(hndl->data)); status) { + ref.publish(error_event{status}); } else { - ref.publish(ListenEvent{}); + ref.publish(listen_event{}); } } + uv_stream_t *as_uv_stream() { + return reinterpret_cast(this->raw()); + } + + const uv_stream_t *as_uv_stream() const { + return reinterpret_cast(this->raw()); + } + public: #ifdef _MSC_VER - StreamHandle(typename Handle::ConstructorAccess ca, std::shared_ptr ref) - : Handle{ca, std::move(ref)} {} + stream_handle(loop::token token, std::shared_ptr ref) + : base{token, std::move(ref)} {} #else - using Handle::Handle; + using base::base; #endif /** @@ -155,75 +163,83 @@ public: * * It waits for pending write requests to complete. The handle should refer * to a initialized stream.
- * A ShutdownEvent event will be emitted after shutdown is complete. + * A shutdown event will be emitted after shutdown is complete. + * + * @return Underlying return value. */ - void shutdown() { + int shutdown() { auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) { ptr->publish(event); }; - auto shutdown = this->loop().template resource(); - shutdown->template once(listener); - shutdown->template once(listener); - shutdown->shutdown(this->template get()); + auto shutdown = this->parent().template resource(); + shutdown->template on(listener); + shutdown->template on(listener); + + return shutdown->shutdown(as_uv_stream()); } /** * @brief Starts listening for incoming connections. * - * When a new incoming connection is received, a ListenEvent event is - * emitted.
- * An ErrorEvent event will be emitted in case of errors. + * When a new incoming connection is received, a listen event is + * emitted. * * @param backlog Indicates the number of connections the kernel might * queue, same as listen(2). + * + * @return Underlying return value. */ - void listen(int backlog = DEFAULT_BACKLOG) { - this->invoke(&uv_listen, this->template get(), backlog, &listenCallback); + int listen(int backlog = DEFAULT_BACKLOG) { + return uv_listen(as_uv_stream(), backlog, &listen_callback); } /** * @brief Accepts incoming connections. * * This call is used in conjunction with `listen()` to accept incoming - * connections. Call this function after receiving a ListenEvent event to - * accept the connection. Before calling this function, the submitted handle - * must be initialized.
- * An ErrorEvent event will be emitted in case of errors. + * connections. Call this function after receiving a listen event to accept + * the connection. Before calling this function, the submitted handle must + * be initialized. * - * When the ListenEvent event is emitted it is guaranteed that this - * function will complete successfully the first time. If you attempt to use - * it more than once, it may fail.
- * It is suggested to only call this function once per ListenEvent event. + * When the listen event is emitted it is guaranteed that this function will + * complete successfully the first time. If you attempt to use it more than + * once, it may fail.
+ * It is suggested to only call this function once per listen event. * * @note * Both the handles must be running on the same loop. * * @param ref An initialized handle to be used to accept the connection. + * @return Underlying return value. */ template - void accept(S &ref) { - this->invoke(&uv_accept, this->template get(), this->template get(ref)); + int accept(S &ref) { + return uv_accept(as_uv_stream(), ref.as_uv_stream()); } /** * @brief Starts reading data from an incoming stream. * - * A DataEvent event will be emitted several times until there is no more - * data to read or `stop()` is called.
- * An EndEvent event will be emitted when there is no more data to read. + * A data event will be emitted several times until there is no more data to + * read or `stop()` is called.
+ * An end event will be emitted when there is no more data to read. + * + * @return Underlying return value. */ - void read() { - this->invoke(&uv_read_start, this->template get(), &this->allocCallback, &readCallback); + int read() { + return uv_read_start(as_uv_stream(), &details::common_alloc_callback, &read_callback); } /** * @brief Stops reading data from the stream. * * This function is idempotent and may be safely called on a stopped stream. + * + * @return Underlying return value. */ - void stop() { - this->invoke(&uv_read_stop, this->template get()); + int stop() { + return uv_read_stop(as_uv_stream()); } /** @@ -232,22 +248,23 @@ public: * Data are written in order. The handle takes the ownership of the data and * it is in charge of delete them. * - * A WriteEvent event will be emitted when the data have been written.
- * An ErrorEvent event will be emitted in case of errors. + * A write event will be emitted when the data have been written. * * @param data The data to be written to the stream. * @param len The lenght of the submitted data. + * @return Underlying return value. */ template - void write(std::unique_ptr data, unsigned int len) { - auto req = this->loop().template resource>(std::move(data), len); + int write(std::unique_ptr data, unsigned int len) { + auto req = this->parent().template resource>(std::move(data), len); auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) { ptr->publish(event); }; - req->template once(listener); - req->template once(listener); - req->write(this->template get()); + req->template on(listener); + req->template on(listener); + + return req->write(as_uv_stream()); } /** @@ -256,21 +273,22 @@ public: * Data are written in order. The handle doesn't take the ownership of the * data. Be sure that their lifetime overcome the one of the request. * - * A WriteEvent event will be emitted when the data have been written.
- * An ErrorEvent event will be emitted in case of errors. + * A write event will be emitted when the data have been written. * * @param data The data to be written to the stream. * @param len The lenght of the submitted data. + * @return Underlying return value. */ - void write(char *data, unsigned int len) { - auto req = this->loop().template resource>(std::unique_ptr{data, [](char *) {}}, len); + int write(char *data, unsigned int len) { + auto req = this->parent().template resource>(std::unique_ptr{data, [](char *) {}}, len); auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) { ptr->publish(event); }; - req->template once(listener); - req->template once(listener); - req->write(this->template get()); + req->template on(listener); + req->template on(listener); + + return req->write(as_uv_stream()); } /** @@ -278,30 +296,31 @@ public: * * The pipe must be initialized with `ipc == true`. * - * `send` must be a TCPHandle or PipeHandle handle, which is a server or a - * connection (listening or connected state). Bound sockets or pipes will be - * assumed to be servers. + * `send` must be a tcp or pipe handle, which is a server or a connection + * (listening or connected state). Bound sockets or pipes will be assumed to + * be servers. * * The handle takes the ownership of the data and it is in charge of delete * them. * - * A WriteEvent event will be emitted when the data have been written.
- * An ErrorEvent wvent will be emitted in case of errors. + * A write event will be emitted when the data have been written. * * @param send The handle over which to write data. * @param data The data to be written to the stream. * @param len The lenght of the submitted data. + * @return Underlying return value. */ template - void write(S &send, std::unique_ptr data, unsigned int len) { - auto req = this->loop().template resource>(std::move(data), len); + int write(S &send, std::unique_ptr data, unsigned int len) { + auto req = this->parent().template resource>(std::move(data), len); auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) { ptr->publish(event); }; - req->template once(listener); - req->template once(listener); - req->write(this->template get(), this->template get(send)); + req->template on(listener); + req->template on(listener); + + return req->write(as_uv_stream(), send.as_uv_stream()); } /** @@ -309,124 +328,93 @@ public: * * The pipe must be initialized with `ipc == true`. * - * `send` must be a TCPHandle or PipeHandle handle, which is a server or a - * connection (listening or connected state). Bound sockets or pipes will be - * assumed to be servers. + * `send` must be a tcp or pipe handle, which is a server or a connection + * (listening or connected state). Bound sockets or pipes will be assumed to + * be servers. * * The handle doesn't take the ownership of the data. Be sure that their * lifetime overcome the one of the request. * - * A WriteEvent event will be emitted when the data have been written.
- * An ErrorEvent wvent will be emitted in case of errors. + * A write event will be emitted when the data have been written. * * @param send The handle over which to write data. * @param data The data to be written to the stream. * @param len The lenght of the submitted data. + * @return Underlying return value. */ template - void write(S &send, char *data, unsigned int len) { - auto req = this->loop().template resource>(std::unique_ptr{data, [](char *) {}}, len); + int write(S &send, char *data, unsigned int len) { + auto req = this->parent().template resource>(std::unique_ptr{data, [](char *) {}}, len); auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) { ptr->publish(event); }; - req->template once(listener); - req->template once(listener); - req->write(this->template get(), this->template get(send)); + req->template on(listener); + req->template on(listener); + + return req->write(as_uv_stream(), send.as_uv_stream()); } /** * @brief Queues a write request if it can be completed immediately. * * Same as `write()`, but won’t queue a write request if it can’t be - * completed immediately.
- * An ErrorEvent event will be emitted in case of errors. + * completed immediately. * * @param data The data to be written to the stream. * @param len The lenght of the submitted data. - * @return Number of bytes written. + * @return Underlying return value. */ - int tryWrite(std::unique_ptr data, unsigned int len) { + int try_write(std::unique_ptr data, unsigned int len) { uv_buf_t bufs[] = {uv_buf_init(data.get(), len)}; - auto bw = uv_try_write(this->template get(), bufs, 1); - - if(bw < 0) { - this->publish(ErrorEvent{bw}); - bw = 0; - } - - return bw; + return uv_try_write(as_uv_stream(), bufs, 1); } /** * @brief Queues a write request if it can be completed immediately. * - * Same as `tryWrite` for sending handles over a pipe.
- * An ErrorEvent event will be emitted in case of errors. + * Same as `try_write` for sending handles over a pipe. * * @param data The data to be written to the stream. * @param len The lenght of the submitted data. * @param send A valid handle suitable for the purpose. - * @return Number of bytes written. + * @return Underlying return value. */ template - int tryWrite(std::unique_ptr data, unsigned int len, StreamHandle &send) { + int try_write(std::unique_ptr data, unsigned int len, stream_handle &send) { uv_buf_t bufs[] = {uv_buf_init(data.get(), len)}; - auto bw = uv_try_write2(this->template get(), bufs, 1, send.raw()); - - if(bw < 0) { - this->publish(ErrorEvent{bw}); - bw = 0; - } - - return bw; + return uv_try_write2(as_uv_stream(), bufs, 1, send.raw()); } /** * @brief Queues a write request if it can be completed immediately. * * Same as `write()`, but won’t queue a write request if it can’t be - * completed immediately.
- * An ErrorEvent event will be emitted in case of errors. + * completed immediately. * * @param data The data to be written to the stream. * @param len The lenght of the submitted data. - * @return Number of bytes written. + * @return Underlying return value. */ - int tryWrite(char *data, unsigned int len) { + int try_write(char *data, unsigned int len) { uv_buf_t bufs[] = {uv_buf_init(data, len)}; - auto bw = uv_try_write(this->template get(), bufs, 1); - - if(bw < 0) { - this->publish(ErrorEvent{bw}); - bw = 0; - } - - return bw; + return uv_try_write(as_uv_stream(), bufs, 1); } /** * @brief Queues a write request if it can be completed immediately. * - * Same as `tryWrite` for sending handles over a pipe.
- * An ErrorEvent event will be emitted in case of errors. + * Same as `try_write` for sending handles over a pipe. * * @param data The data to be written to the stream. * @param len The lenght of the submitted data. * @param send A valid handle suitable for the purpose. - * @return Number of bytes written. + * @return Underlying return value. */ template - int tryWrite(char *data, unsigned int len, StreamHandle &send) { + int try_write(char *data, unsigned int len, stream_handle &send) { uv_buf_t bufs[] = {uv_buf_init(data, len)}; - auto bw = uv_try_write2(this->template get(), bufs, 1, send.raw()); - - if(bw < 0) { - this->publish(ErrorEvent{bw}); - bw = 0; - } - - return bw; + return uv_try_write2(as_uv_stream(), bufs, 1, send.raw()); } /** @@ -434,7 +422,7 @@ public: * @return True if the stream is readable, false otherwise. */ bool readable() const noexcept { - return (uv_is_readable(this->template get()) == 1); + return (uv_is_readable(as_uv_stream()) == 1); } /** @@ -442,7 +430,7 @@ public: * @return True if the stream is writable, false otherwise. */ bool writable() const noexcept { - return (uv_is_writable(this->template get()) == 1); + return (uv_is_writable(as_uv_stream()) == 1); } /** @@ -461,15 +449,15 @@ public: * @return True in case of success, false otherwise. */ bool blocking(bool enable = false) { - return (0 == uv_stream_set_blocking(this->template get(), enable)); + return (0 == uv_stream_set_blocking(as_uv_stream(), enable)); } /** * @brief Gets the amount of queued bytes waiting to be sent. * @return Amount of queued bytes waiting to be sent. */ - size_t writeQueueSize() const noexcept { - return uv_stream_get_write_queue_size(this->template get()); + size_t write_queue_size() const noexcept { + return uv_stream_get_write_queue_size(as_uv_stream()); } }; diff --git a/src/uvw/tcp.cpp b/src/uvw/tcp.cpp index 2107558b..37e98029 100644 --- a/src/uvw/tcp.cpp +++ b/src/uvw/tcp.cpp @@ -6,101 +6,81 @@ namespace uvw { -UVW_INLINE TCPHandle::TCPHandle(ConstructorAccess ca, std::shared_ptr ref, unsigned int f) - : StreamHandle{ca, std::move(ref)}, tag{f ? FLAGS : DEFAULT}, flags{f} {} +UVW_INLINE tcp_handle::tcp_handle(loop::token token, std::shared_ptr ref, unsigned int f) + : stream_handle{token, std::move(ref)}, tag{f ? FLAGS : DEFAULT}, flags{f} {} -UVW_INLINE bool TCPHandle::init() { - return (tag == FLAGS) ? initialize(&uv_tcp_init_ex, flags) : initialize(&uv_tcp_init); +UVW_INLINE int tcp_handle::init() { + if(tag == FLAGS) { + return leak_if(uv_tcp_init_ex(parent().raw(), raw(), flags)); + } else { + return leak_if(uv_tcp_init(parent().raw(), raw())); + } } -UVW_INLINE void TCPHandle::open(OSSocketHandle socket) { - invoke(&uv_tcp_open, get(), socket); +UVW_INLINE int tcp_handle::open(os_socket_handle socket) { + return uv_tcp_open(raw(), socket); } -UVW_INLINE bool TCPHandle::noDelay(bool value) { - return (0 == uv_tcp_nodelay(get(), value)); +UVW_INLINE bool tcp_handle::no_delay(bool value) { + return (0 == uv_tcp_nodelay(raw(), value)); } -UVW_INLINE bool TCPHandle::keepAlive(bool enable, TCPHandle::Time time) { - return (0 == uv_tcp_keepalive(get(), enable, time.count())); +UVW_INLINE bool tcp_handle::keep_alive(bool enable, tcp_handle::time val) { + return (0 == uv_tcp_keepalive(raw(), enable, val.count())); } -UVW_INLINE bool TCPHandle::simultaneousAccepts(bool enable) { - return (0 == uv_tcp_simultaneous_accepts(get(), enable)); +UVW_INLINE bool tcp_handle::simultaneous_accepts(bool enable) { + return (0 == uv_tcp_simultaneous_accepts(raw(), enable)); } -UVW_INLINE void TCPHandle::bind(const sockaddr &addr, Flags opts) { - invoke(&uv_tcp_bind, get(), &addr, opts); +UVW_INLINE int tcp_handle::bind(const sockaddr &addr, tcp_flags opts) { + return uv_tcp_bind(raw(), &addr, static_cast(opts)); } -template -UVW_INLINE void TCPHandle::bind(const std::string &ip, unsigned int port, Flags opts) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - bind(reinterpret_cast(addr), std::move(opts)); +UVW_INLINE int tcp_handle::bind(const std::string &ip, unsigned int port, tcp_flags opts) { + return bind(details::ip_addr(ip.data(), port), opts); } -template -UVW_INLINE void TCPHandle::bind(Addr addr, Flags opts) { - bind(std::move(addr.ip), addr.port, std::move(opts)); +UVW_INLINE int tcp_handle::bind(socket_address addr, tcp_flags opts) { + return bind(addr.ip, addr.port, opts); } -template -UVW_INLINE Addr TCPHandle::sock() const noexcept { - return details::address(&uv_tcp_getsockname, get()); +UVW_INLINE socket_address tcp_handle::sock() const noexcept { + sockaddr_storage storage; + int len = sizeof(sockaddr_storage); + uv_tcp_getsockname(raw(), reinterpret_cast(&storage), &len); + return details::sock_addr(storage); } -template -UVW_INLINE Addr TCPHandle::peer() const noexcept { - return details::address(&uv_tcp_getpeername, get()); +UVW_INLINE socket_address tcp_handle::peer() const noexcept { + sockaddr_storage storage; + int len = sizeof(sockaddr_storage); + uv_tcp_getpeername(raw(), reinterpret_cast(&storage), &len); + return details::sock_addr(storage); } -template -UVW_INLINE void TCPHandle::connect(const std::string &ip, unsigned int port) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - connect(reinterpret_cast(addr)); +UVW_INLINE int tcp_handle::connect(const std::string &ip, unsigned int port) { + return connect(details::ip_addr(ip.data(), port)); } -template -UVW_INLINE void TCPHandle::connect(Addr addr) { - connect(std::move(addr.ip), addr.port); +UVW_INLINE int tcp_handle::connect(socket_address addr) { + return connect(addr.ip, addr.port); } -UVW_INLINE void TCPHandle::connect(const sockaddr &addr) { +UVW_INLINE int tcp_handle::connect(const sockaddr &addr) { auto listener = [ptr = shared_from_this()](const auto &event, const auto &) { ptr->publish(event); }; - auto req = loop().resource(); - req->once(listener); - req->once(listener); - req->connect(&uv_tcp_connect, get(), &addr); + auto req = parent().resource(); + req->on(listener); + req->on(listener); + + return req->connect(&uv_tcp_connect, raw(), &addr); } -UVW_INLINE void TCPHandle::closeReset() { - invoke(&uv_tcp_close_reset, get(), &this->closeCallback); +UVW_INLINE int tcp_handle::close_reset() { + return uv_tcp_close_reset(raw(), &this->close_callback); } -// explicit instantiations -#ifdef UVW_AS_LIB -template void TCPHandle::bind(const std::string &, unsigned int, Flags); -template void TCPHandle::bind(const std::string &, unsigned int, Flags); - -template void TCPHandle::bind(Addr, Flags); -template void TCPHandle::bind(Addr, Flags); - -template Addr TCPHandle::sock() const noexcept; -template Addr TCPHandle::sock() const noexcept; - -template Addr TCPHandle::peer() const noexcept; -template Addr TCPHandle::peer() const noexcept; - -template void TCPHandle::connect(const std::string &, unsigned int); -template void TCPHandle::connect(const std::string &, unsigned int); - -template void TCPHandle::connect(Addr addr); -template void TCPHandle::connect(Addr addr); -#endif // UVW_AS_LIB - } // namespace uvw diff --git a/src/uvw/tcp.h b/src/uvw/tcp.h index 43204194..0d02d92f 100644 --- a/src/uvw/tcp.h +++ b/src/uvw/tcp.h @@ -7,6 +7,8 @@ #include #include #include +#include "config.h" +#include "enum.hpp" #include "request.hpp" #include "stream.h" #include "util.h" @@ -15,20 +17,21 @@ namespace uvw { namespace details { -enum class UVTCPFlags : std::underlying_type_t { - IPV6ONLY = UV_TCP_IPV6ONLY +enum class uvw_tcp_flags : std::underlying_type_t { + IPV6ONLY = UV_TCP_IPV6ONLY, + _UVW_ENUM = 0 }; } /** - * @brief The TCPHandle handle. + * @brief The TCP handle. * * TCP handles are used to represent both TCP streams and servers.
- * By default, _IPv4_ is used as a template parameter. The handle already - * supports _IPv6_ out-of-the-box by using `uvw::IPv6`. + * By default, _ipv4_ is used as a template parameter. The handle already + * supports _IPv6_ out-of-the-box by using `uvw::ipv6`. * - * To create a `TCPHandle` through a `Loop`, arguments follow: + * To create a `tcp_handle` through a `loop`, arguments follow: * * * An optional integer value that indicates the flags used to initialize * the socket. @@ -37,20 +40,20 @@ enum class UVTCPFlags : std::underlying_type_t { * [documentation](http://docs.libuv.org/en/v1.x/tcp.html#c.uv_tcp_init_ex) * for further details. */ -class TCPHandle final: public StreamHandle { +class tcp_handle final: public stream_handle { public: - using Time = std::chrono::duration; - using Bind = details::UVTCPFlags; - using IPv4 = uvw::IPv4; - using IPv6 = uvw::IPv6; + using time = std::chrono::duration; + using tcp_flags = details::uvw_tcp_flags; + using ipv4 = uvw::ipv4; + using ipv6 = uvw::ipv6; - explicit TCPHandle(ConstructorAccess ca, std::shared_ptr ref, unsigned int f = {}); + explicit tcp_handle(loop::token token, std::shared_ptr ref, unsigned int f = {}); /** * @brief Initializes the handle. No socket is created as of yet. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Opens an existing file descriptor or SOCKET as a TCP handle. @@ -58,25 +61,28 @@ public: * The passed file descriptor or SOCKET is not checked for its type, but * it’s required that it represents a valid stream socket. * - * @param socket A valid socket handle (either a file descriptor or a SOCKET). + * @param socket A valid socket handle (either a file descriptor or a + * SOCKET). + * + * @return Underlying return value. */ - void open(OSSocketHandle socket); + int open(os_socket_handle socket); /** * @brief Enables/Disables Nagle’s algorithm. * @param value True to enable it, false otherwise. * @return True in case of success, false otherwise. */ - bool noDelay(bool value = false); + bool no_delay(bool value = false); /** * @brief Enables/Disables TCP keep-alive. * @param enable True to enable it, false otherwise. - * @param time Initial delay in seconds (use + * @param val Initial delay in seconds (use * `std::chrono::duration`). * @return True in case of success, false otherwise. */ - bool keepAlive(bool enable = false, Time time = Time{0}); + bool keep_alive(bool enable = false, time val = time{0}); /** * @brief Enables/Disables simultaneous asynchronous accept requests. @@ -92,78 +98,73 @@ public: * @param enable True to enable it, false otherwise. * @return True in case of success, false otherwise. */ - bool simultaneousAccepts(bool enable = true); + bool simultaneous_accepts(bool enable = true); /** * @brief Binds the handle to an address and port. * * A successful call to this function does not guarantee that the call to - * `listen()` or `connect()` will work properly.
- * ErrorEvent events can be emitted because of either this function or the - * ones mentioned above. + * `listen()` or `connect()` will work properly. * * Available flags are: * - * * `TCPHandle::Bind::IPV6ONLY`: it disables dual-stack support and only - * IPv6 is used. + * * `tcp_handle::tcp_flags::IPV6ONLY`: it disables dual-stack support and + * only IPv6 is used. * * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. * @param opts Optional additional flags. + * @return Underlying return value. */ - void bind(const sockaddr &addr, Flags opts = Flags{}); + int bind(const sockaddr &addr, tcp_flags opts = tcp_flags::_UVW_ENUM); /** * @brief Binds the handle to an address and port. * * A successful call to this function does not guarantee that the call to - * `listen()` or `connect()` will work properly.
- * ErrorEvent events can be emitted because of either this function or the - * ones mentioned above. + * `listen()` or `connect()` will work properly. * * Available flags are: * - * * `TCPHandle::Bind::IPV6ONLY`: it disables dual-stack support and only - * IPv6 is used. + * * `tcp_handle::tcp_flags::IPV6ONLY`: it disables dual-stack support and + * only IPv6 is used. * * @param ip The address to which to bind. * @param port The port to which to bind. * @param opts Optional additional flags. + * @return Underlying return value. */ - template - void bind(const std::string &ip, unsigned int port, Flags opts = Flags{}); + int bind(const std::string &ip, unsigned int port, tcp_flags opts = tcp_flags::_UVW_ENUM); /** * @brief Binds the handle to an address and port. * * A successful call to this function does not guarantee that the call to - * `listen()` or `connect()` will work properly.
- * ErrorEvent events can be emitted because of either this function or the - * ones mentioned above. + * `listen()` or `connect()` will work properly. * * Available flags are: * - * * `TCPHandle::Bind::IPV6ONLY`: it disables dual-stack support and only - * IPv6 is used. + * * `tcp_handle::tcp_flags::IPV6ONLY`: it disables dual-stack support and + * only IPv6 is used. * - * @param addr A valid instance of Addr. + * @param addr A valid instance of socket_address. * @param opts Optional additional flags. + * @return Underlying return value. */ - template - void bind(Addr addr, Flags opts = Flags{}); + int bind(socket_address addr, tcp_flags opts = tcp_flags::_UVW_ENUM); /** * @brief Gets the current address to which the handle is bound. - * @return A valid instance of Addr, an empty one in case of errors. + * @return A valid instance of socket_address, an empty one in case of + * errors. */ - template - Addr sock() const noexcept; + socket_address sock() const noexcept; /** * @brief Gets the address of the peer connected to the handle. - * @return A valid instance of Addr, an empty one in case of errors. + * @return A valid instance of socket_address, an empty one in case of + * errors. */ - template - Addr peer() const noexcept; + socket_address peer() const noexcept; /** * @brief Establishes an IPv4 or IPv6 TCP connection. @@ -172,38 +173,33 @@ public: * (`0.0.0.0` or `::`) it will be changed to point to localhost. This is * done to match the behavior of Linux systems. * - * A ConnectEvent event is emitted when the connection has been - * established.
- * An ErrorEvent event is emitted in case of errors during the connection. + * A connect event is emitted when the connection has been established. * * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. + * @return Underlying return value. */ - void connect(const sockaddr &addr); + int connect(const sockaddr &addr); /** * @brief Establishes an IPv4 or IPv6 TCP connection. * - * A ConnectEvent event is emitted when the connection has been - * established.
- * An ErrorEvent event is emitted in case of errors during the connection. + * A connect event is emitted when the connection has been established. * * @param ip The address to which to bind. * @param port The port to which to bind. + * @return Underlying return value. */ - template - void connect(const std::string &ip, unsigned int port); + int connect(const std::string &ip, unsigned int port); /** * @brief Establishes an IPv4 or IPv6 TCP connection. * - * A ConnectEvent event is emitted when the connection has been - * established.
- * An ErrorEvent event is emitted in case of errors during the connection. + * A connect event is emitted when the connection has been established. * - * @param addr A valid instance of Addr. + * @param addr A valid instance of socket_address. + * @return Underlying return value. */ - template - void connect(Addr addr); + int connect(socket_address addr); /** * @brief Resets a TCP connection by sending a RST packet. @@ -211,12 +207,13 @@ public: * This is accomplished by setting the `SO_LINGER` socket option with a * linger interval of zero and then calling `close`.
* Due to some platform inconsistencies, mixing of `shutdown` and - * `closeReset` calls is not allowed. + * `close_reset` calls is not allowed. * - * A CloseEvent event is emitted when the connection has been reset.
- * An ErrorEvent event is emitted in case of errors. + * A close event is emitted when the connection has been reset. + * + * @return Underlying return value. */ - void closeReset(); + int close_reset(); private: enum { @@ -227,37 +224,6 @@ private: unsigned int flags; }; -/** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - -// (extern) explicit instantiations -#ifdef UVW_AS_LIB -extern template void TCPHandle::bind(const std::string &, unsigned int, Flags); -extern template void TCPHandle::bind(const std::string &, unsigned int, Flags); - -extern template void TCPHandle::bind(Addr, Flags); -extern template void TCPHandle::bind(Addr, Flags); - -extern template Addr TCPHandle::sock() const noexcept; -extern template Addr TCPHandle::sock() const noexcept; - -extern template Addr TCPHandle::peer() const noexcept; -extern template Addr TCPHandle::peer() const noexcept; - -extern template void TCPHandle::connect(const std::string &, unsigned int); -extern template void TCPHandle::connect(const std::string &, unsigned int); - -extern template void TCPHandle::connect(Addr addr); -extern template void TCPHandle::connect(Addr addr); -#endif // UVW_AS_LIB - -/** - * Internal details not to be documented. - * @endcond - */ - } // namespace uvw #ifndef UVW_AS_LIB diff --git a/src/uvw/thread.cpp b/src/uvw/thread.cpp index 715b6c28..a42cf6c3 100644 --- a/src/uvw/thread.cpp +++ b/src/uvw/thread.cpp @@ -6,168 +6,170 @@ namespace uvw { -UVW_INLINE Thread::Thread(ConstructorAccess ca, std::shared_ptr ref, Task t, std::shared_ptr d) noexcept - : UnderlyingType{ca, std::move(ref)}, data{std::move(d)}, task{std::move(t)} {} +UVW_INLINE thread::thread(loop::token token, std::shared_ptr ref, task t, std::shared_ptr d) noexcept + : uv_type{token, std::move(ref)}, + data{std::move(d)}, + func{std::move(t)} {} -UVW_INLINE void Thread::createCallback(void *arg) { - Thread &thread = *(static_cast(arg)); - thread.task(thread.data); +UVW_INLINE void thread::create_callback(void *arg) { + thread &curr = *(static_cast(arg)); + curr.func(curr.data); } -UVW_INLINE Thread::Type Thread::self() noexcept { +UVW_INLINE thread::type thread::self() noexcept { return uv_thread_self(); } -UVW_INLINE bool Thread::equal(const Thread &tl, const Thread &tr) noexcept { - return !(0 == uv_thread_equal(tl.get(), tr.get())); +UVW_INLINE bool thread::equal(const thread &tl, const thread &tr) noexcept { + return !(0 == uv_thread_equal(tl.raw(), tr.raw())); } -UVW_INLINE Thread::~Thread() noexcept { +UVW_INLINE thread::~thread() noexcept { join(); } -UVW_INLINE bool Thread::run() noexcept { - return (0 == uv_thread_create(get(), &createCallback, this)); +UVW_INLINE bool thread::run() noexcept { + return (0 == uv_thread_create(raw(), &create_callback, this)); } -UVW_INLINE bool Thread::run(Flags opts, std::size_t stack) noexcept { +UVW_INLINE bool thread::run(create_flags opts, std::size_t stack) noexcept { uv_thread_options_t params{static_cast(opts), stack}; - return (0 == uv_thread_create_ex(get(), ¶ms, &createCallback, this)); + return (0 == uv_thread_create_ex(raw(), ¶ms, &create_callback, this)); } -UVW_INLINE bool Thread::join() noexcept { - return (0 == uv_thread_join(get())); +UVW_INLINE bool thread::join() noexcept { + return (0 == uv_thread_join(raw())); } -UVW_INLINE ThreadLocalStorage::ThreadLocalStorage(UnderlyingType::ConstructorAccess ca, std::shared_ptr ref) noexcept - : UnderlyingType{ca, std::move(ref)} { - uv_key_create(UnderlyingType::get()); +UVW_INLINE thread_local_storage::thread_local_storage(loop::token token, std::shared_ptr ref) noexcept + : uv_type{token, std::move(ref)} { + uv_key_create(uv_type::raw()); } -UVW_INLINE ThreadLocalStorage::~ThreadLocalStorage() noexcept { - uv_key_delete(UnderlyingType::get()); +UVW_INLINE thread_local_storage::~thread_local_storage() noexcept { + uv_key_delete(uv_type::raw()); } -UVW_INLINE uv_once_t *Once::guard() noexcept { +UVW_INLINE uv_once_t *once::guard() noexcept { static uv_once_t once = UV_ONCE_INIT; return &once; } -UVW_INLINE Mutex::Mutex(UnderlyingType::ConstructorAccess ca, std::shared_ptr ref, bool recursive) noexcept - : UnderlyingType{ca, std::move(ref)} { +UVW_INLINE mutex::mutex(loop::token token, std::shared_ptr ref, bool recursive) noexcept + : uv_type{token, std::move(ref)} { if(recursive) { - uv_mutex_init_recursive(get()); + uv_mutex_init_recursive(raw()); } else { - uv_mutex_init(get()); + uv_mutex_init(raw()); } } -UVW_INLINE Mutex::~Mutex() noexcept { - uv_mutex_destroy(get()); +UVW_INLINE mutex::~mutex() noexcept { + uv_mutex_destroy(raw()); } -UVW_INLINE void Mutex::lock() noexcept { - uv_mutex_lock(get()); +UVW_INLINE void mutex::lock() noexcept { + uv_mutex_lock(raw()); } -UVW_INLINE bool Mutex::tryLock() noexcept { - return (0 == uv_mutex_trylock(get())); +UVW_INLINE bool mutex::try_lock() noexcept { + return (0 == uv_mutex_trylock(raw())); } -UVW_INLINE void Mutex::unlock() noexcept { - uv_mutex_unlock(get()); +UVW_INLINE void mutex::unlock() noexcept { + uv_mutex_unlock(raw()); } -UVW_INLINE RWLock::RWLock(UnderlyingType::ConstructorAccess ca, std::shared_ptr ref) noexcept - : UnderlyingType{ca, std::move(ref)} { - uv_rwlock_init(get()); +UVW_INLINE rwlock::rwlock(loop::token token, std::shared_ptr ref) noexcept + : uv_type{token, std::move(ref)} { + uv_rwlock_init(raw()); } -UVW_INLINE RWLock::~RWLock() noexcept { - uv_rwlock_destroy(get()); +UVW_INLINE rwlock::~rwlock() noexcept { + uv_rwlock_destroy(raw()); } -UVW_INLINE void RWLock::rdLock() noexcept { - uv_rwlock_rdlock(get()); +UVW_INLINE void rwlock::rdlock() noexcept { + uv_rwlock_rdlock(raw()); } -UVW_INLINE bool RWLock::tryRdLock() noexcept { - return (0 == uv_rwlock_tryrdlock(get())); +UVW_INLINE bool rwlock::try_rdlock() noexcept { + return (0 == uv_rwlock_tryrdlock(raw())); } -UVW_INLINE void RWLock::rdUnlock() noexcept { - uv_rwlock_rdunlock(get()); +UVW_INLINE void rwlock::rdunlock() noexcept { + uv_rwlock_rdunlock(raw()); } -UVW_INLINE void RWLock::wrLock() noexcept { - uv_rwlock_wrlock(get()); +UVW_INLINE void rwlock::wrlock() noexcept { + uv_rwlock_wrlock(raw()); } -UVW_INLINE bool RWLock::tryWrLock() noexcept { - return (0 == uv_rwlock_trywrlock(get())); +UVW_INLINE bool rwlock::try_wrlock() noexcept { + return (0 == uv_rwlock_trywrlock(raw())); } -UVW_INLINE void RWLock::wrUnlock() noexcept { - uv_rwlock_wrunlock(get()); +UVW_INLINE void rwlock::wrunlock() noexcept { + uv_rwlock_wrunlock(raw()); } -UVW_INLINE Semaphore::Semaphore(UnderlyingType::ConstructorAccess ca, std::shared_ptr ref, unsigned int value) noexcept - : UnderlyingType{ca, std::move(ref)} { - uv_sem_init(get(), value); +UVW_INLINE semaphore::semaphore(loop::token token, std::shared_ptr ref, unsigned int value) noexcept + : uv_type{token, std::move(ref)} { + uv_sem_init(raw(), value); } -UVW_INLINE Semaphore::~Semaphore() noexcept { - uv_sem_destroy(get()); +UVW_INLINE semaphore::~semaphore() noexcept { + uv_sem_destroy(raw()); } -UVW_INLINE void Semaphore::post() noexcept { - uv_sem_post(get()); +UVW_INLINE void semaphore::post() noexcept { + uv_sem_post(raw()); } -UVW_INLINE void Semaphore::wait() noexcept { - uv_sem_wait(get()); +UVW_INLINE void semaphore::wait() noexcept { + uv_sem_wait(raw()); } -UVW_INLINE bool Semaphore::tryWait() noexcept { - return (0 == uv_sem_trywait(get())); +UVW_INLINE bool semaphore::try_wait() noexcept { + return (0 == uv_sem_trywait(raw())); } -UVW_INLINE Condition::Condition(UnderlyingType::ConstructorAccess ca, std::shared_ptr ref) noexcept - : UnderlyingType{ca, std::move(ref)} { - uv_cond_init(get()); +UVW_INLINE condition::condition(loop::token token, std::shared_ptr ref) noexcept + : uv_type{token, std::move(ref)} { + uv_cond_init(raw()); } -UVW_INLINE Condition::~Condition() noexcept { - uv_cond_destroy(get()); +UVW_INLINE condition::~condition() noexcept { + uv_cond_destroy(raw()); } -UVW_INLINE void Condition::signal() noexcept { - uv_cond_signal(get()); +UVW_INLINE void condition::signal() noexcept { + uv_cond_signal(raw()); } -UVW_INLINE void Condition::broadcast() noexcept { - uv_cond_broadcast(get()); +UVW_INLINE void condition::broadcast() noexcept { + uv_cond_broadcast(raw()); } -UVW_INLINE void Condition::wait(Mutex &mutex) noexcept { - uv_cond_wait(get(), mutex.get()); +UVW_INLINE void condition::wait(mutex &mtx) noexcept { + uv_cond_wait(raw(), mtx.raw()); } -UVW_INLINE bool Condition::timedWait(Mutex &mutex, uint64_t timeout) noexcept { - return (0 == uv_cond_timedwait(get(), mutex.get(), timeout)); +UVW_INLINE bool condition::timed_wait(mutex &mtx, uint64_t timeout) noexcept { + return (0 == uv_cond_timedwait(raw(), mtx.raw(), timeout)); } -UVW_INLINE Barrier::Barrier(UnderlyingType::ConstructorAccess ca, std::shared_ptr ref, unsigned int count) noexcept - : UnderlyingType{ca, std::move(ref)} { - uv_barrier_init(get(), count); +UVW_INLINE barrier::barrier(loop::token token, std::shared_ptr ref, unsigned int count) noexcept + : uv_type{token, std::move(ref)} { + uv_barrier_init(raw(), count); } -UVW_INLINE Barrier::~Barrier() noexcept { - uv_barrier_destroy(get()); +UVW_INLINE barrier::~barrier() noexcept { + uv_barrier_destroy(raw()); } -UVW_INLINE bool Barrier::wait() noexcept { - return (0 == uv_barrier_wait(get())); +UVW_INLINE bool barrier::wait() noexcept { + return (0 == uv_barrier_wait(raw())); } } // namespace uvw diff --git a/src/uvw/thread.h b/src/uvw/thread.h index c97ac799..a82e912c 100644 --- a/src/uvw/thread.h +++ b/src/uvw/thread.h @@ -8,55 +8,57 @@ #include #include #include +#include "config.h" +#include "enum.hpp" #include "loop.h" -#include "underlying_type.hpp" +#include "uv_type.hpp" namespace uvw { namespace details { -enum class UVThreadCreateFlags : std::underlying_type_t { +enum class uvw_thread_create_flags : std::underlying_type_t { THREAD_NO_FLAGS = UV_THREAD_NO_FLAGS, THREAD_HAS_STACK_SIZE = UV_THREAD_HAS_STACK_SIZE }; } -class Thread; -class ThreadLocalStorage; -class Once; -class Mutex; -class RWLock; -class Semaphore; -class Condition; -class Barrier; +class thread; +class thread_local_storage; +class once; +class mutex; +class rwlock; +class semaphore; +class condition; +class barrier; /** - * @brief The Thread wrapper. + * @brief The thread wrapper. * - * To create a `Thread` through a `Loop`, arguments follow: + * To create a `thread` through a `loop`, arguments follow: * * * A callback invoked to initialize thread execution. The type must be such * that it can be assigned to an `std::function)>`. * * An optional payload the type of which is `std::shared_ptr`. */ -class Thread final: public UnderlyingType { - using InternalTask = std::function)>; +class thread final: public uv_type { + using internal_task = std::function)>; - static void createCallback(void *arg); + static void create_callback(void *arg); public: - using Options = details::UVThreadCreateFlags; - using Task = InternalTask; - using Type = uv_thread_t; + using create_flags = details::uvw_thread_create_flags; + using task = internal_task; + using type = uv_thread_t; - explicit Thread(ConstructorAccess ca, std::shared_ptr ref, Task t, std::shared_ptr d = nullptr) noexcept; + explicit thread(loop::token token, std::shared_ptr ref, task t, std::shared_ptr d = nullptr) noexcept; /** * @brief Obtains the identifier of the calling thread. * @return The identifier of the calling thread. */ - static Type self() noexcept; + static type self() noexcept; /** * @brief Compares thread by means of their identifiers. @@ -64,9 +66,9 @@ public: * @param tr A valid instance of a thread. * @return True if the two threads are the same thread, false otherwise. */ - static bool equal(const Thread &tl, const Thread &tr) noexcept; + static bool equal(const thread &tl, const thread &tr) noexcept; - ~Thread() noexcept; + ~thread() noexcept; /** * @brief Creates a new thread. @@ -79,15 +81,15 @@ public: * * Available flags are: * - * * `Thread::Options::THREAD_NO_FLAGS`: no flags set. - * * `Thread::Options::THREAD_HAS_STACK_SIZE`: if set, `stack` specifies a + * * `thread::create_flags::THREAD_NO_FLAGS`: no flags set. + * * `thread::create_flags::THREAD_HAS_STACK_SIZE`: if set, `stack` specifies a * stack size for the new thread. 0 indicates that the default value should * be used (it behaves as if the flag was not set). Other values will be * rounded up to the nearest page boundary. * * @return True in case of success, false otherwise. */ - bool run(Flags opts, std::size_t stack = {}) noexcept; + bool run(create_flags opts, std::size_t stack = {}) noexcept; /** * @brief Joins with a terminated thread. @@ -97,21 +99,21 @@ public: private: std::shared_ptr data; - Task task; + task func; }; /** - * @brief The ThreadLocalStorage wrapper. + * @brief The thread local storage wrapper. * * A storage area that can only be accessed by one thread. The variable can be * seen as a global variable that is only visible to a particular thread and not * the whole program. */ -class ThreadLocalStorage final: public UnderlyingType { +class thread_local_storage final: public uv_type { public: - explicit ThreadLocalStorage(ConstructorAccess ca, std::shared_ptr ref) noexcept; + explicit thread_local_storage(loop::token token, std::shared_ptr ref) noexcept; - ~ThreadLocalStorage() noexcept; + ~thread_local_storage() noexcept; /** * @brief Gets the value of a given variable. @@ -120,7 +122,7 @@ public: */ template T *get() noexcept { - return static_cast(uv_key_get(UnderlyingType::get())); + return static_cast(uv_key_get(uv_type::raw())); } /** @@ -130,21 +132,21 @@ public: */ template void set(T *value) noexcept { - return uv_key_set(UnderlyingType::get(), value); + return uv_key_set(uv_type::raw(), value); } }; /** - * @brief The Once wrapper. + * @brief The once wrapper. * * Runs a function once and only once. Concurrent calls to `once` will block all * callers except one (it’s unspecified which one). */ -class Once final: public UnderlyingType { +class once final: public uv_type { static uv_once_t *guard() noexcept; public: - using UnderlyingType::UnderlyingType; + using uv_type::uv_type; /** * @brief Runs a function once and only once. @@ -156,29 +158,29 @@ public: * @param f A valid callback function. */ template - static void once(F &&f) noexcept { - using CallbackType = void (*)(void); - static_assert(std::is_convertible_v); - CallbackType cb = f; + static void run(F &&f) noexcept { + using callback_type = void (*)(void); + static_assert(std::is_convertible_v); + callback_type cb = f; uv_once(guard(), cb); } }; /** - * @brief The Mutex wrapper. + * @brief The mutex wrapper. * - * To create a `Mutex` through a `Loop`, arguments follow: + * To create a `mutex` through a `loop`, arguments follow: * * * An option boolean that specifies if the mutex is a recursive one. The * default value is false, the mutex isn't recursive. */ -class Mutex final: public UnderlyingType { - friend class Condition; +class mutex final: public uv_type { + friend class condition; public: - explicit Mutex(ConstructorAccess ca, std::shared_ptr ref, bool recursive = false) noexcept; + explicit mutex(loop::token token, std::shared_ptr ref, bool recursive = false) noexcept; - ~Mutex() noexcept; + ~mutex() noexcept; /** * @brief Locks the mutex. @@ -189,7 +191,7 @@ public: * @brief Tries to lock the mutex. * @return True in case of success, false otherwise. */ - bool tryLock() noexcept; + bool try_lock() noexcept; /** * @brief Unlocks the mutex. @@ -198,59 +200,59 @@ public: }; /** - * @brief The RWLock wrapper. + * @brief The rwlock wrapper. */ -class RWLock final: public UnderlyingType { +class rwlock final: public uv_type { public: - explicit RWLock(ConstructorAccess ca, std::shared_ptr ref) noexcept; + explicit rwlock(loop::token token, std::shared_ptr ref) noexcept; - ~RWLock() noexcept; + ~rwlock() noexcept; /** * @brief Locks a read-write lock object for reading. */ - void rdLock() noexcept; + void rdlock() noexcept; /** * @brief Tries to lock a read-write lock object for reading. * @return True in case of success, false otherwise. */ - bool tryRdLock() noexcept; + bool try_rdlock() noexcept; /** * @brief Unlocks a read-write lock object previously locked for reading. */ - void rdUnlock() noexcept; + void rdunlock() noexcept; /** * @brief Locks a read-write lock object for writing. */ - void wrLock() noexcept; + void wrlock() noexcept; /** * @brief Tries to lock a read-write lock object for writing. * @return True in case of success, false otherwise. */ - bool tryWrLock() noexcept; + bool try_wrlock() noexcept; /** * @brief Unlocks a read-write lock object previously locked for writing. */ - void wrUnlock() noexcept; + void wrunlock() noexcept; }; /** - * @brief The Semaphore wrapper. + * @brief The semaphore wrapper. * - * To create a `Semaphore` through a `Loop`, arguments follow: + * To create a `semaphore` through a `loop`, arguments follow: * * * An unsigned integer that specifies the initial value for the semaphore. */ -class Semaphore final: public UnderlyingType { +class semaphore final: public uv_type { public: - explicit Semaphore(ConstructorAccess ca, std::shared_ptr ref, unsigned int value) noexcept; + explicit semaphore(loop::token token, std::shared_ptr ref, unsigned int value) noexcept; - ~Semaphore() noexcept; + ~semaphore() noexcept; /** * @brief Unlocks a semaphore. @@ -266,17 +268,17 @@ public: * @brief Tries to lock a semaphore. * @return True in case of success, false otherwise. */ - bool tryWait() noexcept; + bool try_wait() noexcept; }; /** - * @brief The Condition wrapper. + * @brief The condition wrapper. */ -class Condition final: public UnderlyingType { +class condition final: public uv_type { public: - explicit Condition(ConstructorAccess ca, std::shared_ptr ref) noexcept; + explicit condition(loop::token token, std::shared_ptr ref) noexcept; - ~Condition() noexcept; + ~condition() noexcept; /** * @brief Signals a condition. @@ -299,10 +301,10 @@ public: * These function atomically releases the mutex and causes the calling * thread to block on the condition variable. * - * @param mutex A mutex locked by the calling thread, otherwise expect + * @param mtx A mutex locked by the calling thread, otherwise expect * undefined behavior. */ - void wait(Mutex &mutex) noexcept; + void wait(mutex &mtx) noexcept; /** * @brief Waits on a condition. @@ -314,28 +316,28 @@ public: * signaled or broadcasted, or if the absolute time specified has already * been passed at the time of the call. * - * @param mutex A mutex locked by the calling thread, otherwise expect + * @param mtx A mutex locked by the calling thread, otherwise expect * undefined behavior. * @param timeout The maximum time to wait before to return. * @return True in case of success, false otherwise. */ - bool timedWait(Mutex &mutex, uint64_t timeout) noexcept; + bool timed_wait(mutex &mtx, uint64_t timeout) noexcept; }; /** - * @brief The Barrier wrapper. + * @brief The barrier wrapper. * - * To create a `Barrier` through a `Loop`, arguments follow: + * To create a `barrier` through a `loop`, arguments follow: * * * An unsigned integer that specifies the number of threads that must call * `wait` before any of them successfully return from the call. The value * specified must be greater than zero. */ -class Barrier final: public UnderlyingType { +class barrier final: public uv_type { public: - explicit Barrier(ConstructorAccess ca, std::shared_ptr ref, unsigned int count) noexcept; + explicit barrier(loop::token token, std::shared_ptr ref, unsigned int count) noexcept; - ~Barrier() noexcept; + ~barrier() noexcept; /** * @brief Synchronizes at a barrier. diff --git a/src/uvw/timer.cpp b/src/uvw/timer.cpp index bde69488..6db6dec6 100644 --- a/src/uvw/timer.cpp +++ b/src/uvw/timer.cpp @@ -6,37 +6,37 @@ namespace uvw { -UVW_INLINE void TimerHandle::startCallback(uv_timer_t *handle) { - TimerHandle &timer = *(static_cast(handle->data)); - timer.publish(TimerEvent{}); +UVW_INLINE void timer_handle::start_callback(uv_timer_t *hndl) { + timer_handle &timer = *(static_cast(hndl->data)); + timer.publish(timer_event{}); } -UVW_INLINE bool TimerHandle::init() { - return initialize(&uv_timer_init); +UVW_INLINE int timer_handle::init() { + return leak_if(uv_timer_init(parent().raw(), raw())); } -UVW_INLINE void TimerHandle::start(TimerHandle::Time timeout, TimerHandle::Time repeat) { - invoke(&uv_timer_start, get(), &startCallback, timeout.count(), repeat.count()); +UVW_INLINE int timer_handle::start(timer_handle::time timeout, timer_handle::time repeat) { + return uv_timer_start(raw(), &start_callback, timeout.count(), repeat.count()); } -UVW_INLINE void TimerHandle::stop() { - invoke(&uv_timer_stop, get()); +UVW_INLINE int timer_handle::stop() { + return uv_timer_stop(raw()); } -UVW_INLINE void TimerHandle::again() { - invoke(&uv_timer_again, get()); +UVW_INLINE int timer_handle::again() { + return uv_timer_again(raw()); } -UVW_INLINE void TimerHandle::repeat(TimerHandle::Time repeat) { - uv_timer_set_repeat(get(), repeat.count()); +UVW_INLINE void timer_handle::repeat(timer_handle::time repeat) { + uv_timer_set_repeat(raw(), repeat.count()); } -UVW_INLINE TimerHandle::Time TimerHandle::repeat() { - return Time{uv_timer_get_repeat(get())}; +UVW_INLINE timer_handle::time timer_handle::repeat() { + return time{uv_timer_get_repeat(raw())}; } -UVW_INLINE TimerHandle::Time TimerHandle::dueIn() { - return Time{uv_timer_get_due_in(get())}; +UVW_INLINE timer_handle::time timer_handle::due_in() { + return time{uv_timer_get_due_in(raw())}; } } // namespace uvw diff --git a/src/uvw/timer.h b/src/uvw/timer.h index 5aa89162..6fad9ec1 100644 --- a/src/uvw/timer.h +++ b/src/uvw/timer.h @@ -9,61 +9,61 @@ namespace uvw { -/** - * @brief TimerEvent event. - * - * It will be emitted by TimerHandle according with its functionalities. - */ -struct TimerEvent {}; +/*! @brief Timer event. */ +struct timer_event {}; /** - * @brief The TimerHandle handle. + * @brief The timer handle. * * Timer handles are used to schedule events to be emitted in the future. * - * To create a `TimerHandle` through a `Loop`, no arguments are required. + * To create a `timer_handle` through a `loop`, no arguments are required. */ -class TimerHandle final: public Handle { - static void startCallback(uv_timer_t *handle); +class timer_handle final: public handle { + static void start_callback(uv_timer_t *hndl); public: - using Time = std::chrono::duration; + using time = std::chrono::duration; - using Handle::Handle; + using handle::handle; /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Starts the timer. * - * If timeout is zero, a TimerEvent event is emitted on the next event loop - * iteration. If repeat is non-zero, a TimerEvent event is emitted first - * after timeout milliseconds and then repeatedly after repeat milliseconds. + * If timeout is zero, a timer event is emitted on the next event loop + * iteration. If repeat is non-zero, a timer event is emitted first after + * timeout milliseconds and then repeatedly after repeat milliseconds. * * @param timeout Milliseconds before to emit an event (use * `std::chrono::duration`). * @param repeat Milliseconds between successive events (use * `std::chrono::duration`). + * + * @return Underlying return value. */ - void start(Time timeout, Time repeat); + int start(time timeout, time repeat); /** * @brief Stops the handle. + * @return Underlying return value. */ - void stop(); + int stop(); /** * @brief Stops the timer and restarts it if it was repeating. * * Stop the timer, and if it is repeating restart it using the repeat value - * as the timeout.
- * If the timer has never been started before it emits an ErrorEvent event. + * as the timeout. + * + * @return Underlying return value. */ - void again(); + int again(); /** * @brief Sets the repeat interval value. @@ -83,23 +83,23 @@ public: * @param repeat Repeat interval in milliseconds (use * `std::chrono::duration`). */ - void repeat(Time repeat); + void repeat(time repeat); /** * @brief Gets the timer repeat value. * @return Timer repeat value in milliseconds (as a * `std::chrono::duration`). */ - Time repeat(); + time repeat(); /** * @brief Gets the timer due value. * - * The time is relative to `Loop::now()`. + * The time is relative to `loop::now()`. * * @return The timer due value or 0 if it has expired. */ - Time dueIn(); + time due_in(); }; } // namespace uvw diff --git a/src/uvw/tty.cpp b/src/uvw/tty.cpp index 88f95326..09e83a4f 100644 --- a/src/uvw/tty.cpp +++ b/src/uvw/tty.cpp @@ -3,44 +3,43 @@ #endif #include - #include "config.h" namespace uvw { -UVW_INLINE details::ResetModeMemo::~ResetModeMemo() { +UVW_INLINE details::reset_mode_memo::~reset_mode_memo() { uv_tty_reset_mode(); } -UVW_INLINE TTYHandle::TTYHandle(ConstructorAccess ca, std::shared_ptr ref, FileHandle desc, bool readable) - : StreamHandle{ca, std::move(ref)}, - memo{resetModeMemo()}, +UVW_INLINE tty_handle::tty_handle(loop::token token, std::shared_ptr ref, file_handle desc, bool readable) + : stream_handle{token, std::move(ref)}, + memo{mode_memo_handler()}, fd{desc}, rw{readable} {} -UVW_INLINE std::shared_ptr TTYHandle::resetModeMemo() { - static std::weak_ptr weak; +UVW_INLINE std::shared_ptr tty_handle::mode_memo_handler() { + static std::weak_ptr weak; auto shared = weak.lock(); - if(!shared) { weak = shared = std::make_shared(); } + if(!shared) { weak = shared = std::make_shared(); } return shared; }; -UVW_INLINE bool TTYHandle::init() { - return initialize(&uv_tty_init, fd, rw); +UVW_INLINE int tty_handle::init() { + return leak_if(uv_tty_init(parent().raw(), raw(), fd, rw)); } -UVW_INLINE bool TTYHandle::mode(TTYHandle::Mode m) { - return (0 == uv_tty_set_mode(get(), static_cast>(m))); +UVW_INLINE bool tty_handle::mode(tty_handle::tty_mode m) { + return (0 == uv_tty_set_mode(raw(), static_cast(m))); } -UVW_INLINE bool TTYHandle::reset() noexcept { +UVW_INLINE bool tty_handle::reset_mode() noexcept { return (0 == uv_tty_reset_mode()); } -UVW_INLINE WinSize TTYHandle::getWinSize() { - WinSize size; +UVW_INLINE win_size tty_handle::get_win_size() { + win_size size; - if(0 != uv_tty_get_winsize(get(), &size.width, &size.height)) { + if(0 != uv_tty_get_winsize(raw(), &size.width, &size.height)) { size.width = -1; size.height = -1; } @@ -48,21 +47,21 @@ UVW_INLINE WinSize TTYHandle::getWinSize() { return size; } -UVW_INLINE void TTYHandle::vtermState(TTYHandle::VTermState s) const noexcept { +UVW_INLINE void tty_handle::vterm_state(tty_handle::tty_vtermstate s) const noexcept { switch(s) { - case VTermState::SUPPORTED: + case tty_vtermstate::SUPPORTED: uv_tty_set_vterm_state(uv_tty_vtermstate_t::UV_TTY_SUPPORTED); break; - case VTermState::UNSUPPORTED: + case tty_vtermstate::UNSUPPORTED: uv_tty_set_vterm_state(uv_tty_vtermstate_t::UV_TTY_UNSUPPORTED); break; } } -UVW_INLINE TTYHandle::VTermState TTYHandle::vtermState() const noexcept { +UVW_INLINE tty_handle::tty_vtermstate tty_handle::vterm_state() const noexcept { uv_tty_vtermstate_t state; uv_tty_get_vterm_state(&state); - return VTermState{state}; + return tty_vtermstate{state}; } } // namespace uvw diff --git a/src/uvw/tty.h b/src/uvw/tty.h index 0563e5e7..387585d2 100644 --- a/src/uvw/tty.h +++ b/src/uvw/tty.h @@ -4,6 +4,7 @@ #include #include #include +#include "config.h" #include "stream.h" #include "util.h" @@ -11,17 +12,17 @@ namespace uvw { namespace details { -struct ResetModeMemo { - ~ResetModeMemo(); +struct reset_mode_memo { + ~reset_mode_memo(); }; -enum class UVTTYModeT : std::underlying_type_t { +enum class uvw_tty_mode_t : std::underlying_type_t { NORMAL = UV_TTY_MODE_NORMAL, RAW = UV_TTY_MODE_RAW, IO = UV_TTY_MODE_IO }; -enum class UVTTYVTermStateT : std::underlying_type_t { +enum class uvw_tty_vtermstate_t : std::underlying_type_t { SUPPORTED = UV_TTY_SUPPORTED, UNSUPPORTED = UV_TTY_UNSUPPORTED }; @@ -29,16 +30,16 @@ enum class UVTTYVTermStateT : std::underlying_type_t { } // namespace details /** - * @brief The TTYHandle handle. + * @brief The tty handle. * * TTY handles represent a stream for the console. * - * To create a `TTYHandle` through a `Loop`, arguments follow: + * To create a `tty_handle` through a `loop`, arguments follow: * - * * A valid FileHandle. Usually the file descriptor will be: - * * `uvw::StdIN` or `0` for `stdin` - * * `uvw::StdOUT` or `1` for `stdout` - * * `uvw::StdERR` or `2` for `stderr` + * * A valid file_handle. Usually the file descriptor will be: + * * `uvw::std_in` or `0` for `stdin` + * * `uvw::std_out` or `1` for `stdout` + * * `uvw::std_err` or `2` for `stderr` * * A boolean value that specifies the plan on calling `read()` with this * stream. Remember that `stdin` is readable, `stdout` is not. * @@ -46,29 +47,29 @@ enum class UVTTYVTermStateT : std::underlying_type_t { * [documentation](http://docs.libuv.org/en/v1.x/tty.html#c.uv_tty_init) * for further details. */ -class TTYHandle final: public StreamHandle { - static std::shared_ptr resetModeMemo(); +class tty_handle final: public stream_handle { + static std::shared_ptr mode_memo_handler(); public: - using Mode = details::UVTTYModeT; - using VTermState = details::UVTTYVTermStateT; + using tty_mode = details::uvw_tty_mode_t; + using tty_vtermstate = details::uvw_tty_vtermstate_t; - explicit TTYHandle(ConstructorAccess ca, std::shared_ptr ref, FileHandle desc, bool readable); + explicit tty_handle(loop::token token, std::shared_ptr ref, file_handle desc, bool readable); /** * @brief Initializes the handle. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Sets the TTY using the specified terminal mode. * * Available modes are: * - * * `TTY::Mode::NORMAL` - * * `TTY::Mode::RAW` - * * `TTY::Mode::IO` + * * `TTY::tty_mode::NORMAL` + * * `TTY::tty_mode::RAW` + * * `TTY::tty_mode::IO` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/tty.html#c.uv_tty_mode_t) @@ -77,19 +78,19 @@ public: * @param m The mode to be set. * @return True in case of success, false otherwise. */ - bool mode(Mode m); + bool mode(tty_mode m); /** * @brief Resets TTY settings to default values. * @return True in case of success, false otherwise. */ - bool reset() noexcept; + bool reset_mode() noexcept; /** * @brief Gets the current Window size. * @return The current Window size or `{-1, -1}` in case of errors. */ - WinSize getWinSize(); + win_size get_win_size(); /** * @brief Controls whether console virtual terminal sequences are processed @@ -100,8 +101,8 @@ public: * * Available states are: * - * * `TTY::VTermState::SUPPORTED` - * * `TTY::VTermState::UNSUPPORTED` + * * `TTY::tty_vtermstate::SUPPORTED` + * * `TTY::tty_vtermstate::UNSUPPORTED` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/tty.html#c.uv_tty_vtermstate_t) @@ -109,7 +110,7 @@ public: * * @param s The state to be set. */ - void vtermState(VTermState s) const noexcept; + void vterm_state(tty_vtermstate s) const noexcept; /** * @brief Gets the current state of whether console virtual terminal @@ -119,8 +120,8 @@ public: * * Available states are: * - * * `TTY::VTermState::SUPPORTED` - * * `TTY::VTermState::UNSUPPORTED` + * * `TTY::tty_vtermstate::SUPPORTED` + * * `TTY::tty_vtermstate::UNSUPPORTED` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/tty.html#c.uv_tty_vtermstate_t) @@ -128,11 +129,11 @@ public: * * @return The current state. */ - VTermState vtermState() const noexcept; + tty_vtermstate vterm_state() const noexcept; private: - std::shared_ptr memo; - FileHandle::Type fd; + std::shared_ptr memo; + file_handle fd; int rw; }; diff --git a/src/uvw/type_info.hpp b/src/uvw/type_info.hpp index 479e9972..176dea85 100644 --- a/src/uvw/type_info.hpp +++ b/src/uvw/type_info.hpp @@ -1,9 +1,8 @@ #ifndef UVW_TYPE_INFO_INCLUDE_HPP #define UVW_TYPE_INFO_INCLUDE_HPP -#include #include -#include +#include "config.h" namespace uvw { diff --git a/src/uvw/udp.cpp b/src/uvw/udp.cpp index 84aa596b..fa48bbee 100644 --- a/src/uvw/udp.cpp +++ b/src/uvw/udp.cpp @@ -6,274 +6,211 @@ namespace uvw { -UVW_INLINE UDPDataEvent::UDPDataEvent(Addr sndr, std::unique_ptr buf, std::size_t len, bool part) noexcept - : data{std::move(buf)}, length{len}, sender{std::move(sndr)}, partial{part} {} +UVW_INLINE udp_data_event::udp_data_event(socket_address sndr, std::unique_ptr buf, std::size_t len, bool part) noexcept + : data{std::move(buf)}, + length{len}, + sender{std::move(sndr)}, + partial{part} {} -UVW_INLINE details::SendReq::SendReq(ConstructorAccess ca, std::shared_ptr loop, std::unique_ptr dt, unsigned int len) - : Request{ca, std::move(loop)}, +UVW_INLINE void details::send_req::udp_send_callback(uv_udp_send_t *req, int status) { + if(auto ptr = reserve(req); status) { + ptr->publish(error_event{status}); + } else { + ptr->publish(send_event{}); + } +} + +UVW_INLINE details::send_req::send_req(loop::token token, std::shared_ptr parent, std::unique_ptr dt, unsigned int len) + : request{token, std::move(parent)}, data{std::move(dt)}, buf{uv_buf_init(data.get(), len)} {} -UVW_INLINE void details::SendReq::send(uv_udp_t *handle, const struct sockaddr *addr) { - invoke(&uv_udp_send, get(), handle, &buf, 1, addr, &defaultCallback); +UVW_INLINE int details::send_req::send(uv_udp_t *hndl, const struct sockaddr *addr) { + return this->leak_if(uv_udp_send(raw(), hndl, &buf, 1, addr, &udp_send_callback)); } -UVW_INLINE UDPHandle::UDPHandle(ConstructorAccess ca, std::shared_ptr ref, unsigned int f) - : Handle{ca, std::move(ref)}, tag{FLAGS}, flags{f} {} +UVW_INLINE void udp_handle::recv_callback(uv_udp_t *hndl, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) { + udp_handle &udp = *(static_cast(hndl->data)); + // data will be destroyed no matter of what the value of nread is + std::unique_ptr data{buf->base}; -UVW_INLINE bool UDPHandle::init() { - return (tag == FLAGS) ? initialize(&uv_udp_init_ex, flags) : initialize(&uv_udp_init); + if(nread > 0) { + // data available (can be truncated) + udp.publish(udp_data_event{details::sock_addr(*addr), std::move(data), static_cast(nread), !(0 == (flags & UV_UDP_PARTIAL))}); + } else if(nread == 0 && addr == nullptr) { + // no more data to be read, doing nothing is fine + } else if(nread == 0 && addr != nullptr) { + // empty udp packet + udp.publish(udp_data_event{details::sock_addr(*addr), std::move(data), static_cast(nread), false}); + } else { + // transmission error + udp.publish(error_event(nread)); + } } -UVW_INLINE void UDPHandle::open(OSSocketHandle socket) { - invoke(&uv_udp_open, get(), socket); +UVW_INLINE udp_handle::udp_handle(loop::token token, std::shared_ptr ref, unsigned int f) + : handle{token, std::move(ref)}, tag{FLAGS}, flags{f} {} + +UVW_INLINE int udp_handle::init() { + if(tag == FLAGS) { + return leak_if(uv_udp_init_ex(parent().raw(), raw(), flags)); + } else { + return leak_if(uv_udp_init(parent().raw(), raw())); + } } -UVW_INLINE void UDPHandle::bind(const sockaddr &addr, Flags opts) { - invoke(&uv_udp_bind, get(), &addr, opts); +UVW_INLINE int udp_handle::open(os_socket_handle socket) { + return uv_udp_open(raw(), socket); } -UVW_INLINE void UDPHandle::connect(const sockaddr &addr) { - invoke(&uv_udp_connect, get(), &addr); +UVW_INLINE int udp_handle::connect(const sockaddr &addr) { + return uv_udp_connect(raw(), &addr); } -template -UVW_INLINE void UDPHandle::connect(const std::string &ip, unsigned int port) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - connect(reinterpret_cast(addr)); +UVW_INLINE int udp_handle::connect(const std::string &ip, unsigned int port) { + return connect(details::ip_addr(ip.data(), port)); } -template -UVW_INLINE void UDPHandle::connect(Addr addr) { - connect(std::move(addr.ip), addr.port); +UVW_INLINE int udp_handle::connect(socket_address addr) { + return connect(addr.ip, addr.port); } -UVW_INLINE void UDPHandle::disconnect() { - invoke(&uv_udp_connect, get(), nullptr); +UVW_INLINE int udp_handle::disconnect() { + return uv_udp_connect(raw(), nullptr); } -template -UVW_INLINE Addr UDPHandle::peer() const noexcept { - return details::address(&uv_udp_getpeername, get()); +UVW_INLINE socket_address udp_handle::peer() const noexcept { + sockaddr_storage storage; + int len = sizeof(sockaddr_storage); + uv_udp_getpeername(raw(), reinterpret_cast(&storage), &len); + return details::sock_addr(storage); } -template -UVW_INLINE void UDPHandle::bind(const std::string &ip, unsigned int port, Flags opts) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - bind(reinterpret_cast(addr), std::move(opts)); +UVW_INLINE int udp_handle::bind(const sockaddr &addr, udp_handle::udp_flags opts) { + return uv_udp_bind(raw(), &addr, static_cast(opts)); } -template -UVW_INLINE void UDPHandle::bind(Addr addr, Flags opts) { - bind(std::move(addr.ip), addr.port, std::move(opts)); +UVW_INLINE int udp_handle::bind(const std::string &ip, unsigned int port, udp_flags opts) { + return bind(details::ip_addr(ip.data(), port), opts); } -template -UVW_INLINE Addr UDPHandle::sock() const noexcept { - return details::address(&uv_udp_getsockname, get()); +UVW_INLINE int udp_handle::bind(socket_address addr, udp_flags opts) { + return bind(addr.ip, addr.port, opts); } -template -UVW_INLINE bool UDPHandle::multicastMembership(const std::string &multicast, const std::string &iface, Membership membership) { - return (0 == uv_udp_set_membership(get(), multicast.data(), iface.data(), static_cast(membership))); +UVW_INLINE socket_address udp_handle::sock() const noexcept { + sockaddr_storage storage; + int len = sizeof(sockaddr_storage); + uv_udp_getsockname(raw(), reinterpret_cast(&storage), &len); + return details::sock_addr(storage); } -UVW_INLINE bool UDPHandle::multicastLoop(bool enable) { - return (0 == uv_udp_set_multicast_loop(get(), enable)); +UVW_INLINE bool udp_handle::multicast_membership(const std::string &multicast, const std::string &iface, membership ms) { + return (0 == uv_udp_set_membership(raw(), multicast.data(), iface.data(), static_cast(ms))); } -UVW_INLINE bool UDPHandle::multicastTtl(int val) { - return (0 == uv_udp_set_multicast_ttl(get(), val > 255 ? 255 : val)); +UVW_INLINE bool udp_handle::multicast_loop(bool enable) { + return (0 == uv_udp_set_multicast_loop(raw(), enable)); } -template -UVW_INLINE bool UDPHandle::multicastInterface(const std::string &iface) { - return (0 == uv_udp_set_multicast_interface(get(), iface.data())); +UVW_INLINE bool udp_handle::multicast_ttl(int val) { + return (0 == uv_udp_set_multicast_ttl(raw(), val > 255 ? 255 : val)); } -UVW_INLINE bool UDPHandle::broadcast(bool enable) { - return (0 == uv_udp_set_broadcast(get(), enable)); +UVW_INLINE bool udp_handle::multicast_interface(const std::string &iface) { + return (0 == uv_udp_set_multicast_interface(raw(), iface.data())); } -UVW_INLINE bool UDPHandle::ttl(int val) { - return (0 == uv_udp_set_ttl(get(), val > 255 ? 255 : val)); +UVW_INLINE bool udp_handle::broadcast(bool enable) { + return (0 == uv_udp_set_broadcast(raw(), enable)); } -UVW_INLINE void UDPHandle::send(const sockaddr &addr, std::unique_ptr data, unsigned int len) { - auto req = loop().resource(std::unique_ptr{data.release(), [](char *ptr) { delete[] ptr; }}, len); +UVW_INLINE bool udp_handle::ttl(int val) { + return (0 == uv_udp_set_ttl(raw(), val > 255 ? 255 : val)); +} + +UVW_INLINE int udp_handle::send(const sockaddr &addr, std::unique_ptr data, unsigned int len) { + auto req = parent().resource(std::unique_ptr{data.release(), [](char *ptr) { delete[] ptr; }}, len); auto listener = [ptr = shared_from_this()](const auto &event, const auto &) { ptr->publish(event); }; - req->once(listener); - req->once(listener); - req->send(get(), &addr); + req->on(listener); + req->on(listener); + + return req->send(raw(), &addr); } -template -UVW_INLINE void UDPHandle::send(const std::string &ip, unsigned int port, std::unique_ptr data, unsigned int len) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - send(reinterpret_cast(addr), std::move(data), len); +UVW_INLINE int udp_handle::send(const std::string &ip, unsigned int port, std::unique_ptr data, unsigned int len) { + return send(details::ip_addr(ip.data(), port), std::move(data), len); } -template -UVW_INLINE void UDPHandle::send(Addr addr, std::unique_ptr data, unsigned int len) { - send(std::move(addr.ip), addr.port, std::move(data), len); +UVW_INLINE int udp_handle::send(socket_address addr, std::unique_ptr data, unsigned int len) { + return send(addr.ip, addr.port, std::move(data), len); } -UVW_INLINE void UDPHandle::send(const sockaddr &addr, char *data, unsigned int len) { - auto req = loop().resource(std::unique_ptr{data, [](char *) {}}, len); +UVW_INLINE int udp_handle::send(const sockaddr &addr, char *data, unsigned int len) { + auto req = parent().resource(std::unique_ptr{data, [](char *) {}}, len); auto listener = [ptr = shared_from_this()](const auto &event, const auto &) { ptr->publish(event); }; - req->once(listener); - req->once(listener); - req->send(get(), &addr); + req->on(listener); + req->on(listener); + + return req->send(raw(), &addr); } -template -UVW_INLINE void UDPHandle::send(const std::string &ip, unsigned int port, char *data, unsigned int len) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - send(reinterpret_cast(addr), data, len); +UVW_INLINE int udp_handle::send(const std::string &ip, unsigned int port, char *data, unsigned int len) { + return send(details::ip_addr(ip.data(), port), data, len); } -template -UVW_INLINE void UDPHandle::send(Addr addr, char *data, unsigned int len) { - send(std::move(addr.ip), addr.port, data, len); +UVW_INLINE int udp_handle::send(socket_address addr, char *data, unsigned int len) { + return send(addr.ip, addr.port, data, len); } -template -UVW_INLINE int UDPHandle::trySend(const sockaddr &addr, std::unique_ptr data, unsigned int len) { +UVW_INLINE int udp_handle::try_send(const sockaddr &addr, std::unique_ptr data, unsigned int len) { uv_buf_t bufs[] = {uv_buf_init(data.get(), len)}; - auto bw = uv_udp_try_send(get(), bufs, 1, &addr); - - if(bw < 0) { - publish(ErrorEvent{bw}); - bw = 0; - } - - return bw; + return uv_udp_try_send(raw(), bufs, 1, &addr); } -template -UVW_INLINE int UDPHandle::trySend(const std::string &ip, unsigned int port, std::unique_ptr data, unsigned int len) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - return trySend(reinterpret_cast(addr), std::move(data), len); +UVW_INLINE int udp_handle::try_send(const std::string &ip, unsigned int port, std::unique_ptr data, unsigned int len) { + return try_send(details::ip_addr(ip.data(), port), std::move(data), len); } -template -UVW_INLINE int UDPHandle::trySend(Addr addr, std::unique_ptr data, unsigned int len) { - return trySend(std::move(addr.ip), addr.port, std::move(data), len); +UVW_INLINE int udp_handle::try_send(socket_address addr, std::unique_ptr data, unsigned int len) { + return try_send(addr.ip, addr.port, std::move(data), len); } -template -UVW_INLINE int UDPHandle::trySend(const sockaddr &addr, char *data, unsigned int len) { +UVW_INLINE int udp_handle::try_send(const sockaddr &addr, char *data, unsigned int len) { uv_buf_t bufs[] = {uv_buf_init(data, len)}; - auto bw = uv_udp_try_send(get(), bufs, 1, &addr); - - if(bw < 0) { - publish(ErrorEvent{bw}); - bw = 0; - } - - return bw; + return uv_udp_try_send(raw(), bufs, 1, &addr); } -template -UVW_INLINE int UDPHandle::trySend(const std::string &ip, unsigned int port, char *data, unsigned int len) { - typename details::IpTraits::Type addr; - details::IpTraits::addrFunc(ip.data(), port, &addr); - return trySend(reinterpret_cast(addr), data, len); +UVW_INLINE int udp_handle::try_send(const std::string &ip, unsigned int port, char *data, unsigned int len) { + return try_send(details::ip_addr(ip.data(), port), data, len); } -template -UVW_INLINE int UDPHandle::trySend(Addr addr, char *data, unsigned int len) { - return trySend(std::move(addr.ip), addr.port, data, len); +UVW_INLINE int udp_handle::try_send(socket_address addr, char *data, unsigned int len) { + return try_send(addr.ip, addr.port, data, len); } -template -UVW_INLINE void UDPHandle::recv() { - invoke(&uv_udp_recv_start, get(), &allocCallback, &recvCallback); +UVW_INLINE int udp_handle::recv() { + return uv_udp_recv_start(raw(), &details::common_alloc_callback, &recv_callback); } -UVW_INLINE void UDPHandle::stop() { - invoke(&uv_udp_recv_stop, get()); +UVW_INLINE int udp_handle::stop() { + return uv_udp_recv_stop(raw()); } -UVW_INLINE size_t UDPHandle::sendQueueSize() const noexcept { - return uv_udp_get_send_queue_size(get()); +UVW_INLINE size_t udp_handle::send_queue_size() const noexcept { + return uv_udp_get_send_queue_size(raw()); } -UVW_INLINE size_t UDPHandle::sendQueueCount() const noexcept { - return uv_udp_get_send_queue_count(get()); +UVW_INLINE size_t udp_handle::send_queue_count() const noexcept { + return uv_udp_get_send_queue_count(raw()); } -// explicit instantiations -#ifdef UVW_AS_LIB -template void UDPHandle::connect(const std::string &, unsigned int); -template void UDPHandle::connect(const std::string &, unsigned int); - -template void UDPHandle::connect(Addr); -template void UDPHandle::connect(Addr); - -template Addr UDPHandle::peer() const noexcept; -template Addr UDPHandle::peer() const noexcept; - -template void UDPHandle::bind(const std::string &, unsigned int, Flags); -template void UDPHandle::bind(const std::string &, unsigned int, Flags); - -template void UDPHandle::bind(Addr, Flags); -template void UDPHandle::bind(Addr, Flags); - -template Addr UDPHandle::sock() const noexcept; -template Addr UDPHandle::sock() const noexcept; - -template bool UDPHandle::multicastMembership(const std::string &, const std::string &, Membership); -template bool UDPHandle::multicastMembership(const std::string &, const std::string &, Membership); - -template bool UDPHandle::multicastInterface(const std::string &); -template bool UDPHandle::multicastInterface(const std::string &); - -template void UDPHandle::send(const std::string &, unsigned int, std::unique_ptr, unsigned int); -template void UDPHandle::send(const std::string &, unsigned int, std::unique_ptr, unsigned int); - -template void UDPHandle::send(Addr, std::unique_ptr, unsigned int); -template void UDPHandle::send(Addr, std::unique_ptr, unsigned int); - -template void UDPHandle::send(const std::string &, unsigned int, char *, unsigned int); -template void UDPHandle::send(const std::string &, unsigned int, char *, unsigned int); - -template void UDPHandle::send(Addr, char *, unsigned int); -template void UDPHandle::send(Addr, char *, unsigned int); - -template int UDPHandle::trySend(const sockaddr &, std::unique_ptr, unsigned int); -template int UDPHandle::trySend(const sockaddr &, std::unique_ptr, unsigned int); - -template int UDPHandle::trySend(const std::string &, unsigned int, std::unique_ptr, unsigned int); -template int UDPHandle::trySend(const std::string &, unsigned int, std::unique_ptr, unsigned int); - -template int UDPHandle::trySend(Addr, std::unique_ptr, unsigned int); -template int UDPHandle::trySend(Addr, std::unique_ptr, unsigned int); - -template int UDPHandle::trySend(const sockaddr &, char *, unsigned int); -template int UDPHandle::trySend(const sockaddr &, char *, unsigned int); - -template int UDPHandle::trySend(const std::string &, unsigned int, char *, unsigned int); -template int UDPHandle::trySend(const std::string &, unsigned int, char *, unsigned int); - -template int UDPHandle::trySend(Addr, char *, unsigned int); -template int UDPHandle::trySend(Addr, char *, unsigned int); - -template void UDPHandle::recv(); -template void UDPHandle::recv(); -#endif // UVW_AS_LIB - } // namespace uvw diff --git a/src/uvw/udp.h b/src/uvw/udp.h index bca4bc05..c6b276d5 100644 --- a/src/uvw/udp.h +++ b/src/uvw/udp.h @@ -7,73 +7,70 @@ #include #include #include +#include "config.h" +#include "enum.hpp" #include "handle.hpp" #include "request.hpp" #include "util.h" namespace uvw { -/** - * @brief SendEvent event. - * - * It will be emitted by UDPHandle according with its functionalities. - */ -struct SendEvent {}; +/*! @brief Send event. */ +struct send_event {}; -/** - * @brief UDPDataEvent event. - * - * It will be emitted by UDPHandle according with its functionalities. - */ -struct UDPDataEvent { - explicit UDPDataEvent(Addr sndr, std::unique_ptr buf, std::size_t len, bool part) noexcept; +/*! @brief UDP data event. */ +struct udp_data_event { + explicit udp_data_event(socket_address sndr, std::unique_ptr buf, std::size_t len, bool part) noexcept; std::unique_ptr data; /*!< A bunch of data read on the stream. */ std::size_t length; /*!< The amount of data read on the stream. */ - Addr sender; /*!< A valid instance of Addr. */ + socket_address sender; /*!< A valid instance of socket_address. */ bool partial; /*!< True if the message was truncated, false otherwise. */ }; namespace details { -enum class UVUDPFlags : std::underlying_type_t { +enum class uvw_udp_flags : std::underlying_type_t { IPV6ONLY = UV_UDP_IPV6ONLY, UDP_PARTIAL = UV_UDP_PARTIAL, REUSEADDR = UV_UDP_REUSEADDR, UDP_MMSG_CHUNK = UV_UDP_MMSG_CHUNK, UDP_MMSG_FREE = UV_UDP_MMSG_FREE, UDP_LINUX_RECVERR = UV_UDP_LINUX_RECVERR, - UDP_RECVMMSG = UV_UDP_RECVMMSG + UDP_RECVMMSG = UV_UDP_RECVMMSG, + _UVW_ENUM = 0 }; -enum class UVMembership : std::underlying_type_t { +enum class uvw_membership : std::underlying_type_t { LEAVE_GROUP = UV_LEAVE_GROUP, JOIN_GROUP = UV_JOIN_GROUP }; -class SendReq final: public Request { +class send_req final: public request { + static void udp_send_callback(uv_udp_send_t *req, int status); + public: - using Deleter = void (*)(char *); + using deleter = void (*)(char *); - SendReq(ConstructorAccess ca, std::shared_ptr loop, std::unique_ptr dt, unsigned int len); + send_req(loop::token token, std::shared_ptr parent, std::unique_ptr dt, unsigned int len); - void send(uv_udp_t *handle, const struct sockaddr *addr); + int send(uv_udp_t *hndl, const struct sockaddr *addr); private: - std::unique_ptr data; + std::unique_ptr data; uv_buf_t buf; }; } // namespace details /** - * @brief The UDPHandle handle. + * @brief The UDP handle. * * UDP handles encapsulate UDP communication for both clients and servers.
- * By default, _IPv4_ is used as a template parameter. The handle already - * supports _IPv6_ out-of-the-box by using `uvw::IPv6`. + * By default, _ipv4_ is used as a template parameter. The handle already + * supports _IPv6_ out-of-the-box by using `uvw::ipv6`. * - * To create an `UDPHandle` through a `Loop`, arguments follow: + * To create an `udp_handle` through a `loop`, arguments follow: * * * An optional integer value that indicates optional flags used to initialize * the socket. @@ -82,42 +79,22 @@ private: * [documentation](http://docs.libuv.org/en/v1.x/udp.html#c.uv_udp_init_ex) * for further details. */ -class UDPHandle final: public Handle { - template - static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) { - const typename details::IpTraits::Type *aptr = reinterpret_cast::Type *>(addr); - - UDPHandle &udp = *(static_cast(handle->data)); - // data will be destroyed no matter of what the value of nread is - std::unique_ptr data{buf->base}; - - if(nread > 0) { - // data available (can be truncated) - udp.publish(UDPDataEvent{details::address(aptr), std::move(data), static_cast(nread), !(0 == (flags & UV_UDP_PARTIAL))}); - } else if(nread == 0 && addr == nullptr) { - // no more data to be read, doing nothing is fine - } else if(nread == 0 && addr != nullptr) { - // empty udp packet - udp.publish(UDPDataEvent{details::address(aptr), std::move(data), static_cast(nread), false}); - } else { - // transmission error - udp.publish(ErrorEvent(nread)); - } - } +class udp_handle final: public handle { + static void recv_callback(uv_udp_t *hndl, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags); public: - using Membership = details::UVMembership; - using Bind = details::UVUDPFlags; - using IPv4 = uvw::IPv4; - using IPv6 = uvw::IPv6; + using membership = details::uvw_membership; + using udp_flags = details::uvw_udp_flags; + using ipv4 = uvw::ipv4; + using ipv6 = uvw::ipv6; - explicit UDPHandle(ConstructorAccess ca, std::shared_ptr ref, unsigned int f = {}); + explicit udp_handle(loop::token token, std::shared_ptr ref, unsigned int f = {}); /** * @brief Initializes the handle. The actual socket is created lazily. - * @return True in case of success, false otherwise. + * @return Underlying return value. */ - bool init(); + int init() final; /** * @brief Opens an existing file descriptor or SOCKET as a UDP handle. @@ -129,22 +106,84 @@ public: * [documentation](http://docs.libuv.org/en/v1.x/udp.html#c.uv_udp_open) * for further details. * - * @param socket A valid socket handle (either a file descriptor or a SOCKET). + * @param socket A valid socket handle (either a file descriptor or a + * SOCKET). + * + * @return Underlying return value. */ - void open(OSSocketHandle socket); + int open(os_socket_handle socket); + + /** + * @brief Associates the handle to a remote address and port (either IPv4 or + * IPv6). + * + * Every message sent by this handle is automatically sent to the given + * destination.
+ * Trying to call this function on an already connected handle isn't + * allowed. + * + * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. + * @return Underlying return value. + */ + int connect(const sockaddr &addr); + + /** + * @brief Associates the handle to a remote address and port (either IPv4 or + * IPv6). + * + * Every message sent by this handle is automatically sent to the given + * destination.
+ * Trying to call this function on an already connected handle isn't + * allowed. + * + * @param ip The address to which to bind. + * @param port The port to which to bind. + * @return Underlying return value. + */ + int connect(const std::string &ip, unsigned int port); + + /** + * @brief Associates the handle to a remote address and port (either IPv4 or + * IPv6). + * + * Every message sent by this handle is automatically sent to the given + * destination.
+ * Trying to call this function on an already connected handle isn't + * allowed. + * + * @param addr A valid instance of socket_address. + * @return Underlying return value. + */ + int connect(socket_address addr); + + /** + * @brief Disconnects the handle. + * + * Trying to disconnect a handle that is not connected isn't allowed. + * + * @return Underlying return value. + */ + int disconnect(); + + /** + * @brief Gets the remote address to which the handle is connected, if any. + * @return A valid instance of socket_address, an empty one in case of + * errors. + */ + socket_address peer() const noexcept; /** * @brief Binds the UDP handle to an IP address and port. * * Available flags are: * - * * `UDPHandle::Bind::IPV6ONLY` - * * `UDPHandle::Bind::UDP_PARTIAL` - * * `UDPHandle::Bind::REUSEADDR` - * * `UDPHandle::Bind::UDP_MMSG_CHUNK` - * * `UDPHandle::Bind::UDP_MMSG_FREE` - * * `UDPHandle::Bind::UDP_LINUX_RECVERR` - * * `UDPHandle::Bind::UDP_RECVMMSG` + * * `udp_handle::udp_flags::IPV6ONLY` + * * `udp_handle::udp_flags::UDP_PARTIAL` + * * `udp_handle::udp_flags::REUSEADDR` + * * `udp_handle::udp_flags::UDP_MMSG_CHUNK` + * * `udp_handle::udp_flags::UDP_MMSG_FREE` + * * `udp_handle::udp_flags::UDP_LINUX_RECVERR` + * * `udp_handle::udp_flags::UDP_RECVMMSG` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/udp.html#c.uv_udp_flags) @@ -152,85 +191,22 @@ public: * * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. * @param opts Optional additional flags. + * @return Underlying return value. */ - void bind(const sockaddr &addr, Flags opts = Flags{}); - - /** - * @brief Associates the handle to a remote address and port (either IPv4 or - * IPv6). - * - * Every message sent by this handle is automatically sent to the given - * destination.
- * Trying to call this function on an already connected handle isn't - * allowed. - * - * An ErrorEvent event is emitted in case of errors during the connection. - * - * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. - */ - void connect(const sockaddr &addr); - - /** - * @brief Associates the handle to a remote address and port (either IPv4 or - * IPv6). - * - * Every message sent by this handle is automatically sent to the given - * destination.
- * Trying to call this function on an already connected handle isn't - * allowed. - * - * An ErrorEvent event is emitted in case of errors during the connection. - * - * @param ip The address to which to bind. - * @param port The port to which to bind. - */ - template - void connect(const std::string &ip, unsigned int port); - - /** - * @brief Associates the handle to a remote address and port (either IPv4 or - * IPv6). - * - * Every message sent by this handle is automatically sent to the given - * destination.
- * Trying to call this function on an already connected handle isn't - * allowed. - * - * An ErrorEvent event is emitted in case of errors during the connection. - * - * @param addr A valid instance of Addr. - */ - template - void connect(Addr addr); - - /** - * @brief Disconnects the handle. - * - * Trying to disconnect a handle that is not connected isn't allowed. - * - * An ErrorEvent event is emitted in case of errors. - */ - void disconnect(); - - /** - * @brief Gets the remote address to which the handle is connected, if any. - * @return A valid instance of Addr, an empty one in case of errors. - */ - template - Addr peer() const noexcept; + int bind(const sockaddr &addr, udp_flags opts = udp_flags::_UVW_ENUM); /** * @brief Binds the UDP handle to an IP address and port. * * Available flags are: * - * * `UDPHandle::Bind::IPV6ONLY` - * * `UDPHandle::Bind::UDP_PARTIAL` - * * `UDPHandle::Bind::REUSEADDR` - * * `UDPHandle::Bind::UDP_MMSG_CHUNK` - * * `UDPHandle::Bind::UDP_MMSG_FREE` - * * `UDPHandle::Bind::UDP_LINUX_RECVERR` - * * `UDPHandle::Bind::UDP_RECVMMSG` + * * `udp_handle::udp_flags::IPV6ONLY` + * * `udp_handle::udp_flags::UDP_PARTIAL` + * * `udp_handle::udp_flags::REUSEADDR` + * * `udp_handle::udp_flags::UDP_MMSG_CHUNK` + * * `udp_handle::udp_flags::UDP_MMSG_FREE` + * * `udp_handle::udp_flags::UDP_LINUX_RECVERR` + * * `udp_handle::udp_flags::UDP_RECVMMSG` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/udp.html#c.uv_udp_flags) @@ -239,55 +215,54 @@ public: * @param ip The IP address to which to bind. * @param port The port to which to bind. * @param opts Optional additional flags. + * @return Underlying return value. */ - template - void bind(const std::string &ip, unsigned int port, Flags opts = Flags{}); + int bind(const std::string &ip, unsigned int port, udp_flags opts = udp_flags::_UVW_ENUM); /** * @brief Binds the UDP handle to an IP address and port. * * Available flags are: * - * * `UDPHandle::Bind::IPV6ONLY` - * * `UDPHandle::Bind::UDP_PARTIAL` - * * `UDPHandle::Bind::REUSEADDR` - * * `UDPHandle::Bind::UDP_MMSG_CHUNK` - * * `UDPHandle::Bind::UDP_MMSG_FREE` - * * `UDPHandle::Bind::UDP_LINUX_RECVERR` - * * `UDPHandle::Bind::UDP_RECVMMSG` + * * `udp_handle::udp_flags::IPV6ONLY` + * * `udp_handle::udp_flags::UDP_PARTIAL` + * * `udp_handle::udp_flags::REUSEADDR` + * * `udp_handle::udp_flags::UDP_MMSG_CHUNK` + * * `udp_handle::udp_flags::UDP_MMSG_FREE` + * * `udp_handle::udp_flags::UDP_LINUX_RECVERR` + * * `udp_handle::udp_flags::UDP_RECVMMSG` * * See the official * [documentation](http://docs.libuv.org/en/v1.x/udp.html#c.uv_udp_flags) * for further details. * - * @param addr A valid instance of Addr. + * @param addr A valid instance of socket_address. * @param opts Optional additional flags. + * @return Underlying return value. */ - template - void bind(Addr addr, Flags opts = Flags{}); + int bind(socket_address addr, udp_flags opts = udp_flags::_UVW_ENUM); /** * @brief Get the local IP and port of the UDP handle. - * @return A valid instance of Addr, an empty one in case of errors. + * @return A valid instance of socket_address, an empty one in case of + * errors. */ - template - Addr sock() const noexcept; + socket_address sock() const noexcept; /** * @brief Sets membership for a multicast address. * - * Available values for `membership` are: + * Available values for `ms` are: * - * * `UDPHandle::Membership::LEAVE_GROUP` - * * `UDPHandle::Membership::JOIN_GROUP` + * * `udp_handle::membership::LEAVE_GROUP` + * * `udp_handle::membership::JOIN_GROUP` * * @param multicast Multicast address to set membership for. * @param iface Interface address. - * @param membership Action to be performed. + * @param ms Action to be performed. * @return True in case of success, false otherwise. */ - template - bool multicastMembership(const std::string &multicast, const std::string &iface, Membership membership); + bool multicast_membership(const std::string &multicast, const std::string &iface, membership ms); /** * @brief Sets IP multicast loop flag. @@ -297,22 +272,21 @@ public: * @param enable True to enable multicast loop, false otherwise. * @return True in case of success, false otherwise. */ - bool multicastLoop(bool enable = true); + bool multicast_loop(bool enable = true); /** * @brief Sets the multicast ttl. * @param val A value in the range `[1, 255]`. * @return True in case of success, false otherwise. */ - bool multicastTtl(int val); + bool multicast_ttl(int val); /** * @brief Sets the multicast interface to send or receive data on. * @param iface Interface address. * @return True in case of success, false otherwise. */ - template - bool multicastInterface(const std::string &iface); + bool multicast_interface(const std::string &iface); /** * @brief Sets broadcast on or off. @@ -338,14 +312,14 @@ public: * The handle takes the ownership of the data and it is in charge of delete * them. * - * A SendEvent event will be emitted when the data have been sent.
- * An ErrorEvent event will be emitted in case of errors. + * A send event will be emitted when the data have been sent. * * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. * @param data The data to be sent. * @param len The lenght of the submitted data. + * @return Underlying return value. */ - void send(const sockaddr &addr, std::unique_ptr data, unsigned int len); + int send(const sockaddr &addr, std::unique_ptr data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -357,16 +331,15 @@ public: * The handle takes the ownership of the data and it is in charge of delete * them. * - * A SendEvent event will be emitted when the data have been sent.
- * An ErrorEvent event will be emitted in case of errors. + * A send event will be emitted when the data have been sent. * * @param ip The address to which to send data. * @param port The port to which to send data. * @param data The data to be sent. * @param len The lenght of the submitted data. + * @return Underlying return value. */ - template - void send(const std::string &ip, unsigned int port, std::unique_ptr data, unsigned int len); + int send(const std::string &ip, unsigned int port, std::unique_ptr data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -378,15 +351,14 @@ public: * The handle takes the ownership of the data and it is in charge of delete * them. * - * A SendEvent event will be emitted when the data have been sent.
- * An ErrorEvent event will be emitted in case of errors. + * A send event will be emitted when the data have been sent. * - * @param addr A valid instance of Addr. + * @param addr A valid instance of socket_address. * @param data The data to be sent. * @param len The lenght of the submitted data. + * @return Underlying return value. */ - template - void send(Addr addr, std::unique_ptr data, unsigned int len); + int send(socket_address addr, std::unique_ptr data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -398,14 +370,14 @@ public: * The handle doesn't take the ownership of the data. Be sure that their * lifetime overcome the one of the request. * - * A SendEvent event will be emitted when the data have been sent.
- * An ErrorEvent event will be emitted in case of errors. + * A send event will be emitted when the data have been sent. * * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. * @param data The data to be sent. * @param len The lenght of the submitted data. + * @return Underlying return value. */ - void send(const sockaddr &addr, char *data, unsigned int len); + int send(const sockaddr &addr, char *data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -417,16 +389,15 @@ public: * The handle doesn't take the ownership of the data. Be sure that their * lifetime overcome the one of the request. * - * A SendEvent event will be emitted when the data have been sent.
- * An ErrorEvent event will be emitted in case of errors. + * A send event will be emitted when the data have been sent. * * @param ip The address to which to send data. * @param port The port to which to send data. * @param data The data to be sent. * @param len The lenght of the submitted data. + * @return Underlying return value. */ - template - void send(const std::string &ip, unsigned int port, char *data, unsigned int len); + int send(const std::string &ip, unsigned int port, char *data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -438,15 +409,14 @@ public: * The handle doesn't take the ownership of the data. Be sure that their * lifetime overcome the one of the request. * - * A SendEvent event will be emitted when the data have been sent.
- * An ErrorEvent event will be emitted in case of errors. + * A send event will be emitted when the data have been sent. * - * @param addr A valid instance of Addr. + * @param addr A valid instance of socket_address. * @param data The data to be sent. * @param len The lenght of the submitted data. + * @return Underlying return value. */ - template - void send(Addr addr, char *data, unsigned int len); + int send(socket_address addr, char *data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -457,10 +427,9 @@ public: * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. * @param data The data to be sent. * @param len The lenght of the submitted data. - * @return Number of bytes written. + * @return Underlying return value. */ - template - int trySend(const sockaddr &addr, std::unique_ptr data, unsigned int len); + int try_send(const sockaddr &addr, std::unique_ptr data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -472,10 +441,9 @@ public: * @param port The port to which to send data. * @param data The data to be sent. * @param len The lenght of the submitted data. - * @return Number of bytes written. + * @return Underlying return value. */ - template - int trySend(const std::string &ip, unsigned int port, std::unique_ptr data, unsigned int len); + int try_send(const std::string &ip, unsigned int port, std::unique_ptr data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -483,13 +451,12 @@ public: * Same as `send()`, but it won’t queue a send request if it can’t be * completed immediately. * - * @param addr A valid instance of Addr. + * @param addr A valid instance of socket_address. * @param data The data to be sent. * @param len The lenght of the submitted data. - * @return Number of bytes written. + * @return Underlying return value. */ - template - int trySend(Addr addr, std::unique_ptr data, unsigned int len); + int try_send(socket_address addr, std::unique_ptr data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -500,10 +467,9 @@ public: * @param addr Initialized `sockaddr_in` or `sockaddr_in6` data structure. * @param data The data to be sent. * @param len The lenght of the submitted data. - * @return Number of bytes written. + * @return Underlying return value. */ - template - int trySend(const sockaddr &addr, char *data, unsigned int len); + int try_send(const sockaddr &addr, char *data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -515,10 +481,9 @@ public: * @param port The port to which to send data. * @param data The data to be sent. * @param len The lenght of the submitted data. - * @return Number of bytes written. + * @return Underlying return value. */ - template - int trySend(const std::string &ip, unsigned int port, char *data, unsigned int len); + int try_send(const std::string &ip, unsigned int port, char *data, unsigned int len); /** * @brief Sends data over the UDP socket. @@ -526,13 +491,12 @@ public: * Same as `send()`, but it won’t queue a send request if it can’t be * completed immediately. * - * @param addr A valid instance of Addr. + * @param addr A valid instance of socket_address. * @param data The data to be sent. * @param len The lenght of the submitted data. - * @return Number of bytes written. + * @return Underlying return value. */ - template - int trySend(Addr addr, char *data, unsigned int len); + int try_send(socket_address addr, char *data, unsigned int len); /** * @brief Prepares for receiving data. @@ -541,16 +505,17 @@ public: * is bound to `0.0.0.0` (the _all interfaces_ IPv4 address) and a random * port number. * - * An UDPDataEvent event will be emitted when the handle receives data.
- * An ErrorEvent event will be emitted in case of errors. + * An UDP data event will be emitted when the handle receives data. + * + * @return Underlying return value. */ - template - void recv(); + int recv(); /** * @brief Stops listening for incoming datagrams. + * @return Underlying return value. */ - void stop(); + int stop(); /** * @brief Gets the number of bytes queued for sending. @@ -559,13 +524,14 @@ public: * * @return Number of bytes queued for sending. */ - size_t sendQueueSize() const noexcept; + size_t send_queue_size() const noexcept; /** - * @brief Number of send requests currently in the queue awaiting to be processed. + * @brief Number of send requests currently in the queue awaiting to be + * processed. * @return Number of send requests currently in the queue. */ - size_t sendQueueCount() const noexcept; + size_t send_queue_count() const noexcept; private: enum { @@ -576,76 +542,6 @@ private: unsigned int flags{}; }; -/** - * @cond TURN_OFF_DOXYGEN - * Internal details not to be documented. - */ - -// (extern) explicit instantiations -#ifdef UVW_AS_LIB -extern template void UDPHandle::connect(const std::string &, unsigned int); -extern template void UDPHandle::connect(const std::string &, unsigned int); - -extern template void UDPHandle::connect(Addr); -extern template void UDPHandle::connect(Addr); - -extern template Addr UDPHandle::peer() const noexcept; -extern template Addr UDPHandle::peer() const noexcept; - -extern template void UDPHandle::bind(const std::string &, unsigned int, Flags); -extern template void UDPHandle::bind(const std::string &, unsigned int, Flags); - -extern template void UDPHandle::bind(Addr, Flags); -extern template void UDPHandle::bind(Addr, Flags); - -extern template Addr UDPHandle::sock() const noexcept; -extern template Addr UDPHandle::sock() const noexcept; - -extern template bool UDPHandle::multicastMembership(const std::string &, const std::string &, Membership); -extern template bool UDPHandle::multicastMembership(const std::string &, const std::string &, Membership); - -extern template bool UDPHandle::multicastInterface(const std::string &); -extern template bool UDPHandle::multicastInterface(const std::string &); - -extern template void UDPHandle::send(const std::string &, unsigned int, std::unique_ptr, unsigned int); -extern template void UDPHandle::send(const std::string &, unsigned int, std::unique_ptr, unsigned int); - -extern template void UDPHandle::send(Addr, std::unique_ptr, unsigned int); -extern template void UDPHandle::send(Addr, std::unique_ptr, unsigned int); - -extern template void UDPHandle::send(const std::string &, unsigned int, char *, unsigned int); -extern template void UDPHandle::send(const std::string &, unsigned int, char *, unsigned int); - -extern template void UDPHandle::send(Addr, char *, unsigned int); -extern template void UDPHandle::send(Addr, char *, unsigned int); - -extern template int UDPHandle::trySend(const sockaddr &, std::unique_ptr, unsigned int); -extern template int UDPHandle::trySend(const sockaddr &, std::unique_ptr, unsigned int); - -extern template int UDPHandle::trySend(const std::string &, unsigned int, std::unique_ptr, unsigned int); -extern template int UDPHandle::trySend(const std::string &, unsigned int, std::unique_ptr, unsigned int); - -extern template int UDPHandle::trySend(Addr, std::unique_ptr, unsigned int); -extern template int UDPHandle::trySend(Addr, std::unique_ptr, unsigned int); - -extern template int UDPHandle::trySend(const sockaddr &, char *, unsigned int); -extern template int UDPHandle::trySend(const sockaddr &, char *, unsigned int); - -extern template int UDPHandle::trySend(const std::string &, unsigned int, char *, unsigned int); -extern template int UDPHandle::trySend(const std::string &, unsigned int, char *, unsigned int); - -extern template int UDPHandle::trySend(Addr, char *, unsigned int); -extern template int UDPHandle::trySend(Addr, char *, unsigned int); - -extern template void UDPHandle::recv(); -extern template void UDPHandle::recv(); -#endif // UVW_AS_LIB - -/** - * Internal details not to be documented. - * @endcond - */ - } // namespace uvw #ifndef UVW_AS_LIB diff --git a/src/uvw/underlying_type.hpp b/src/uvw/underlying_type.hpp deleted file mode 100644 index 86035fb2..00000000 --- a/src/uvw/underlying_type.hpp +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef UVW_UNDERLYING_TYPE_INCLUDE_H -#define UVW_UNDERLYING_TYPE_INCLUDE_H - -#include -#include -#include -#include "loop.h" - -namespace uvw { - -/** - * @brief Wrapper class for underlying types. - * - * It acts mainly as a wrapper around data structures of the underlying library. - */ -template -class UnderlyingType { - template - friend class UnderlyingType; - -protected: - struct ConstructorAccess { - explicit ConstructorAccess(int) {} - }; - - template - auto get() noexcept { - return reinterpret_cast(&resource); - } - - template - auto get() const noexcept { - return reinterpret_cast(&resource); - } - - template - auto get(UnderlyingType &other) noexcept { - return reinterpret_cast(&other.resource); - } - -public: - explicit UnderlyingType(ConstructorAccess, std::shared_ptr ref) noexcept - : pLoop{std::move(ref)}, resource{} {} - - UnderlyingType(const UnderlyingType &) = delete; - UnderlyingType(UnderlyingType &&) = delete; - - virtual ~UnderlyingType() { - static_assert(std::is_base_of_v, T>); - } - - UnderlyingType &operator=(const UnderlyingType &) = delete; - UnderlyingType &operator=(UnderlyingType &&) = delete; - - /** - * @brief Creates a new resource of the given type. - * @param args Arguments to be forwarded to the actual constructor (if any). - * @return A pointer to the newly created resource. - */ - template - static std::shared_ptr create(Args &&...args) { - return std::make_shared(ConstructorAccess{0}, std::forward(args)...); - } - - /** - * @brief Gets the loop from which the resource was originated. - * @return A reference to a loop instance. - */ - Loop &loop() const noexcept { - return *pLoop; - } - - /** - * @brief Gets the underlying raw data structure. - * - * This function should not be used, unless you know exactly what you are - * doing and what are the risks.
- * Going raw is dangerous, mainly because the lifetime management of a loop, - * a handle or a request is in charge to the library itself and users should - * not work around it. - * - * @warning - * Use this function at your own risk, but do not expect any support in case - * of bugs. - * - * @return The underlying raw data structure. - */ - const U *raw() const noexcept { - return &resource; - } - - /** - * @brief Gets the underlying raw data structure. - * - * This function should not be used, unless you know exactly what you are - * doing and what are the risks.
- * Going raw is dangerous, mainly because the lifetime management of a loop, - * a handle or a request is in charge to the library itself and users should - * not work around it. - * - * @warning - * Use this function at your own risk, but do not expect any support in case - * of bugs. - * - * @return The underlying raw data structure. - */ - U *raw() noexcept { - return const_cast(const_cast(this)->raw()); - } - -private: - std::shared_ptr pLoop; - U resource; -}; - -} // namespace uvw - -#endif // UVW_UNDERLYING_TYPE_INCLUDE_H diff --git a/src/uvw/util.cpp b/src/uvw/util.cpp index a18b0e80..b0390b7b 100644 --- a/src/uvw/util.cpp +++ b/src/uvw/util.cpp @@ -2,93 +2,146 @@ # include "util.h" #endif -#include - #include "config.h" namespace uvw { -UVW_INLINE Passwd::Passwd(std::shared_ptr pwd) - : passwd{pwd} {} +UVW_INLINE passwd_info::passwd_info(std::shared_ptr pwd) + : value{pwd} {} -UVW_INLINE std::string Passwd::username() const noexcept { - return ((passwd && passwd->username) ? passwd->username : ""); +UVW_INLINE std::string passwd_info::username() const noexcept { + return ((value && value->username) ? value->username : ""); } -UVW_INLINE decltype(uv_passwd_t::uid) Passwd::uid() const noexcept { - return (passwd ? passwd->uid : decltype(uv_passwd_t::uid){}); +UVW_INLINE decltype(uv_passwd_t::uid) passwd_info::uid() const noexcept { + return (value ? value->uid : decltype(uv_passwd_t::uid){}); } -UVW_INLINE decltype(uv_passwd_t::gid) Passwd::gid() const noexcept { - return (passwd ? passwd->gid : decltype(uv_passwd_t::gid){}); +UVW_INLINE decltype(uv_passwd_t::gid) passwd_info::gid() const noexcept { + return (value ? value->gid : decltype(uv_passwd_t::gid){}); } -UVW_INLINE std::string Passwd::shell() const noexcept { - return ((passwd && passwd->shell) ? passwd->shell : ""); +UVW_INLINE std::string passwd_info::shell() const noexcept { + return ((value && value->shell) ? value->shell : ""); } -UVW_INLINE std::string Passwd::homedir() const noexcept { - return ((passwd && passwd->homedir) ? passwd->homedir : ""); +UVW_INLINE std::string passwd_info::homedir() const noexcept { + return ((value && value->homedir) ? value->homedir : ""); } -UVW_INLINE Passwd::operator bool() const noexcept { - return static_cast(passwd); +UVW_INLINE passwd_info::operator bool() const noexcept { + return static_cast(value); } -UVW_INLINE UtsName::UtsName(std::shared_ptr utsname) - : utsname{utsname} {} +UVW_INLINE uts_name::uts_name(std::shared_ptr init) + : uname{init} {} -UVW_INLINE std::string UtsName::sysname() const noexcept { - return utsname ? utsname->sysname : ""; +UVW_INLINE std::string uts_name::sysname() const noexcept { + return uname ? uname->sysname : ""; } -UVW_INLINE std::string UtsName::release() const noexcept { - return utsname ? utsname->release : ""; +UVW_INLINE std::string uts_name::release() const noexcept { + return uname ? uname->release : ""; } -UVW_INLINE std::string UtsName::version() const noexcept { - return utsname ? utsname->version : ""; +UVW_INLINE std::string uts_name::version() const noexcept { + return uname ? uname->version : ""; } -UVW_INLINE std::string UtsName::machine() const noexcept { - return utsname ? utsname->machine : ""; +UVW_INLINE std::string uts_name::machine() const noexcept { + return uname ? uname->machine : ""; } -UVW_INLINE PidType Utilities::OS::pid() noexcept { +namespace details { + +UVW_INLINE void common_alloc_callback(uv_handle_t *, std::size_t suggested, uv_buf_t *buf) { + auto size = static_cast(suggested); + *buf = uv_buf_init(new char[size], size); +} + +UVW_INLINE sockaddr ip_addr(const char *addr, unsigned int port) { + if(sockaddr_in addr_in; uv_ip4_addr(addr, port, &addr_in) == 0) { + return reinterpret_cast(addr_in); + } else if(sockaddr_in6 addr_in6; uv_ip6_addr(addr, port, &addr_in6) == 0) { + return reinterpret_cast(addr_in6); + } + + return {}; +} + +UVW_INLINE socket_address sock_addr(const sockaddr_in &addr) { + if(char name[details::DEFAULT_SIZE]; uv_ip4_name(&addr, name, details::DEFAULT_SIZE) == 0) { + return socket_address{std::string{name}, ntohs(addr.sin_port)}; + } + + return socket_address{}; +} + +UVW_INLINE socket_address sock_addr(const sockaddr_in6 &addr) { + if(char name[details::DEFAULT_SIZE]; uv_ip6_name(&addr, name, details::DEFAULT_SIZE) == 0) { + return socket_address{std::string{name}, ntohs(addr.sin6_port)}; + } + + return socket_address{}; +} + +UVW_INLINE socket_address sock_addr(const sockaddr &addr) { + if(addr.sa_family == AF_INET) { + return sock_addr(reinterpret_cast(addr)); + } else if(addr.sa_family == AF_INET6) { + return sock_addr(reinterpret_cast(addr)); + } + + return socket_address{}; +} + +UVW_INLINE socket_address sock_addr(const sockaddr_storage &storage) { + if(storage.ss_family == AF_INET) { + return sock_addr(reinterpret_cast(storage)); + } else if(storage.ss_family == AF_INET6) { + return sock_addr(reinterpret_cast(storage)); + } + + return socket_address{}; +} + +} // namespace details + +UVW_INLINE pid_type utilities::os::pid() noexcept { return uv_os_getpid(); } -UVW_INLINE PidType Utilities::OS::parent() noexcept { +UVW_INLINE pid_type utilities::os::ppid() noexcept { return uv_os_getppid(); } -UVW_INLINE std::string Utilities::OS::homedir() noexcept { - return details::tryRead(&uv_os_homedir); +UVW_INLINE std::string utilities::os::homedir() noexcept { + return details::try_read(&uv_os_homedir); } -UVW_INLINE std::string Utilities::OS::tmpdir() noexcept { - return details::tryRead(&uv_os_tmpdir); +UVW_INLINE std::string utilities::os::tmpdir() noexcept { + return details::try_read(&uv_os_tmpdir); } -UVW_INLINE std::string Utilities::OS::env(const std::string &name) noexcept { - return details::tryRead(&uv_os_getenv, name.c_str()); +UVW_INLINE std::string utilities::os::env(const std::string &name) noexcept { + return details::try_read(&uv_os_getenv, name.c_str()); } -UVW_INLINE bool Utilities::OS::env(const std::string &name, const std::string &value) noexcept { +UVW_INLINE bool utilities::os::env(const std::string &name, const std::string &value) noexcept { return (0 == (value.empty() ? uv_os_unsetenv(name.c_str()) : uv_os_setenv(name.c_str(), value.c_str()))); } -UVW_INLINE std::string Utilities::OS::hostname() noexcept { - return details::tryRead(&uv_os_gethostname); +UVW_INLINE std::string utilities::os::hostname() noexcept { + return details::try_read(&uv_os_gethostname); } -UVW_INLINE UtsName Utilities::OS::uname() noexcept { +UVW_INLINE uts_name utilities::os::uname() noexcept { auto ptr = std::make_shared(); uv_os_uname(ptr.get()); return ptr; } -UVW_INLINE Passwd Utilities::OS::passwd() noexcept { +UVW_INLINE passwd_info utilities::os::passwd() noexcept { auto deleter = [](uv_passwd_t *passwd) { uv_os_free_passwd(passwd); delete passwd; @@ -99,7 +152,7 @@ UVW_INLINE Passwd Utilities::OS::passwd() noexcept { return ptr; } -UVW_INLINE int Utilities::OS::priority(PidType pid) { +UVW_INLINE int utilities::os::priority(pid_type pid) { int prio = 0; if(uv_os_getpriority(pid, &prio)) { @@ -109,66 +162,66 @@ UVW_INLINE int Utilities::OS::priority(PidType pid) { return prio; } -UVW_INLINE bool Utilities::OS::priority(PidType pid, int prio) { +UVW_INLINE bool utilities::os::priority(pid_type pid, int prio) { return 0 == uv_os_setpriority(pid, prio); } -UVW_INLINE HandleType Utilities::guessHandle(HandleCategory category) noexcept { +UVW_INLINE handle_type utilities::guess_handle(handle_category category) noexcept { switch(category) { case UV_ASYNC: - return HandleType::ASYNC; + return handle_type::ASYNC; case UV_CHECK: - return HandleType::CHECK; + return handle_type::CHECK; case UV_FS_EVENT: - return HandleType::FS_EVENT; + return handle_type::FS_EVENT; case UV_FS_POLL: - return HandleType::FS_POLL; + return handle_type::FS_POLL; case UV_HANDLE: - return HandleType::HANDLE; + return handle_type::HANDLE; case UV_IDLE: - return HandleType::IDLE; + return handle_type::IDLE; case UV_NAMED_PIPE: - return HandleType::PIPE; + return handle_type::PIPE; case UV_POLL: - return HandleType::POLL; + return handle_type::POLL; case UV_PREPARE: - return HandleType::PREPARE; + return handle_type::PREPARE; case UV_PROCESS: - return HandleType::PROCESS; + return handle_type::PROCESS; case UV_STREAM: - return HandleType::STREAM; + return handle_type::STREAM; case UV_TCP: - return HandleType::TCP; + return handle_type::TCP; case UV_TIMER: - return HandleType::TIMER; + return handle_type::TIMER; case UV_TTY: - return HandleType::TTY; + return handle_type::TTY; case UV_UDP: - return HandleType::UDP; + return handle_type::UDP; case UV_SIGNAL: - return HandleType::SIGNAL; + return handle_type::SIGNAL; case UV_FILE: - return HandleType::FILE; + return handle_type::FILE; default: - return HandleType::UNKNOWN; + return handle_type::UNKNOWN; } } -UVW_INLINE HandleType Utilities::guessHandle(FileHandle file) noexcept { - HandleCategory category = uv_guess_handle(file); - return guessHandle(category); +UVW_INLINE handle_type utilities::guess_handle(file_handle file) noexcept { + handle_category category = uv_guess_handle(file); + return guess_handle(category); } -UVW_INLINE std::vector Utilities::cpuInfo() noexcept { - std::vector cpuinfos; +UVW_INLINE std::vector utilities::cpu() noexcept { + std::vector cpuinfos; uv_cpu_info_t *infos; int count; if(0 == uv_cpu_info(&infos, &count)) { - std::for_each(infos, infos + count, [&cpuinfos](const auto &info) { - cpuinfos.push_back({info.model, info.speed, info.cpu_times}); - }); + for (int next = 0; next < count; ++next) { + cpuinfos.push_back({infos[next].model, infos[next].speed, infos[next].cpu_times}); + } uv_free_cpu_info(infos, count); } @@ -176,30 +229,30 @@ UVW_INLINE std::vector Utilities::cpuInfo() noexcept { return cpuinfos; } -UVW_INLINE std::vector Utilities::interfaceAddresses() noexcept { - std::vector interfaces; +UVW_INLINE std::vector utilities::interface_addresses() noexcept { + std::vector interfaces; uv_interface_address_t *ifaces{nullptr}; int count{0}; if(0 == uv_interface_addresses(&ifaces, &count)) { - std::for_each(ifaces, ifaces + count, [&interfaces](const auto &iface) { - InterfaceAddress interfaceAddress; + for(int next = 0; next < count; ++next) { + interface_address iface_addr; - interfaceAddress.name = iface.name; - std::copy(iface.phys_addr, (iface.phys_addr + 6), interfaceAddress.physical); - interfaceAddress.internal = iface.is_internal == 0 ? false : true; + iface_addr.name = ifaces[next].name; + std::copy(ifaces[next].phys_addr, (ifaces[next].phys_addr + 6), iface_addr.physical); + iface_addr.internal = ifaces[next].is_internal == 0 ? false : true; - if(iface.address.address4.sin_family == AF_INET) { - interfaceAddress.address = details::address(&iface.address.address4); - interfaceAddress.netmask = details::address(&iface.netmask.netmask4); - } else if(iface.address.address4.sin_family == AF_INET6) { - interfaceAddress.address = details::address(&iface.address.address6); - interfaceAddress.netmask = details::address(&iface.netmask.netmask6); + if(ifaces[next].address.address4.sin_family == AF_INET) { + iface_addr.address = details::sock_addr(ifaces[next].address.address4); + iface_addr.netmask = details::sock_addr(ifaces[next].netmask.netmask4); + } else if(ifaces[next].address.address4.sin_family == AF_INET6) { + iface_addr.address = details::sock_addr(ifaces[next].address.address6); + iface_addr.netmask = details::sock_addr(ifaces[next].netmask.netmask6); } - interfaces.push_back(std::move(interfaceAddress)); - }); + interfaces.push_back(std::move(iface_addr)); + } uv_free_interface_addresses(ifaces, count); } @@ -207,29 +260,29 @@ UVW_INLINE std::vector Utilities::interfaceAddresses() noexcep return interfaces; } -UVW_INLINE std::string Utilities::indexToName(unsigned int index) noexcept { - return details::tryRead(&uv_if_indextoname, index); +UVW_INLINE std::string utilities::index_to_name(unsigned int index) noexcept { + return details::try_read(&uv_if_indextoname, index); } -UVW_INLINE std::string Utilities::indexToIid(unsigned int index) noexcept { - return details::tryRead(&uv_if_indextoiid, index); +UVW_INLINE std::string utilities::index_to_iid(unsigned int index) noexcept { + return details::try_read(&uv_if_indextoiid, index); } -UVW_INLINE bool Utilities::replaceAllocator(MallocFuncType mallocFunc, ReallocFuncType reallocFunc, CallocFuncType callocFunc, FreeFuncType freeFunc) noexcept { - return (0 == uv_replace_allocator(mallocFunc, reallocFunc, callocFunc, freeFunc)); +UVW_INLINE bool utilities::replace_allocator(malloc_func_type malloc_func, realloc_func_type realloc_func, calloc_func_type calloc_func, free_func_type free_func) noexcept { + return (0 == uv_replace_allocator(malloc_func, realloc_func, calloc_func, free_func)); } -UVW_INLINE std::array Utilities::loadAverage() noexcept { +UVW_INLINE std::array utilities::load_average() noexcept { std::array avg; uv_loadavg(avg.data()); return avg; } -UVW_INLINE char **Utilities::setupArgs(int argc, char **argv) { +UVW_INLINE char **utilities::setup_args(int argc, char **argv) { return uv_setup_args(argc, argv); } -UVW_INLINE std::string Utilities::processTitle() { +UVW_INLINE std::string utilities::process_title() { std::size_t size = details::DEFAULT_SIZE; char buf[details::DEFAULT_SIZE]; std::string str{}; @@ -241,19 +294,19 @@ UVW_INLINE std::string Utilities::processTitle() { return str; } -UVW_INLINE bool Utilities::processTitle(const std::string &title) { +UVW_INLINE bool utilities::process_title(const std::string &title) { return (0 == uv_set_process_title(title.c_str())); } -UVW_INLINE uint64_t Utilities::totalMemory() noexcept { +UVW_INLINE uint64_t utilities::total_memory() noexcept { return uv_get_total_memory(); } -UVW_INLINE uint64_t Utilities::constrainedMemory() noexcept { +UVW_INLINE uint64_t utilities::constrained_memory() noexcept { return uv_get_constrained_memory(); } -UVW_INLINE double Utilities::uptime() noexcept { +UVW_INLINE double utilities::uptime() noexcept { double ret; if(0 != uv_uptime(&ret)) { @@ -263,39 +316,39 @@ UVW_INLINE double Utilities::uptime() noexcept { return ret; } -UVW_INLINE RUsage Utilities::rusage() noexcept { - RUsage ru; +UVW_INLINE resource_usage utilities::rusage() noexcept { + resource_usage ru; auto err = uv_getrusage(&ru); - return err ? RUsage{} : ru; + return err ? resource_usage{} : ru; } -UVW_INLINE uint64_t Utilities::hrtime() noexcept { +UVW_INLINE uint64_t utilities::hrtime() noexcept { return uv_hrtime(); } -UVW_INLINE std::string Utilities::path() noexcept { - return details::tryRead(&uv_exepath); +UVW_INLINE std::string utilities::path() noexcept { + return details::try_read(&uv_exepath); } -UVW_INLINE std::string Utilities::cwd() noexcept { - return details::tryRead(&uv_cwd); +UVW_INLINE std::string utilities::cwd() noexcept { + return details::try_read(&uv_cwd); } -UVW_INLINE bool Utilities::chdir(const std::string &dir) noexcept { +UVW_INLINE bool utilities::chdir(const std::string &dir) noexcept { return (0 == uv_chdir(dir.data())); } -UVW_INLINE TimeVal64 Utilities::timeOfDay() noexcept { +UVW_INLINE timeval64 utilities::time_of_day() noexcept { uv_timeval64_t ret; uv_gettimeofday(&ret); return ret; } -UVW_INLINE void Utilities::sleep(unsigned int msec) noexcept { +UVW_INLINE void utilities::sleep(unsigned int msec) noexcept { uv_sleep(msec); } -UVW_INLINE unsigned int Utilities::availableParallelism() noexcept { +UVW_INLINE unsigned int utilities::available_parallelism() noexcept { return uv_available_parallelism(); } diff --git a/src/uvw/util.h b/src/uvw/util.h index fd94d3a3..ed8c276e 100644 --- a/src/uvw/util.h +++ b/src/uvw/util.h @@ -11,12 +11,13 @@ #include #include #include +#include "config.h" namespace uvw { namespace details { -enum class UVHandleType : std::underlying_type_t { +enum class uvw_handle_type : std::underlying_type_t { UNKNOWN = UV_UNKNOWN_HANDLE, ASYNC = UV_ASYNC, CHECK = UV_CHECK, @@ -38,20 +39,20 @@ enum class UVHandleType : std::underlying_type_t { }; template -struct UVTypeWrapper { +struct uv_type_wrapper { using Type = T; - constexpr UVTypeWrapper() + constexpr uv_type_wrapper() : value{} {} - constexpr UVTypeWrapper(Type val) + constexpr uv_type_wrapper(Type val) : value{val} {} constexpr operator Type() const noexcept { return value; } - bool operator==(UVTypeWrapper other) const noexcept { + bool operator==(uv_type_wrapper other) const noexcept { return value == other.value; } @@ -60,166 +61,40 @@ private: }; template -bool operator==(UVTypeWrapper lhs, UVTypeWrapper rhs) { +bool operator==(uv_type_wrapper lhs, uv_type_wrapper rhs) { return !(lhs == rhs); } } // namespace details -/** - * @brief Utility class to handle flags. - * - * This class can be used to handle flags of a same enumeration type.
- * It is meant to be used as an argument for functions and member methods and - * as part of events.
- * `Flags` objects can be easily _or-ed_ and _and-ed_ with other instances of - * the same type or with instances of the type `E` (that is, the actual flag - * type), thus converted to the underlying type when needed. - */ -template -class Flags final { - static_assert(std::is_enum_v); - - using InnerType = std::underlying_type_t; - - constexpr InnerType toInnerType(E flag) const noexcept { - return static_cast(flag); - } - -public: - using Type = InnerType; - - /** - * @brief Utility factory method to pack a set of values all at once. - * @return A valid instance of Flags instantiated from values `V`. - */ - template - static constexpr Flags from() { - return (Flags{} | ... | V); - } - - /** - * @brief Constructs a Flags object from a value of the enum `E`. - * @param flag A value of the enum `E`. - */ - constexpr Flags(E flag) noexcept - : flags{toInnerType(flag)} {} - - /** - * @brief Constructs a Flags object from an instance of the underlying type - * of the enum `E`. - * @param f An instance of the underlying type of the enum `E`. - */ - constexpr Flags(Type f) - : flags{f} {} - - /** - * @brief Constructs an uninitialized Flags object. - */ - constexpr Flags() - : flags{} {} - - constexpr Flags(const Flags &f) noexcept - : flags{f.flags} {} - - constexpr Flags(Flags &&f) noexcept - : flags{std::move(f.flags)} {} - - constexpr Flags &operator=(const Flags &f) noexcept { - flags = f.flags; - return *this; - } - - constexpr Flags &operator=(Flags &&f) noexcept { - flags = std::move(f.flags); - return *this; - } - - /** - * @brief Or operator. - * @param f A valid instance of Flags. - * @return This instance _or-ed_ with `f`. - */ - constexpr Flags operator|(const Flags &f) const noexcept { - return Flags{flags | f.flags}; - } - - /** - * @brief Or operator. - * @param flag A value of the enum `E`. - * @return This instance _or-ed_ with `flag`. - */ - constexpr Flags operator|(E flag) const noexcept { - return Flags{flags | toInnerType(flag)}; - } - - /** - * @brief And operator. - * @param f A valid instance of Flags. - * @return This instance _and-ed_ with `f`. - */ - constexpr Flags operator&(const Flags &f) const noexcept { - return Flags{flags & f.flags}; - } - - /** - * @brief And operator. - * @param flag A value of the enum `E`. - * @return This instance _and-ed_ with `flag`. - */ - constexpr Flags operator&(E flag) const noexcept { - return Flags{flags & toInnerType(flag)}; - } - - /** - * @brief Checks if this instance is initialized. - * @return False if it's uninitialized, true otherwise. - */ - explicit constexpr operator bool() const noexcept { - return !(flags == InnerType{}); - } - - /** - * @brief Casts the instance to the underlying type of `E`. - * @return An integral representation of the contained flags. - */ - constexpr operator Type() const noexcept { - return flags; - } - -private: - InnerType flags; -}; - /** * @brief Windows size representation. */ -struct WinSize { +struct win_size { int width; /*!< The _width_ of the given window. */ int height; /*!< The _height_ of the given window. */ }; -using HandleType = details::UVHandleType; /*!< The type of a handle. */ +using handle_type = details::uvw_handle_type; /*!< The type of a handle. */ +using handle_category = details::uv_type_wrapper; /*!< Utility class that wraps an internal handle type. */ +using file_handle = details::uv_type_wrapper; /*!< Utility class that wraps an internal file handle. */ +using os_socket_handle = details::uv_type_wrapper; /*!< Utility class that wraps an os socket handle. */ +using os_file_descriptor = details::uv_type_wrapper; /*!< Utility class that wraps an os file descriptor. */ +using pid_type = details::uv_type_wrapper; /*!< Utility class that wraps a cross platform representation of a pid. */ -using HandleCategory = details::UVTypeWrapper; /*!< Utility class that wraps an internal handle type. */ -using FileHandle = details::UVTypeWrapper; /*!< Utility class that wraps an internal file handle. */ -using OSSocketHandle = details::UVTypeWrapper; /*!< Utility class that wraps an os socket handle. */ -using OSFileDescriptor = details::UVTypeWrapper; /*!< Utility class that wraps an os file descriptor. */ -using PidType = details::UVTypeWrapper; /*!< Utility class that wraps a cross platform representation of a pid. */ +constexpr file_handle std_in{0}; /*!< Placeholder for stdin descriptor. */ +constexpr file_handle std_out{1}; /*!< Placeholder for stdout descriptor. */ +constexpr file_handle std_err{2}; /*!< Placeholder for stderr descriptor. */ -constexpr FileHandle StdIN{0}; /*!< Placeholder for stdin descriptor. */ -constexpr FileHandle StdOUT{1}; /*!< Placeholder for stdout descriptor. */ -constexpr FileHandle StdERR{2}; /*!< Placeholder for stderr descriptor. */ +using time_spec = uv_timespec_t; /*!< Library equivalent for uv_timespec_t. */ +using file_info = uv_stat_t; /*!< Library equivalent for uv_stat_t. */ +using fs_info = uv_statfs_t; /*!< Library equivalent for uv_statfs_t. */ +using uid_type = uv_uid_t; /*!< Library equivalent for uv_uid_t. */ +using gid_type = uv_gid_t; /*!< Library equivalent for uv_gid_t. */ -using TimeSpec = uv_timespec_t; /*!< Library equivalent for uv_timespec_t. */ -using Stat = uv_stat_t; /*!< Library equivalent for uv_stat_t. */ -using Statfs = uv_statfs_t; /*!< Library equivalent for uv_statfs_t. */ -using Uid = uv_uid_t; /*!< Library equivalent for uv_uid_t. */ -using Gid = uv_gid_t; /*!< Library equivalent for uv_gid_t. */ - -using TimeVal = uv_timeval_t; /*!< Library equivalent for uv_timeval_t. */ -using TimeVal64 = uv_timeval64_t; /*!< Library equivalent for uv_timeval64_t. */ -using RUsage = uv_rusage_t; /*!< Library equivalent for uv_rusage_t. */ +using timeval = uv_timeval_t; /*!< Library equivalent for uv_timeval_t. */ +using timeval64 = uv_timeval64_t; /*!< Library equivalent for uv_timeval64_t. */ +using resource_usage = uv_rusage_t; /*!< Library equivalent for uv_rusage_t. */ /** * @brief Utility class. @@ -227,10 +102,10 @@ using RUsage = uv_rusage_t; /*!< Library equivalent for uv_rusage_t. */ * This class can be used to query the subset of the password file entry for the * current effective uid (not the real uid). * - * \sa Utilities::passwd + * \sa utilities::passwd */ -struct Passwd { - Passwd(std::shared_ptr pwd); +struct passwd_info { + passwd_info(std::shared_ptr pwd); /** * @brief Gets the username. @@ -269,7 +144,7 @@ struct Passwd { operator bool() const noexcept; private: - std::shared_ptr passwd; + std::shared_ptr value; }; /** @@ -279,10 +154,10 @@ private: * The populated data includes the operating system name, release, version, and * machine. * - * \sa Utilities::uname + * \sa utilities::uname */ -struct UtsName { - UtsName(std::shared_ptr utsname); +struct uts_name { + uts_name(std::shared_ptr init); /** * @brief Gets the operating system name (like "Linux"). @@ -309,7 +184,7 @@ struct UtsName { std::string machine() const noexcept; private: - std::shared_ptr utsname; + std::shared_ptr uname; }; /** @@ -317,19 +192,19 @@ private: * * To be used as template parameter to switch between IPv4 and IPv6. */ -struct IPv4 {}; +struct ipv4 {}; /** * @brief The IPv6 tag. * * To be used as template parameter to switch between IPv4 and IPv6. */ -struct IPv6 {}; +struct ipv6 {}; /** * @brief Address representation. */ -struct Addr { +struct socket_address { std::string ip; /*!< Either an IPv4 or an IPv6. */ unsigned int port; /*!< A valid service identifier. */ }; @@ -337,8 +212,8 @@ struct Addr { /** * \brief CPU information. */ -struct CPUInfo { - using CPUTime = decltype(uv_cpu_info_t::cpu_times); +struct cpu_info { + using cpu_time = decltype(uv_cpu_info_t::cpu_times); std::string model; /*!< The model of the CPU. */ int speed; /*!< The frequency of the CPU. */ @@ -349,88 +224,26 @@ struct CPUInfo { * It is built up of the following data members: `user`, `nice`, `sys`, * `idle`, `irq`, all of them having type `uint64_t`. */ - CPUTime times; + cpu_time times; }; /** * \brief Interface address. */ -struct InterfaceAddress { - std::string name; /*!< The name of the interface (as an example _eth0_). */ - char physical[6]; /*!< The physical address. */ - bool internal; /*!< True if it is an internal interface (as an example _loopback_), false otherwise. */ - Addr address; /*!< The address of the given interface. */ - Addr netmask; /*!< The netmask of the given interface. */ +struct interface_address { + std::string name; /*!< The name of the interface (as an example _eth0_). */ + char physical[6]; /*!< The physical address. */ + bool internal; /*!< True if it is an internal interface (as an example _loopback_), false otherwise. */ + socket_address address; /*!< The address of the given interface. */ + socket_address netmask; /*!< The netmask of the given interface. */ }; namespace details { static constexpr std::size_t DEFAULT_SIZE = 128; -template -struct IpTraits; - -template<> -struct IpTraits { - using Type = sockaddr_in; - using AddrFuncType = int (*)(const char *, int, Type *); - using NameFuncType = int (*)(const Type *, char *, std::size_t); - - inline static const AddrFuncType addrFunc = &uv_ip4_addr; - inline static const NameFuncType nameFunc = &uv_ip4_name; - - static constexpr auto sinPort(const Type *addr) { - return addr->sin_port; - } -}; - -template<> -struct IpTraits { - using Type = sockaddr_in6; - using AddrFuncType = int (*)(const char *, int, Type *); - using NameFuncType = int (*)(const Type *, char *, std::size_t); - - inline static const AddrFuncType addrFunc = &uv_ip6_addr; - inline static const NameFuncType nameFunc = &uv_ip6_name; - - static constexpr auto sinPort(const Type *addr) { - return addr->sin6_port; - } -}; - -template -Addr address(const typename details::IpTraits::Type *aptr) noexcept { - Addr addr{}; - char name[DEFAULT_SIZE]; - - int err = details::IpTraits::nameFunc(aptr, name, DEFAULT_SIZE); - - if(0 == err) { - addr.port = ntohs(details::IpTraits::sinPort(aptr)); - addr.ip = std::string{name}; - } - - return addr; -} - -template -Addr address(F &&f, const H *handle) noexcept { - sockaddr_storage ssto; - int len = sizeof(ssto); - Addr addr{}; - - int err = std::forward(f)(handle, reinterpret_cast(&ssto), &len); - - if(0 == err) { - typename IpTraits::Type *aptr = reinterpret_cast::Type *>(&ssto); - addr = address(aptr); - } - - return addr; -} - template -std::string tryRead(F &&f, Args &&...args) noexcept { +std::string try_read(F &&f, Args &&...args) noexcept { std::size_t size = DEFAULT_SIZE; char buf[DEFAULT_SIZE]; std::string str{}; @@ -450,6 +263,14 @@ std::string tryRead(F &&f, Args &&...args) noexcept { return str; } +void common_alloc_callback(uv_handle_t *, std::size_t suggested, uv_buf_t *buf); + +sockaddr ip_addr(const char *addr, unsigned int port); +socket_address sock_addr(const sockaddr_in &addr); +socket_address sock_addr(const sockaddr_in6 &addr); +socket_address sock_addr(const sockaddr &addr); +socket_address sock_addr(const sockaddr_storage &storage); + } // namespace details /** @@ -457,16 +278,16 @@ std::string tryRead(F &&f, Args &&...args) noexcept { * * Miscellaneous functions that don’t really belong to any other class. */ -struct Utilities { - using MallocFuncType = void *(*)(size_t); - using ReallocFuncType = void *(*)(void *, size_t); - using CallocFuncType = void *(*)(size_t, size_t); - using FreeFuncType = void (*)(void *); +struct utilities { + using malloc_func_type = void *(*)(size_t); + using realloc_func_type = void *(*)(void *, size_t); + using calloc_func_type = void *(*)(size_t, size_t); + using free_func_type = void (*)(void *); /** * @brief OS dedicated utilities. */ - struct OS { + struct os { /** * @brief Returns the current process id. * @@ -476,7 +297,7 @@ struct Utilities { * * @return The current process id. */ - static PidType pid() noexcept; + static pid_type pid() noexcept; /** * @brief Returns the parent process id. @@ -487,7 +308,7 @@ struct Utilities { * * @return The parent process id. */ - static PidType parent() noexcept; + static pid_type ppid() noexcept; /** * @brief Gets the current user's home directory. @@ -576,7 +397,7 @@ struct Utilities { * * @return Name and information about the current kernel. */ - static UtsName uname() noexcept; + static uts_name uname() noexcept; /** * @brief Gets a subset of the password file entry. @@ -590,7 +411,7 @@ struct Utilities { * * @return The accessible subset of the password file entry. */ - static Passwd passwd() noexcept; + static passwd_info passwd() noexcept; /** * @brief Retrieves the scheduling priority of a process. @@ -605,7 +426,7 @@ struct Utilities { * @param pid A valid process id. * @return The scheduling priority of the process. */ - static int priority(PidType pid); + static int priority(pid_type pid); /** * @brief Sets the scheduling priority of a process. @@ -622,15 +443,15 @@ struct Utilities { * @param prio The scheduling priority to set to the process. * @return True in case of success, false otherwise. */ - static bool priority(PidType pid, int prio); + static bool priority(pid_type pid, int prio); }; /** * @brief Gets the type of the handle given a category. * @param category A properly initialized handle category. - * @return The actual type of the handle as defined by HandleType + * @return The actual type of the handle as defined by handle_type */ - static HandleType guessHandle(HandleCategory category) noexcept; + static handle_type guess_handle(handle_category category) noexcept; /** * @brief Gets the type of the stream to be used with the given descriptor. @@ -643,14 +464,14 @@ struct Utilities { * @param file A valid descriptor. * @return One of the following types: * - * * `HandleType::UNKNOWN` - * * `HandleType::PIPE` - * * `HandleType::TCP` - * * `HandleType::TTY` - * * `HandleType::UDP` - * * `HandleType::FILE` + * * `handle_type::UNKNOWN` + * * `handle_type::PIPE` + * * `handle_type::TCP` + * * `handle_type::TTY` + * * `handle_type::UDP` + * * `handle_type::FILE` */ - static HandleType guessHandle(FileHandle file) noexcept; + static handle_type guess_handle(file_handle file) noexcept; /** @brief Gets information about the CPUs on the system. * @@ -659,7 +480,7 @@ struct Utilities { * * @return A set of descriptors of all the available CPUs. */ - static std::vector cpuInfo() noexcept; + static std::vector cpu() noexcept; /** * @brief Gets a set of descriptors of all the available interfaces. @@ -669,7 +490,7 @@ struct Utilities { * * @return A set of descriptors of all the available interfaces. */ - static std::vector interfaceAddresses() noexcept; + static std::vector interface_addresses() noexcept; /** * @brief IPv6-capable implementation of @@ -684,7 +505,7 @@ struct Utilities { * @param index Network interface index. * @return Network interface name. */ - static std::string indexToName(unsigned int index) noexcept; + static std::string index_to_name(unsigned int index) noexcept; /** * @brief Retrieves a network interface identifier. @@ -696,7 +517,7 @@ struct Utilities { * @param index Network interface index. * @return Network interface identifier. */ - static std::string indexToIid(unsigned int index) noexcept; + static std::string index_to_iid(unsigned int index) noexcept; /** * @brief Override the use of some standard library’s functions. @@ -715,19 +536,19 @@ struct Utilities { * changed while no memory was allocated with the previous allocator, or * that they are compatible. * - * @param mallocFunc Replacement function for _malloc_. - * @param reallocFunc Replacement function for _realloc_. - * @param callocFunc Replacement function for _calloc_. - * @param freeFunc Replacement function for _free_. + * @param malloc_func Replacement function for _malloc_. + * @param realloc_func Replacement function for _realloc_. + * @param calloc_func Replacement function for _calloc_. + * @param free_func Replacement function for _free_. * @return True in case of success, false otherwise. */ - static bool replaceAllocator(MallocFuncType mallocFunc, ReallocFuncType reallocFunc, CallocFuncType callocFunc, FreeFuncType freeFunc) noexcept; + static bool replace_allocator(malloc_func_type malloc_func, realloc_func_type realloc_func, calloc_func_type calloc_func, free_func_type free_func) noexcept; /** * @brief Gets the load average. * @return `[0,0,0]` on Windows (not available), the load average otherwise. */ - static std::array loadAverage() noexcept; + static std::array load_average() noexcept; /** * @brief Store the program arguments. @@ -736,26 +557,26 @@ struct Utilities { * * @return Arguments that haven't been consumed internally. */ - static char **setupArgs(int argc, char **argv); + static char **setup_args(int argc, char **argv); /** * @brief Gets the title of the current process. * @return The process title. */ - static std::string processTitle(); + static std::string process_title(); /** * @brief Sets the current process title. * @param title The process title to be set. * @return True in case of success, false otherwise. */ - static bool processTitle(const std::string &title); + static bool process_title(const std::string &title); /** * @brief Gets memory information (in bytes). * @return Memory information. */ - static uint64_t totalMemory() noexcept; + static uint64_t total_memory() noexcept; /** * @brief Gets the amount of memory available to the process (in bytes). @@ -768,7 +589,7 @@ struct Utilities { * * @return Amount of memory available to the process. */ - static uint64_t constrainedMemory() noexcept; + static uint64_t constrained_memory() noexcept; /** * @brief Gets the current system uptime. @@ -780,7 +601,7 @@ struct Utilities { * @brief Gets the resource usage measures for the current process. * @return Resource usage measures, zeroes-filled object in case of errors. */ - static RUsage rusage() noexcept; + static resource_usage rusage() noexcept; /** * @brief Gets the current high-resolution real time. @@ -818,7 +639,7 @@ struct Utilities { * [`gettimeofday`](https://linux.die.net/man/2/gettimeofday) * @return The current time. */ - static TimeVal64 timeOfDay() noexcept; + static timeval64 time_of_day() noexcept; /** * @brief Causes the calling thread to sleep for a while. @@ -831,7 +652,7 @@ struct Utilities { * use (always a non-zero value). * @return Estimate of the amount of parallelism a program should use. */ - static unsigned int availableParallelism() noexcept; + static unsigned int available_parallelism() noexcept; }; /** @@ -839,7 +660,7 @@ struct Utilities { * @tparam Func Types of function objects. */ template -struct Overloaded: Func... { +struct overloaded: Func... { using Func::operator()...; }; @@ -848,7 +669,7 @@ struct Overloaded: Func... { * @tparam Func Types of function objects. */ template -Overloaded(Func...) -> Overloaded; +overloaded(Func...) -> overloaded; } // namespace uvw diff --git a/src/uvw/uv_type.hpp b/src/uvw/uv_type.hpp new file mode 100644 index 00000000..854b2d8b --- /dev/null +++ b/src/uvw/uv_type.hpp @@ -0,0 +1,89 @@ +#ifndef UVW_UV_TYPE_INCLUDE_H +#define UVW_UV_TYPE_INCLUDE_H + +#include +#include +#include +#include "config.h" +#include "loop.h" + +namespace uvw { + +/** + * @brief Wrapper class for underlying types. + * + * It acts mainly as a wrapper around data structures of the underlying library. + */ +template +struct uv_type { + explicit uv_type(loop::token token, std::shared_ptr ref) noexcept + : owner{std::move(ref)}, resource{} {} + + uv_type(const uv_type &) = delete; + uv_type(uv_type &&) = delete; + + uv_type &operator=(const uv_type &) = delete; + uv_type &operator=(uv_type &&) = delete; + + /** + * @brief Initializes the handle. + * @return Underlying return value. + */ + virtual int init() { + return 0; + } + + /** + * @brief Gets the loop from which the resource was originated. + * @return A reference to a loop instance. + */ + loop &parent() const noexcept { + return *owner; + } + + /** + * @brief Gets the underlying raw data structure. + * + * This function should not be used, unless you know exactly what you are + * doing and what are the risks.
+ * Going raw is dangerous, mainly because the lifetime management of a loop, + * a handle or a request is in charge to the library itself and users should + * not work around it. + * + * @warning + * Use this function at your own risk, but do not expect any support in case + * of bugs. + * + * @return The underlying raw data structure. + */ + const U *raw() const noexcept { + return &resource; + } + + /** + * @brief Gets the underlying raw data structure. + * + * This function should not be used, unless you know exactly what you are + * doing and what are the risks.
+ * Going raw is dangerous, mainly because the lifetime management of a loop, + * a handle or a request is in charge to the library itself and users should + * not work around it. + * + * @warning + * Use this function at your own risk, but do not expect any support in case + * of bugs. + * + * @return The underlying raw data structure. + */ + U *raw() noexcept { + return &resource; + } + +private: + std::shared_ptr owner; + U resource; +}; + +} // namespace uvw + +#endif // UVW_UV_TYPE_INCLUDE_H diff --git a/src/uvw/work.cpp b/src/uvw/work.cpp index 426feea0..f6fc68d0 100644 --- a/src/uvw/work.cpp +++ b/src/uvw/work.cpp @@ -8,15 +8,23 @@ namespace uvw { -UVW_INLINE WorkReq::WorkReq(ConstructorAccess ca, std::shared_ptr ref, InternalTask t) - : Request{ca, std::move(ref)}, task{t} {} +UVW_INLINE work_req::work_req(loop::token token, std::shared_ptr ref, task t) + : request{token, std::move(ref)}, func{t} {} -UVW_INLINE void WorkReq::workCallback(uv_work_t *req) { - static_cast(req->data)->task(); +UVW_INLINE void work_req::work_callback(uv_work_t *req) { + static_cast(req->data)->func(); } -UVW_INLINE void WorkReq::queue() { - invoke(&uv_queue_work, parent(), get(), &workCallback, &defaultCallback); +UVW_INLINE void work_req::after_work_callback(uv_work_t* req, int status) { + if(auto ptr = reserve(req); status) { + ptr->publish(error_event{status}); + } else { + ptr->publish(work_event{}); + } +} + +UVW_INLINE int work_req::queue() { + return this->leak_if(uv_queue_work(parent().raw(), raw(), &work_callback, &after_work_callback)); } } // namespace uvw diff --git a/src/uvw/work.h b/src/uvw/work.h index d1042b05..d6a4c1e2 100644 --- a/src/uvw/work.h +++ b/src/uvw/work.h @@ -9,20 +9,16 @@ namespace uvw { -/** - * @brief WorkEvent event. - * - * It will be emitted by WorkReq according with its functionalities. - */ -struct WorkEvent {}; +/*! @brief Work event. */ +struct work_event {}; /** - * @brief The WorkReq request. + * @brief The work request. * * It runs user code using a thread from the threadpool and gets notified in the * loop thread by means of an event. * - * To create a `WorkReq` through a `Loop`, arguments follow: + * To create a `work_req` through a `loop`, arguments follow: * * * A valid instance of a `Task`, that is of type `std::function`. * @@ -30,27 +26,28 @@ struct WorkEvent {}; * [documentation](http://docs.libuv.org/en/v1.x/threadpool.html) * for further details. */ -class WorkReq final: public Request { - using InternalTask = std::function; - - static void workCallback(uv_work_t *req); +class work_req final: public request { + static void work_callback(uv_work_t *req); + static void after_work_callback(uv_work_t *req, int status); public: - using Task = InternalTask; + using task = std::function; - explicit WorkReq(ConstructorAccess ca, std::shared_ptr ref, InternalTask t); + explicit work_req(loop::token token, std::shared_ptr ref, task t); /** * @brief Runs the given task in a separate thread. * - * A WorkEvent event will be emitted on the loop thread when the task is + * A work event will be emitted on the loop thread when the task is * finished.
* This request can be cancelled with `cancel()`. + * + * @return Underlying return value. */ - void queue(); + int queue(); private: - Task task{}; + task func{}; }; } // namespace uvw diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3d85c7a1..1fc896d8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -95,7 +95,6 @@ ADD_UVW_TEST(check uvw/check.cpp) ADD_UVW_TEST(emitter uvw/emitter.cpp) ADD_UVW_DIR_TEST(file_req uvw/file_req.cpp) ADD_UVW_DIR_TEST(fs_event uvw/fs_event.cpp) -ADD_UVW_DIR_TEST(fs_poll uvw/fs_poll.cpp) ADD_UVW_DIR_TEST(fs_req uvw/fs_req.cpp) ADD_UVW_TEST(handle uvw/handle.cpp) ADD_UVW_TEST(idle uvw/idle.cpp) @@ -113,7 +112,7 @@ ADD_UVW_TEST(thread uvw/thread.cpp) ADD_UVW_TEST(timer uvw/timer.cpp) ADD_UVW_TEST(tty uvw/tty.cpp) ADD_UVW_TEST(udp uvw/udp.cpp) -ADD_UVW_TEST(underlying_type uvw/underlying_type.cpp) +ADD_UVW_TEST(uv_type uvw/uv_type.cpp) ADD_UVW_TEST(util uvw/util.cpp) ADD_UVW_TEST(work uvw/work.cpp) diff --git a/test/main.cpp b/test/main.cpp index 70c1b177..383d3e08 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -4,38 +4,38 @@ #include #include -void listen(uvw::Loop &loop) { - std::shared_ptr tcp = loop.resource(); - tcp->on([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); }); +void listen(uvw::loop &loop) { + std::shared_ptr tcp = loop.resource(); + tcp->on([](const uvw::error_event &, uvw::tcp_handle &) { assert(false); }); - tcp->once([](const uvw::ListenEvent &, uvw::TCPHandle &srv) { + tcp->on([](const uvw::listen_event &, uvw::tcp_handle &srv) { std::cout << "listen" << std::endl; - std::shared_ptr client = srv.loop().resource(); - client->on([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); }); + std::shared_ptr client = srv.parent().resource(); + client->on([](const uvw::error_event &, uvw::tcp_handle &) { assert(false); }); - client->on([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::TCPHandle &) { + client->on([ptr = srv.shared_from_this()](const uvw::close_event &, uvw::tcp_handle &) { std::cout << "close" << std::endl; ptr->close(); }); srv.accept(*client); - uvw::Addr local = srv.sock(); + uvw::socket_address local = srv.sock(); std::cout << "local: " << local.ip << " " << local.port << std::endl; - uvw::Addr remote = client->peer(); + uvw::socket_address remote = client->peer(); std::cout << "remote: " << remote.ip << " " << remote.port << std::endl; - client->on([](const uvw::DataEvent &event, uvw::TCPHandle &) { + client->on([](const uvw::data_event &event, uvw::tcp_handle &) { std::cout.write(event.data.get(), event.length) << std::endl; std::cout << "data length: " << event.length << std::endl; }); - client->on([](const uvw::EndEvent &, uvw::TCPHandle &handle) { + client->on([](const uvw::end_event &, uvw::tcp_handle &handle) { std::cout << "end" << std::endl; int count = 0; - handle.loop().walk([&count](auto &) { ++count; }); + handle.parent().walk([&count](auto &) { ++count; }); std::cout << "still alive: " << count << " handles" << std::endl; handle.close(); }); @@ -43,7 +43,7 @@ void listen(uvw::Loop &loop) { client->read(); }); - tcp->once([](const uvw::CloseEvent &, uvw::TCPHandle &) { + tcp->on([](const uvw::close_event &, uvw::tcp_handle &) { std::cout << "close" << std::endl; }); @@ -51,27 +51,27 @@ void listen(uvw::Loop &loop) { tcp->listen(); } -void conn(uvw::Loop &loop) { - auto tcp = loop.resource(); - tcp->on([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); }); +void conn(uvw::loop &loop) { + auto tcp = loop.resource(); + tcp->on([](const uvw::error_event &, uvw::tcp_handle &) { assert(false); }); - tcp->once([](const uvw::WriteEvent &, uvw::TCPHandle &handle) { + tcp->on([](const uvw::write_event &, uvw::tcp_handle &handle) { std::cout << "write" << std::endl; handle.close(); }); - tcp->once([](const uvw::ConnectEvent &, uvw::TCPHandle &handle) { + tcp->on([](const uvw::connect_event &, uvw::tcp_handle &handle) { std::cout << "connect" << std::endl; auto dataTryWrite = std::unique_ptr(new char[1]{'a'}); - int bw = handle.tryWrite(std::move(dataTryWrite), 1); + int bw = handle.try_write(std::move(dataTryWrite), 1); std::cout << "written: " << ((int)bw) << std::endl; auto dataWrite = std::unique_ptr(new char[2]{'b', 'c'}); handle.write(std::move(dataWrite), 2); }); - tcp->once([](const uvw::CloseEvent &, uvw::TCPHandle &) { + tcp->on([](const uvw::close_event &, uvw::tcp_handle &) { std::cout << "close" << std::endl; }); @@ -79,7 +79,7 @@ void conn(uvw::Loop &loop) { } void g() { - auto loop = uvw::Loop::getDefault(); + auto loop = uvw::loop::get_default(); listen(*loop); conn(*loop); loop->run(); diff --git a/test/uvw/async.cpp b/test/uvw/async.cpp index 28373d15..84afdedd 100644 --- a/test/uvw/async.cpp +++ b/test/uvw/async.cpp @@ -2,22 +2,21 @@ #include TEST(Async, Send) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); bool checkAsyncEvent = false; - handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); - handle->on([&checkAsyncEvent](const auto &, auto &hndl) { + handle->on([&checkAsyncEvent](const auto &, auto &hndl) { ASSERT_FALSE(checkAsyncEvent); checkAsyncEvent = true; hndl.close(); ASSERT_TRUE(hndl.closing()); }); - handle->send(); - + ASSERT_EQ(0, handle->send()); ASSERT_TRUE(handle->active()); ASSERT_FALSE(handle->closing()); @@ -27,11 +26,11 @@ TEST(Async, Send) { } TEST(Async, Fake) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - handle->on([](auto &&...) { FAIL(); }); - handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); handle->send(); handle->close(); diff --git a/test/uvw/check.cpp b/test/uvw/check.cpp index 7089ce80..3c6eb6c5 100644 --- a/test/uvw/check.cpp +++ b/test/uvw/check.cpp @@ -2,37 +2,40 @@ #include TEST(Check, StartAndStop) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); bool checkCheckEvent = false; - handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); - handle->on([&checkCheckEvent](const auto &, auto &hndl) { + handle->on([&checkCheckEvent](const auto &, auto &hndl) { ASSERT_FALSE(checkCheckEvent); + checkCheckEvent = true; - hndl.stop(); + + ASSERT_EQ(0, hndl.stop()); + hndl.close(); + ASSERT_TRUE(hndl.closing()); }); - handle->start(); - + ASSERT_EQ(0, handle->start()); ASSERT_TRUE(handle->active()); ASSERT_FALSE(handle->closing()); - loop->run(); + loop->run(uvw::loop::run_mode::NOWAIT); ASSERT_TRUE(checkCheckEvent); } TEST(Check, Fake) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - handle->on([](auto &&...) { FAIL(); }); - handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); handle->start(); handle->close(); diff --git a/test/uvw/dns.cpp b/test/uvw/dns.cpp index 61d751b8..9120f042 100644 --- a/test/uvw/dns.cpp +++ b/test/uvw/dns.cpp @@ -2,19 +2,19 @@ #include TEST(GetAddrInfo, GetNodeAddrInfo) { - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkAddrInfoEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on([&checkAddrInfoEvent](const auto &, auto &) { + request->on([&checkAddrInfoEvent](const auto &, auto &) { ASSERT_FALSE(checkAddrInfoEvent); checkAddrInfoEvent = true; }); - request->nodeAddrInfo("irc.freenode.net"); + request->node_addr_info("irc.freenode.net"); loop->run(); @@ -22,27 +22,27 @@ TEST(GetAddrInfo, GetNodeAddrInfo) { } TEST(GetAddrInfo, GetNodeAddrInfoSync) { - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); - ASSERT_TRUE(request->nodeAddrInfoSync("irc.freenode.net").first); - ASSERT_FALSE(request->nodeAddrInfoSync("").first); + ASSERT_TRUE(request->node_addr_info_sync("irc.freenode.net").first); + ASSERT_FALSE(request->node_addr_info_sync("").first); loop->run(); } TEST(GetAddrInfo, GetServiceAddrInfo) { - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkErrorEvent = false; - request->on([&checkErrorEvent](const auto &, auto &) { + request->on([&checkErrorEvent](const auto &, auto &) { ASSERT_FALSE(checkErrorEvent); checkErrorEvent = true; }); - request->serviceAddrInfo("foobar"); + request->service_addr_info("foobar"); loop->run(); @@ -50,28 +50,28 @@ TEST(GetAddrInfo, GetServiceAddrInfo) { } TEST(GetAddrInfo, GetServiceAddrInfoSync) { - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); - ASSERT_FALSE(request->serviceAddrInfoSync("foobar").first); + ASSERT_FALSE(request->service_addr_info_sync("foobar").first); loop->run(); } TEST(GetAddrInfo, GetAddrInfo) { - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkAddrInfoEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on([&checkAddrInfoEvent](const auto &, auto &) { + request->on([&checkAddrInfoEvent](const auto &, auto &) { ASSERT_FALSE(checkAddrInfoEvent); checkAddrInfoEvent = true; }); - request->addrInfo("irc.freenode.net", "6667"); + request->addr_info("irc.freenode.net", "6667"); loop->run(); @@ -79,35 +79,35 @@ TEST(GetAddrInfo, GetAddrInfo) { } TEST(GetAddrInfo, GetAddrInfoSync) { - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); - ASSERT_TRUE(request->addrInfoSync("irc.freenode.net", "6667").first); - ASSERT_FALSE(request->addrInfoSync("", "").first); + ASSERT_TRUE(request->addr_info_sync("irc.freenode.net", "6667").first); + ASSERT_FALSE(request->addr_info_sync("", "").first); loop->run(); } TEST(GetNameInfo, GetNameInfo) { - auto loop = uvw::Loop::getDefault(); - auto koRequest = loop->resource(); - auto okRequest = loop->resource(); + auto loop = uvw::loop::get_default(); + auto koRequest = loop->resource(); + auto okRequest = loop->resource(); bool checkErrorEvent = false; bool checkNameInfoEvent = false; - koRequest->on([&checkErrorEvent](const auto &, auto &) { + koRequest->on([&checkErrorEvent](const auto &, auto &) { ASSERT_FALSE(checkErrorEvent); checkErrorEvent = true; }); - okRequest->on([&checkNameInfoEvent](const auto &, auto &) { + okRequest->on([&checkNameInfoEvent](const auto &, auto &) { ASSERT_FALSE(checkNameInfoEvent); checkNameInfoEvent = true; }); - koRequest->nameInfo(uvw::Addr{"", 0}, -1); - okRequest->nameInfo("irc.freenode.net", 6667); + koRequest->name_info(uvw::socket_address{"", 0}, -1); + okRequest->name_info("irc.freenode.net", 6667); loop->run(); @@ -116,11 +116,11 @@ TEST(GetNameInfo, GetNameInfo) { } TEST(GetNameInfo, GetNameInfoSync) { - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); - ASSERT_FALSE(request->nameInfoSync(uvw::Addr{"", 0}, -1).first); - ASSERT_TRUE(request->nameInfoSync("irc.freenode.net", 6667).first); + ASSERT_FALSE(request->name_info_sync(uvw::socket_address{"", 0}, -1).first); + ASSERT_TRUE(request->name_info_sync("irc.freenode.net", 6667).first); loop->run(); } diff --git a/test/uvw/emitter.cpp b/test/uvw/emitter.cpp index 4a754719..29d9ec7c 100644 --- a/test/uvw/emitter.cpp +++ b/test/uvw/emitter.cpp @@ -4,7 +4,7 @@ struct FakeEvent {}; -struct TestEmitter: uvw::Emitter { +struct TestEmitter: uvw::emitter { void emit() { publish(FakeEvent{}); } @@ -13,136 +13,51 @@ struct TestEmitter: uvw::Emitter { TEST(ErrorEvent, Functionalities) { auto ecode = static_cast>(UV_EADDRINUSE); - uvw::ErrorEvent event{ecode}; + uvw::error_event event{ecode}; - ASSERT_EQ(ecode, uvw::ErrorEvent::translate(ecode)); + ASSERT_EQ(ecode, uvw::error_event::translate(ecode)); ASSERT_NE(event.what(), nullptr); ASSERT_NE(event.name(), nullptr); ASSERT_EQ(event.code(), ecode); - ASSERT_FALSE(static_cast(uvw::ErrorEvent{0})); - ASSERT_TRUE(static_cast(uvw::ErrorEvent{ecode})); + ASSERT_FALSE(static_cast(uvw::error_event{0})); + ASSERT_TRUE(static_cast(uvw::error_event{ecode})); } -TEST(Emitter, EmptyAndClear) { +TEST(Emitter, Functionalities) { TestEmitter emitter{}; - ASSERT_TRUE(emitter.empty()); + emitter.on([](const auto &, auto &) {}); - emitter.on([](const auto &, auto &) {}); + ASSERT_TRUE(emitter.has()); + ASSERT_FALSE(emitter.has()); - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); + emitter.reset(); - emitter.clear(); + ASSERT_TRUE(emitter.has()); + ASSERT_FALSE(emitter.has()); - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); + emitter.reset(); - emitter.clear(); + ASSERT_FALSE(emitter.has()); + ASSERT_FALSE(emitter.has()); - ASSERT_TRUE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); + bool sentinel = false; + emitter.on([](const auto &, auto &) {}); + emitter.on([&](const auto &, auto &) { sentinel = true; }); - emitter.on([](const auto &, auto &) {}); - emitter.on([](const auto &, auto &) {}); - - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); - - emitter.clear(); - - ASSERT_TRUE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); -} - -TEST(Emitter, On) { - TestEmitter emitter{}; - - emitter.on([](const auto &, auto &) {}); - - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); + ASSERT_FALSE(sentinel); + ASSERT_TRUE(emitter.has()); + ASSERT_TRUE(emitter.has()); emitter.emit(); - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); -} - -TEST(Emitter, Once) { - TestEmitter emitter{}; - - emitter.once([](const auto &, auto &) {}); - - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); - - emitter.emit(); - - ASSERT_TRUE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); -} - -TEST(Emitter, OnceAndErase) { - TestEmitter emitter{}; - - auto conn = emitter.once([](const auto &, auto &) {}); - - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); - - emitter.erase(conn); - - ASSERT_TRUE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); -} - -TEST(Emitter, OnAndErase) { - TestEmitter emitter{}; - - auto conn = emitter.on([](const auto &, auto &) {}); - - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); - - emitter.erase(conn); - - ASSERT_TRUE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); -} - -TEST(Emitter, CallbackClear) { - TestEmitter emitter{}; - - emitter.on([](const auto &, auto &ref) { - ref.template on([](const auto &, auto &) {}); - ref.clear(); - }); - - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); - - emitter.emit(); - - ASSERT_TRUE(emitter.empty()); - ASSERT_TRUE(emitter.empty()); - - emitter.on([](const auto &, auto &ref) { - ref.clear(); - ref.template on([](const auto &, auto &) {}); - }); - - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); - - emitter.emit(); - - ASSERT_FALSE(emitter.empty()); - ASSERT_FALSE(emitter.empty()); + ASSERT_TRUE(sentinel); + ASSERT_TRUE(emitter.has()); + ASSERT_TRUE(emitter.has()); + + emitter.reset(); + + ASSERT_FALSE(emitter.has()); + ASSERT_FALSE(emitter.has()); } diff --git a/test/uvw/file_req.cpp b/test/uvw/file_req.cpp index eab31e0f..ced59f26 100644 --- a/test/uvw/file_req.cpp +++ b/test/uvw/file_req.cpp @@ -10,24 +10,24 @@ TEST(FileReq, OpenAndCloseErr) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/err.file"}; - auto loop = uvw::Loop::getDefault(); - auto openReq = loop->resource(); - auto closeReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto openReq = loop->resource(); + auto closeReq = loop->resource(); bool checkFileOpenErrorEvent = false; bool checkFileCloseErrorEvent = false; - openReq->on([&checkFileOpenErrorEvent](const auto &, auto &) { + openReq->on([&checkFileOpenErrorEvent](const auto &, auto &) { ASSERT_FALSE(checkFileOpenErrorEvent); checkFileOpenErrorEvent = true; }); - closeReq->on([&checkFileCloseErrorEvent](const auto &, auto &) { + closeReq->on([&checkFileCloseErrorEvent](const auto &, auto &) { ASSERT_FALSE(checkFileCloseErrorEvent); checkFileCloseErrorEvent = true; }); - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::RDONLY; openReq->open(filename, flags, 0644); closeReq->close(); @@ -40,11 +40,12 @@ TEST(FileReq, OpenAndCloseErr) { TEST(FileReq, OpenAndCloseErrSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/err.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::RDONLY; - ASSERT_FALSE(request->openSync(filename, O_RDONLY, 0644)); - ASSERT_FALSE(request->closeSync()); + ASSERT_FALSE(request->open_sync(filename, flags, 0644)); + ASSERT_FALSE(request->close_sync()); loop->run(); } @@ -52,26 +53,26 @@ TEST(FileReq, OpenAndCloseErrSync) { TEST(FileReq, OpenAndClose) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileOpenEvent = false; bool checkFileCloseEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileCloseEvent](const auto &, auto &) { - ASSERT_FALSE(checkFileCloseEvent); - checkFileCloseEvent = true; + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + ASSERT_FALSE(checkFileCloseEvent); + checkFileCloseEvent = true; + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + ASSERT_FALSE(checkFileOpenEvent); + checkFileOpenEvent = true; + req.close(); + }; }); - request->on>([&checkFileOpenEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileOpenEvent); - checkFileOpenEvent = true; - req.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::WRONLY; request->open(filename, flags, 0644); loop->run(); @@ -83,11 +84,12 @@ TEST(FileReq, OpenAndClose) { TEST(FileReq, OpenAndCloseSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::WRONLY; - ASSERT_TRUE(request->openSync(filename, O_CREAT | O_WRONLY, 0644)); - ASSERT_TRUE(request->closeSync()); + ASSERT_TRUE(request->open_sync(filename, flags, 0644)); + ASSERT_TRUE(request->close_sync()); loop->run(); } @@ -95,32 +97,30 @@ TEST(FileReq, OpenAndCloseSync) { TEST(FileReq, RWChecked) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileWriteEvent = false; bool checkFileReadEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileReadEvent](const auto &event, auto &req) { - ASSERT_FALSE(checkFileReadEvent); - ASSERT_EQ(event.data[0], 42); - checkFileReadEvent = true; - req.close(); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::OPEN) { + req.write(std::unique_ptr{new char[1]{42}}, 1, 0); + } else if(event.type == uvw::fs_req::fs_type::READ) { + ASSERT_FALSE(checkFileReadEvent); + ASSERT_EQ(event.read.data[0], 42); + checkFileReadEvent = true; + req.close(); + } else if(event.type == uvw::fs_req::fs_type::WRITE) { + ASSERT_FALSE(checkFileWriteEvent); + checkFileWriteEvent = true; + req.read(0, 1); + }; }); - request->on>([&checkFileWriteEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileWriteEvent); - checkFileWriteEvent = true; - req.read(0, 1); - }); - - request->on>([](const auto &, auto &req) { - req.write(std::unique_ptr{new char[1]{42}}, 1, 0); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); loop->run(); @@ -133,32 +133,30 @@ TEST(FileReq, RWUnchecked) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; std::unique_ptr data{new char[1]{42}}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileWriteEvent = false; bool checkFileReadEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileReadEvent](const auto &event, auto &req) { - ASSERT_FALSE(checkFileReadEvent); - ASSERT_EQ(event.data[0], 42); - checkFileReadEvent = true; - req.close(); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::OPEN) { + req.write(data.get(), 1, 0); + } else if(event.type == uvw::fs_req::fs_type::READ) { + ASSERT_FALSE(checkFileReadEvent); + ASSERT_EQ(event.read.data[0], 42); + checkFileReadEvent = true; + req.close(); + } else if(event.type == uvw::fs_req::fs_type::WRITE) { + ASSERT_FALSE(checkFileWriteEvent); + checkFileWriteEvent = true; + req.read(0, 1); + }; }); - request->on>([&checkFileWriteEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileWriteEvent); - checkFileWriteEvent = true; - req.read(0, 1); - }); - - request->on>([&data](const auto &, auto &req) { - req.write(data.get(), 1, 0); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); loop->run(); @@ -170,22 +168,23 @@ TEST(FileReq, RWUnchecked) { TEST(FileReq, RWSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); + ASSERT_TRUE(request->open_sync(filename, flags, 0644)); - auto writeR = request->writeSync(std::unique_ptr{new char[1]{42}}, 1, 0); + auto writeR = request->write_sync(std::unique_ptr{new char[1]{42}}, 1, 0); ASSERT_TRUE(writeR.first); ASSERT_EQ(writeR.second, std::size_t{1}); - auto readR = request->readSync(0, 1); + auto readR = request->read_sync(0, 1); ASSERT_TRUE(readR.first); ASSERT_EQ(readR.second.first[0], 42); ASSERT_EQ(readR.second.second, std::size_t{1}); - ASSERT_TRUE(request->closeSync()); + ASSERT_TRUE(request->close_sync()); loop->run(); } @@ -193,24 +192,24 @@ TEST(FileReq, RWSync) { TEST(FileReq, Stat) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileStatEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileStatEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileStatEvent); - checkFileStatEvent = true; - req.close(); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::OPEN) { + req.stat(); + } else if(event.type == uvw::fs_req::fs_type::FSTAT) { + ASSERT_FALSE(checkFileStatEvent); + checkFileStatEvent = true; + req.close(); + }; }); - request->on>([](const auto &, auto &req) { - req.stat(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); loop->run(); @@ -221,15 +220,16 @@ TEST(FileReq, Stat) { TEST(FileReq, StatSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); + ASSERT_TRUE(request->open_sync(filename, flags, 0644)); - auto statR = request->statSync(); + auto statR = request->stat_sync(); ASSERT_TRUE(statR.first); - ASSERT_TRUE(request->closeSync()); + ASSERT_TRUE(request->close_sync()); loop->run(); } @@ -237,24 +237,24 @@ TEST(FileReq, StatSync) { TEST(FileReq, Sync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileSyncEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileSyncEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileSyncEvent); - checkFileSyncEvent = true; - req.close(); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::FSYNC) { + ASSERT_FALSE(checkFileSyncEvent); + checkFileSyncEvent = true; + req.close(); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.sync(); + }; }); - request->on>([](const auto &, auto &req) { - req.sync(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); loop->run(); @@ -265,12 +265,13 @@ TEST(FileReq, Sync) { TEST(FileReq, SyncSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(request->syncSync()); - ASSERT_TRUE(request->closeSync()); + ASSERT_TRUE(request->open_sync(filename, flags, 0644)); + ASSERT_TRUE(request->sync_sync()); + ASSERT_TRUE(request->close_sync()); loop->run(); } @@ -278,24 +279,24 @@ TEST(FileReq, SyncSync) { TEST(FileReq, Datasync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileDatasyncEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileDatasyncEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileDatasyncEvent); - checkFileDatasyncEvent = true; - req.close(); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::FDATASYNC) { + ASSERT_FALSE(checkFileDatasyncEvent); + checkFileDatasyncEvent = true; + req.close(); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.datasync(); + }; }); - request->on>([](const auto &, auto &req) { - req.datasync(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); loop->run(); @@ -306,12 +307,13 @@ TEST(FileReq, Datasync) { TEST(FileReq, DatasyncSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(request->datasyncSync()); - ASSERT_TRUE(request->closeSync()); + ASSERT_TRUE(request->open_sync(filename, flags, 0644)); + ASSERT_TRUE(request->datasync_sync()); + ASSERT_TRUE(request->close_sync()); loop->run(); } @@ -319,24 +321,24 @@ TEST(FileReq, DatasyncSync) { TEST(FileReq, Truncate) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileTruncateEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileTruncateEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileTruncateEvent); - checkFileTruncateEvent = true; - req.close(); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::FTRUNCATE) { + ASSERT_FALSE(checkFileTruncateEvent); + checkFileTruncateEvent = true; + req.close(); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.truncate(0); + }; }); - request->on>([](const auto &, auto &req) { - req.truncate(0); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); loop->run(); @@ -347,12 +349,13 @@ TEST(FileReq, Truncate) { TEST(FileReq, TruncateSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(request->truncateSync(0)); - ASSERT_TRUE(request->closeSync()); + ASSERT_TRUE(request->open_sync(filename, flags, 0644)); + ASSERT_TRUE(request->truncate_sync(0)); + ASSERT_TRUE(request->close_sync()); loop->run(); } @@ -360,24 +363,24 @@ TEST(FileReq, TruncateSync) { TEST(FileReq, Chmod) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileChmodEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileChmodEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileChmodEvent); - checkFileChmodEvent = true; - req.close(); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::FCHMOD) { + ASSERT_FALSE(checkFileChmodEvent); + checkFileChmodEvent = true; + req.close(); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.chmod(0644); + }; }); - request->on>([](const auto &, auto &req) { - req.chmod(0644); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); loop->run(); @@ -388,12 +391,13 @@ TEST(FileReq, Chmod) { TEST(FileReq, ChmodSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(request->chmodSync(0644)); - ASSERT_TRUE(request->closeSync()); + ASSERT_TRUE(request->open_sync(filename, flags, 0644)); + ASSERT_TRUE(request->chmod_sync(0644)); + ASSERT_TRUE(request->close_sync()); loop->run(); } @@ -401,27 +405,26 @@ TEST(FileReq, ChmodSync) { TEST(FileReq, Futime) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileUtimeEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileUtimeEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileUtimeEvent); - checkFileUtimeEvent = true; - req.close(); + request->on([&](const auto &event, auto &req) { + const auto value = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + + if(event.type == uvw::fs_req::fs_type::FUTIME) { + ASSERT_FALSE(checkFileUtimeEvent); + checkFileUtimeEvent = true; + req.close(); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.futime(value, value); + }; }); - request->on>([](const auto &, auto &req) { - auto now = std::chrono::system_clock::now(); - auto epoch = now.time_since_epoch(); - auto value = std::chrono::duration_cast(epoch); - req.futime(value, value); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); loop->run(); @@ -432,18 +435,19 @@ TEST(FileReq, Futime) { TEST(FileReq, FutimeSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); + ASSERT_TRUE(request->open_sync(filename, flags, 0644)); auto now = std::chrono::system_clock::now(); auto epoch = now.time_since_epoch(); auto value = std::chrono::duration_cast(epoch); - ASSERT_TRUE(request->futimeSync(value, value)); - ASSERT_TRUE(request->truncateSync(0)); - ASSERT_TRUE(request->closeSync()); + ASSERT_TRUE(request->futime_sync(value, value)); + ASSERT_TRUE(request->truncate_sync(0)); + ASSERT_TRUE(request->close_sync()); loop->run(); } @@ -451,30 +455,26 @@ TEST(FileReq, FutimeSync) { TEST(FileReq, Chown) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFileChownEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFileChownEvent](const auto &, auto &req) { - ASSERT_FALSE(checkFileChownEvent); - checkFileChownEvent = true; - req.close(); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::FCHOWN) { + ASSERT_FALSE(checkFileChownEvent); + checkFileChownEvent = true; + req.close(); + } else if(event.type == uvw::fs_req::fs_type::FSTAT) { + req.chown(static_cast(event.stat.st_uid), static_cast(event.stat.st_gid)); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.stat(); + }; }); - request->on>([](const auto &event, auto &req) { - auto uid = static_cast(event.stat.st_uid); - auto gid = static_cast(event.stat.st_gid); - req.chown(uid, gid); - }); - - request->on>([](const auto &, auto &req) { - req.stat(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); loop->run(); @@ -485,18 +485,19 @@ TEST(FileReq, Chown) { TEST(FileReq, ChownSync) { const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); + ASSERT_TRUE(request->open_sync(filename, flags, 0644)); - auto statR = request->statSync(); + auto statR = request->stat_sync(); ASSERT_TRUE(statR.first); - auto uid = static_cast(statR.second.st_uid); - auto gid = static_cast(statR.second.st_gid); - ASSERT_TRUE(request->chownSync(uid, gid)); - ASSERT_TRUE(request->closeSync()); + auto uid = static_cast(statR.second.st_uid); + auto gid = static_cast(statR.second.st_gid); + ASSERT_TRUE(request->chown_sync(uid, gid)); + ASSERT_TRUE(request->close_sync()); loop->run(); } diff --git a/test/uvw/file_req_sendfile.cpp b/test/uvw/file_req_sendfile.cpp index 8120e269..dae160da 100644 --- a/test/uvw/file_req_sendfile.cpp +++ b/test/uvw/file_req_sendfile.cpp @@ -11,32 +11,33 @@ TEST(FileReq, SendFile) { const std::string srcFilename = std::string{TARGET_FILE_REQ_SENDFILE_DIR} + std::string{"/src.file"}; const std::string dstFilename = std::string{TARGET_FILE_REQ_SENDFILE_DIR} + std::string{"/dst.file"}; - auto loop = uvw::Loop::getDefault(); - auto srcReq = loop->resource(); - auto dstReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto srcReq = loop->resource(); + auto dstReq = loop->resource(); bool checkFileSendFileEvent = false; - dstReq->on([](const auto &, auto &) { FAIL(); }); - srcReq->on([](const auto &, auto &) { FAIL(); }); + dstReq->on([](const auto &, auto &) { FAIL(); }); + srcReq->on([](const auto &, auto &) { FAIL(); }); - dstReq->on>([&srcReq](const auto &, auto &req) { - srcReq->sendfile(static_cast(req), 0, 0); + dstReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::OPEN) { + srcReq->sendfile(static_cast(req), 0, 0); + } }); - srcReq->on>([&checkFileSendFileEvent, &dstReq](const auto &, auto &req) { - ASSERT_FALSE(checkFileSendFileEvent); - checkFileSendFileEvent = true; - dstReq->close(); - req.close(); + srcReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::SENDFILE) { + ASSERT_FALSE(checkFileSendFileEvent); + checkFileSendFileEvent = true; + dstReq->close(); + req.close(); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + dstReq->open(dstFilename, uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::WRONLY | uvw::file_req::file_open_flags::TRUNC, 0644); + } }); - srcReq->on>([&dstFilename, &dstReq](const auto &, auto &) { - auto flags = uvw::Flags::from(); - dstReq->open(dstFilename, flags, 0644); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDONLY | uvw::file_req::file_open_flags::TRUNC; srcReq->open(srcFilename, flags, 0644); loop->run(); @@ -48,18 +49,18 @@ TEST(FileReq, SendFileSync) { const std::string srcFilename = std::string{TARGET_FILE_REQ_SENDFILE_DIR} + std::string{"/src.file"}; const std::string dstFilename = std::string{TARGET_FILE_REQ_SENDFILE_DIR} + std::string{"/dst.file"}; - auto loop = uvw::Loop::getDefault(); - auto srcReq = loop->resource(); - auto dstReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto srcReq = loop->resource(); + auto dstReq = loop->resource(); - ASSERT_TRUE(srcReq->openSync(srcFilename, O_CREAT | O_RDONLY | O_TRUNC, 0644)); - ASSERT_TRUE(dstReq->openSync(dstFilename, O_CREAT | O_WRONLY | O_TRUNC, 0644)); + ASSERT_TRUE(srcReq->open_sync(srcFilename, uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDONLY | uvw::file_req::file_open_flags::TRUNC, 0644)); + ASSERT_TRUE(dstReq->open_sync(dstFilename, uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::WRONLY | uvw::file_req::file_open_flags::TRUNC, 0644)); - auto sendfileR = srcReq->sendfileSync(static_cast(*dstReq), 0, 0); + auto sendfileR = srcReq->sendfile_sync(static_cast(*dstReq), 0, 0); ASSERT_TRUE(sendfileR.first); - ASSERT_TRUE(srcReq->closeSync()); - ASSERT_TRUE(dstReq->closeSync()); + ASSERT_TRUE(srcReq->close_sync()); + ASSERT_TRUE(dstReq->close_sync()); loop->run(); } diff --git a/test/uvw/fs_event.cpp b/test/uvw/fs_event.cpp index e22efd4f..db6dae9f 100644 --- a/test/uvw/fs_event.cpp +++ b/test/uvw/fs_event.cpp @@ -5,40 +5,49 @@ TEST(FsEvent, Functionalities) { const std::string filename = std::string{TARGET_FS_EVENT_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); + auto request = loop->resource(); bool checkFsEventEvent = false; - handle->on([](const auto &, auto &) { FAIL(); }); - request->on([](const auto &, auto &) { FAIL(); }); + handle->on([&](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - handle->on([&checkFsEventEvent](const auto &event, auto &hndl) { + handle->on([&checkFsEventEvent](const auto &event, auto &hndl) { ASSERT_FALSE(checkFsEventEvent); ASSERT_EQ(std::string{event.filename}, std::string{"test.file"}); + checkFsEventEvent = true; - hndl.stop(); + + ASSERT_EQ(0, hndl.stop()); + hndl.close(); + ASSERT_TRUE(hndl.closing()); }); - request->on>([](const auto &, auto &req) { - req.close(); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::WRITE) { + req.close(); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.write(std::unique_ptr{new char[1]{42}}, 1, 0); + } }); - request->on>([](const auto &, auto &req) { - req.write(std::unique_ptr{new char[1]{42}}, 1, 0); - }); - - handle->start(std::string{TARGET_FS_EVENT_DIR}, uvw::FsEventHandle::Event::RECURSIVE); - auto flags = uvw::Flags::from(); + ASSERT_EQ(0, handle->start(std::string{TARGET_FS_EVENT_DIR}, uvw::fs_event_handle::event_flags::RECURSIVE)); + + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; request->open(filename, flags, 0644); ASSERT_EQ(handle->path(), std::string{TARGET_FS_EVENT_DIR}); ASSERT_TRUE(handle->active()); ASSERT_FALSE(handle->closing()); + ASSERT_NE(0, handle->start(std::string{TARGET_FS_EVENT_DIR}, uvw::fs_event_handle::event_flags::RECURSIVE)); + + ASSERT_FALSE(checkFsEventEvent); + loop->run(); ASSERT_TRUE(checkFsEventEvent); diff --git a/test/uvw/fs_poll.cpp b/test/uvw/fs_poll.cpp deleted file mode 100644 index 187241af..00000000 --- a/test/uvw/fs_poll.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include - -TEST(FsPoll, Functionalities) { - const std::string filename = std::string{TARGET_FS_POLL_DIR} + std::string{"/test.file"}; - - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); - auto request = loop->resource(); - - bool checkFsPollEvent = false; - - handle->on([](const auto &, auto &) { FAIL(); }); - request->on([](const auto &, auto &) { FAIL(); }); - - handle->on([&checkFsPollEvent](const auto &, auto &hndl) { - ASSERT_FALSE(checkFsPollEvent); - checkFsPollEvent = true; - hndl.stop(); - hndl.close(); - ASSERT_TRUE(hndl.closing()); - }); - - request->on>([](const auto &, auto &req) { - req.close(); - }); - - request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0755); - handle->start(filename, uvw::FsPollHandle::Time{1000}); - request->write(std::unique_ptr{new char[1]{42}}, 1, 0); - - ASSERT_EQ(handle->path(), filename); - ASSERT_TRUE(handle->active()); - ASSERT_FALSE(handle->closing()); - - loop->run(); - - ASSERT_TRUE(checkFsPollEvent); -} diff --git a/test/uvw/fs_req.cpp b/test/uvw/fs_req.cpp index 7b89d7e6..bc64262c 100644 --- a/test/uvw/fs_req.cpp +++ b/test/uvw/fs_req.cpp @@ -10,23 +10,23 @@ TEST(FsReq, MkdirAndRmdir) { const std::string dirname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.dir"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFsMkdirEvent = false; bool checkFsRmdirEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFsRmdirEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsRmdirEvent); - checkFsRmdirEvent = true; - }); - - request->on>([&checkFsMkdirEvent, &dirname](const auto &, auto &req) { - ASSERT_FALSE(checkFsMkdirEvent); - checkFsMkdirEvent = true; - req.rmdir(dirname); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::MKDIR) { + ASSERT_FALSE(checkFsMkdirEvent); + checkFsMkdirEvent = true; + req.rmdir(dirname); + } else if(event.type == uvw::fs_req::fs_type::RMDIR) { + ASSERT_FALSE(checkFsRmdirEvent); + checkFsRmdirEvent = true; + }; }); request->mkdir(dirname, 0755); @@ -40,11 +40,11 @@ TEST(FsReq, MkdirAndRmdir) { TEST(FsReq, MkdirAndRmdirSync) { const std::string dirname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.dir"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); - ASSERT_TRUE(request->mkdirSync(dirname, 0755)); - ASSERT_TRUE(request->rmdirSync(dirname)); + ASSERT_TRUE(request->mkdir_sync(dirname, 0755)); + ASSERT_TRUE(request->rmdir_sync(dirname)); loop->run(); } @@ -52,24 +52,24 @@ TEST(FsReq, MkdirAndRmdirSync) { TEST(FsReq, MkdtempAndRmdir) { const std::string dirname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.dir.XXXXXX"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); bool checkFsMkdtempEvent = false; bool checkFsRmdirEvent = false; - request->on([](const auto &, auto &) { FAIL(); }); + request->on([](const auto &, auto &) { FAIL(); }); - request->on>([&checkFsRmdirEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsRmdirEvent); - checkFsRmdirEvent = true; - }); - - request->on>([&checkFsMkdtempEvent](const auto &event, auto &req) { - ASSERT_FALSE(checkFsMkdtempEvent); - ASSERT_NE(event.path, nullptr); - checkFsMkdtempEvent = true; - req.rmdir(event.path); + request->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::MKDTEMP) { + ASSERT_FALSE(checkFsMkdtempEvent); + ASSERT_NE(event.path, nullptr); + checkFsMkdtempEvent = true; + req.rmdir(event.path); + } else if(event.type == uvw::fs_req::fs_type::RMDIR) { + ASSERT_FALSE(checkFsRmdirEvent); + checkFsRmdirEvent = true; + }; }); request->mkdtemp(dirname); @@ -83,14 +83,14 @@ TEST(FsReq, MkdtempAndRmdir) { TEST(FsReq, MkdtempAndRmdirSync) { const std::string dirname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.dir.XXXXXX"}; - auto loop = uvw::Loop::getDefault(); - auto request = loop->resource(); + auto loop = uvw::loop::get_default(); + auto request = loop->resource(); - auto mkdtempR = request->mkdtempSync(dirname); + auto mkdtempR = request->mkdtemp_sync(dirname); ASSERT_TRUE(mkdtempR.first); ASSERT_NE(mkdtempR.second, nullptr); - ASSERT_TRUE(request->rmdirSync(mkdtempR.second)); + ASSERT_TRUE(request->rmdir_sync(mkdtempR.second)); loop->run(); } @@ -98,29 +98,31 @@ TEST(FsReq, MkdtempAndRmdirSync) { TEST(FsReq, Stat) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsStatEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsStatEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsStatEvent); - checkFsStatEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::STAT) { + ASSERT_FALSE(checkFsStatEvent); + checkFsStatEvent = true; + } }); - fileReq->on>([&fsReq, &filename](const auto &, auto &) { - fsReq->stat(filename); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->stat(filename); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -131,14 +133,15 @@ TEST(FsReq, Stat) { TEST(FsReq, StatSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); - auto statR = fsReq->statSync(filename); + auto statR = fsReq->stat_sync(filename); ASSERT_TRUE(statR.first); @@ -148,29 +151,31 @@ TEST(FsReq, StatSync) { TEST(FsReq, Lstat) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsLstatEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsLstatEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsLstatEvent); - checkFsLstatEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::LSTAT) { + ASSERT_FALSE(checkFsLstatEvent); + checkFsLstatEvent = true; + } }); - fileReq->on>([&fsReq, &filename](const auto &, auto &) { - fsReq->lstat(filename); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->lstat(filename); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -181,14 +186,15 @@ TEST(FsReq, Lstat) { TEST(FsReq, LstatSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); - auto statR = fsReq->lstatSync(filename); + auto statR = fsReq->lstat_sync(filename); ASSERT_TRUE(statR.first); @@ -199,29 +205,31 @@ TEST(FsReq, Rename) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; const std::string rename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.rename"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsRenameEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsRenameEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsRenameEvent); - checkFsRenameEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::RENAME) { + ASSERT_FALSE(checkFsRenameEvent); + checkFsRenameEvent = true; + } }); - fileReq->on>([&fsReq, &filename, &rename](const auto &, auto &) { - fsReq->rename(filename, rename); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->rename(filename, rename); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -233,13 +241,14 @@ TEST(FsReq, RenameSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; const std::string rename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.rename"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); - ASSERT_TRUE(fsReq->renameSync(filename, rename)); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); + ASSERT_TRUE(fsReq->rename_sync(filename, rename)); loop->run(); } @@ -247,29 +256,31 @@ TEST(FsReq, RenameSync) { TEST(FsReq, Access) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsAccessEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsAccessEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsAccessEvent); - checkFsAccessEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::ACCESS) { + ASSERT_FALSE(checkFsAccessEvent); + checkFsAccessEvent = true; + } }); - fileReq->on>([&fsReq, &filename](const auto &, auto &) { - fsReq->access(filename, R_OK); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->access(filename, R_OK); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -280,13 +291,14 @@ TEST(FsReq, Access) { TEST(FsReq, AccessSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); - ASSERT_TRUE(fsReq->accessSync(filename, R_OK)); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); + ASSERT_TRUE(fsReq->access_sync(filename, R_OK)); loop->run(); } @@ -294,29 +306,31 @@ TEST(FsReq, AccessSync) { TEST(FsReq, Chmod) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsChmodEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsChmodEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsChmodEvent); - checkFsChmodEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CHMOD) { + ASSERT_FALSE(checkFsChmodEvent); + checkFsChmodEvent = true; + } }); - fileReq->on>([&fsReq, &filename](const auto &, auto &) { - fsReq->chmod(filename, 0644); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->chmod(filename, 0644); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -327,13 +341,14 @@ TEST(FsReq, Chmod) { TEST(FsReq, ChmodSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); - ASSERT_TRUE(fsReq->chmodSync(filename, 0644)); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); + ASSERT_TRUE(fsReq->chmod_sync(filename, 0644)); loop->run(); } @@ -341,32 +356,33 @@ TEST(FsReq, ChmodSync) { TEST(FsReq, Utime) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsUtimeEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsUtimeEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsUtimeEvent); - checkFsUtimeEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::UTIME) { + ASSERT_FALSE(checkFsUtimeEvent); + checkFsUtimeEvent = true; + } }); - fileReq->on>([&fsReq, &filename](const auto &, auto &) { - auto now = std::chrono::system_clock::now(); - auto epoch = now.time_since_epoch(); - auto value = std::chrono::duration_cast(epoch); - fsReq->utime(filename, value, value); + fileReq->on([&](const auto &event, auto &req) { + const auto value = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->utime(filename, value, value); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -377,18 +393,19 @@ TEST(FsReq, Utime) { TEST(FsReq, UtimeSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); auto now = std::chrono::system_clock::now(); auto epoch = now.time_since_epoch(); auto value = std::chrono::duration_cast(epoch); - ASSERT_TRUE(fileReq->closeSync()); - ASSERT_TRUE(fsReq->utimeSync(filename, value, value)); + ASSERT_TRUE(fileReq->close_sync()); + ASSERT_TRUE(fsReq->utime_sync(filename, value, value)); loop->run(); } @@ -397,36 +414,36 @@ TEST(FsReq, LinkAndUnlink) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsLinkEvent = false; bool checkFsUnlinkEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsUnlinkEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsUnlinkEvent); - checkFsUnlinkEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::LINK) { + ASSERT_FALSE(checkFsLinkEvent); + checkFsLinkEvent = true; + req.unlink(linkname); + } else if(event.type == uvw::fs_req::fs_type::UNLINK) { + ASSERT_FALSE(checkFsUnlinkEvent); + checkFsUnlinkEvent = true; + } }); - fsReq->on>([&checkFsLinkEvent, &linkname](const auto &, auto &request) { - ASSERT_FALSE(checkFsLinkEvent); - checkFsLinkEvent = true; - request.unlink(linkname); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->link(filename, linkname); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([&fsReq, &filename, &linkname](const auto &, auto &) { - fsReq->link(filename, linkname); - }); - - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -439,14 +456,15 @@ TEST(FsReq, LinkAndUnlinkSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); - ASSERT_TRUE(fsReq->linkSync(filename, linkname)); - ASSERT_TRUE(fsReq->unlinkSync(linkname)); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); + ASSERT_TRUE(fsReq->link_sync(filename, linkname)); + ASSERT_TRUE(fsReq->unlink_sync(linkname)); loop->run(); } @@ -455,36 +473,36 @@ TEST(FsReq, SymlinkAndUnlink) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsLinkEvent = false; bool checkFsUnlinkEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsUnlinkEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsUnlinkEvent); - checkFsUnlinkEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::SYMLINK) { + ASSERT_FALSE(checkFsLinkEvent); + checkFsLinkEvent = true; + req.unlink(linkname); + } else if(event.type == uvw::fs_req::fs_type::UNLINK) { + ASSERT_FALSE(checkFsUnlinkEvent); + checkFsUnlinkEvent = true; + } }); - fsReq->on>([&checkFsLinkEvent, &linkname](const auto &, auto &request) { - ASSERT_FALSE(checkFsLinkEvent); - checkFsLinkEvent = true; - request.unlink(linkname); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->symlink(filename, linkname); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([&fsReq, &filename, &linkname](const auto &, auto &) { - fsReq->symlink(filename, linkname); - }); - - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -497,14 +515,15 @@ TEST(FsReq, SymlinkAndUnlinkSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); - ASSERT_TRUE(fsReq->symlinkSync(filename, linkname)); - ASSERT_TRUE(fsReq->unlinkSync(linkname)); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); + ASSERT_TRUE(fsReq->symlink_sync(filename, linkname)); + ASSERT_TRUE(fsReq->unlink_sync(linkname)); loop->run(); } @@ -513,34 +532,34 @@ TEST(FsReq, Readlink) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsReadlinkEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsReadlinkEvent, &linkname](const auto &, auto &request) { - ASSERT_FALSE(checkFsReadlinkEvent); - checkFsReadlinkEvent = true; - request.unlink(linkname); + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::READLINK) { + ASSERT_FALSE(checkFsReadlinkEvent); + checkFsReadlinkEvent = true; + req.unlink(linkname); + } else if(event.type == uvw::fs_req::fs_type::SYMLINK) { + req.readlink(linkname); + } }); - fsReq->on>([&linkname](const auto &, auto &request) { - request.readlink(linkname); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->symlink(filename, linkname); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([&fsReq, &filename, &linkname](const auto &, auto &) { - fsReq->symlink(filename, linkname, 0); - }); - - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -552,18 +571,19 @@ TEST(FsReq, ReadlinkSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); - ASSERT_TRUE(fsReq->symlinkSync(filename, linkname, 0)); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); + ASSERT_TRUE(fsReq->symlink_sync(filename, linkname)); - auto readlinkR = fsReq->readlinkSync(linkname); + auto readlinkR = fsReq->readlink_sync(linkname); ASSERT_TRUE(readlinkR.first); - ASSERT_TRUE(fsReq->unlinkSync(linkname)); + ASSERT_TRUE(fsReq->unlink_sync(linkname)); loop->run(); } @@ -571,30 +591,32 @@ TEST(FsReq, ReadlinkSync) { TEST(FsReq, Realpath) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsRealpathEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsRealpathEvent](const auto &event, auto &) { - ASSERT_FALSE(checkFsRealpathEvent); - ASSERT_NE(event.path, nullptr); - checkFsRealpathEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::REALPATH) { + ASSERT_FALSE(checkFsRealpathEvent); + ASSERT_NE(event.path, nullptr); + checkFsRealpathEvent = true; + }; }); - fileReq->on>([&fsReq, &filename](const auto &, auto &) { - fsReq->realpath(filename); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->realpath(filename); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -605,14 +627,15 @@ TEST(FsReq, Realpath) { TEST(FsReq, RealpathSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); - auto realpathR = fsReq->realpathSync(filename); + auto realpathR = fsReq->realpath_sync(filename); ASSERT_TRUE(realpathR.first); ASSERT_NE(realpathR.second, nullptr); @@ -623,35 +646,33 @@ TEST(FsReq, RealpathSync) { TEST(FsReq, Chown) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsChownEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsChownEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsChownEvent); - checkFsChownEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CHOWN) { + ASSERT_FALSE(checkFsChownEvent); + checkFsChownEvent = true; + } else if(event.type == uvw::fs_req::fs_type::STAT) { + req.chown(filename, static_cast(event.stat.st_uid), static_cast(event.stat.st_gid)); + }; }); - fsReq->on>([&filename](const auto &event, auto &request) { - auto uid = static_cast(event.stat.st_uid); - auto gid = static_cast(event.stat.st_gid); - request.chown(filename, uid, gid); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->stat(filename); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([&fsReq, &filename](const auto &, auto &) { - fsReq->stat(filename); - }); - - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -662,19 +683,20 @@ TEST(FsReq, Chown) { TEST(FsReq, ChownSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); - auto statR = fsReq->statSync(filename); + auto statR = fsReq->stat_sync(filename); ASSERT_TRUE(statR.first); - auto uid = static_cast(statR.second.st_uid); - auto gid = static_cast(statR.second.st_gid); - ASSERT_TRUE(fsReq->chownSync(filename, uid, gid)); + auto uid = static_cast(statR.second.st_uid); + auto gid = static_cast(statR.second.st_gid); + ASSERT_TRUE(fsReq->chown_sync(filename, uid, gid)); loop->run(); } @@ -682,35 +704,33 @@ TEST(FsReq, ChownSync) { TEST(FsReq, Lchown) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); bool checkFsLChownEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); - fileReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); + fileReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsLChownEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsLChownEvent); - checkFsLChownEvent = true; + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::LCHOWN) { + ASSERT_FALSE(checkFsLChownEvent); + checkFsLChownEvent = true; + } else if(event.type == uvw::fs_req::fs_type::STAT) { + req.lchown(filename, static_cast(event.stat.st_uid), static_cast(event.stat.st_gid)); + }; }); - fsReq->on>([&filename](const auto &event, auto &request) { - auto uid = static_cast(event.stat.st_uid); - auto gid = static_cast(event.stat.st_gid); - request.lchown(filename, uid, gid); + fileReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSE) { + fsReq->stat(filename); + } else if(event.type == uvw::fs_req::fs_type::OPEN) { + req.close(); + } }); - fileReq->on>([&fsReq, &filename](const auto &, auto &) { - fsReq->stat(filename); - }); - - fileReq->on>([](const auto &, auto &request) { - request.close(); - }); - - auto flags = uvw::Flags::from(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; fileReq->open(filename, flags, 0644); loop->run(); @@ -721,19 +741,20 @@ TEST(FsReq, Lchown) { TEST(FsReq, LchownSync) { const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"}; - auto loop = uvw::Loop::getDefault(); - auto fileReq = loop->resource(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fileReq = loop->resource(); + auto fsReq = loop->resource(); + auto flags = uvw::file_req::file_open_flags::CREAT | uvw::file_req::file_open_flags::RDWR | uvw::file_req::file_open_flags::TRUNC; - ASSERT_TRUE(fileReq->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)); - ASSERT_TRUE(fileReq->closeSync()); + ASSERT_TRUE(fileReq->open_sync(filename, flags, 0644)); + ASSERT_TRUE(fileReq->close_sync()); - auto statR = fsReq->statSync(filename); + auto statR = fsReq->stat_sync(filename); ASSERT_TRUE(statR.first); - auto uid = static_cast(statR.second.st_uid); - auto gid = static_cast(statR.second.st_gid); - ASSERT_TRUE(fsReq->lchownSync(filename, uid, gid)); + auto uid = static_cast(statR.second.st_uid); + auto gid = static_cast(statR.second.st_gid); + ASSERT_TRUE(fsReq->lchown_sync(filename, uid, gid)); loop->run(); } @@ -741,36 +762,34 @@ TEST(FsReq, LchownSync) { TEST(FsReq, ReadDir) { const std::string dir_name = std::string{TARGET_FS_REQ_DIR}; - auto loop = uvw::Loop::getDefault(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fsReq = loop->resource(); bool checkFsReadDirEvent = false; bool checkFsOpenDirEvent = false; bool checkFsCloseDirEvent = false; - fsReq->on([](const auto &, auto &) { FAIL(); }); + fsReq->on([](const auto &, auto &) { FAIL(); }); - fsReq->on>([&checkFsCloseDirEvent](const auto &, auto &) { - ASSERT_FALSE(checkFsCloseDirEvent); - checkFsCloseDirEvent = true; - }); - - fsReq->on>([&checkFsReadDirEvent](const auto &event, auto &hndl) { - ASSERT_FALSE(checkFsReadDirEvent); - if(!event.eos) { - hndl.readdir(); - } else { - checkFsReadDirEvent = true; - hndl.closedir(); + fsReq->on([&](const auto &event, auto &req) { + if(event.type == uvw::fs_req::fs_type::CLOSEDIR) { + ASSERT_FALSE(checkFsCloseDirEvent); + checkFsCloseDirEvent = true; + } else if(event.type == uvw::fs_req::fs_type::OPENDIR) { + ASSERT_FALSE(checkFsOpenDirEvent); + checkFsOpenDirEvent = true; + req.readdir(); + } else if(event.type == uvw::fs_req::fs_type::READDIR) { + ASSERT_FALSE(checkFsReadDirEvent); + if(!event.dirent.eos) { + req.readdir(); + } else { + checkFsReadDirEvent = true; + req.closedir(); + } } }); - fsReq->on>([&checkFsOpenDirEvent](const auto &, auto &hndl) { - ASSERT_FALSE(checkFsOpenDirEvent); - checkFsOpenDirEvent = true; - hndl.readdir(); - }); - fsReq->opendir(dir_name); loop->run(); @@ -782,15 +801,15 @@ TEST(FsReq, ReadDir) { TEST(FsReq, ReadDirSync) { const std::string dir_name = std::string{TARGET_FS_REQ_DIR}; - auto loop = uvw::Loop::getDefault(); - auto fsReq = loop->resource(); + auto loop = uvw::loop::get_default(); + auto fsReq = loop->resource(); - ASSERT_TRUE(fsReq->opendirSync(dir_name)); - auto res = fsReq->readdirSync(); + ASSERT_TRUE(fsReq->opendir_sync(dir_name)); + auto res = fsReq->readdir_sync(); while(res.first) { - res = fsReq->readdirSync(); + res = fsReq->readdir_sync(); } - ASSERT_TRUE(fsReq->closedirSync()); + ASSERT_TRUE(fsReq->closedir_sync()); loop->run(); } diff --git a/test/uvw/handle.cpp b/test/uvw/handle.cpp index 10a8df9d..73b0e1e8 100644 --- a/test/uvw/handle.cpp +++ b/test/uvw/handle.cpp @@ -6,21 +6,20 @@ struct fake_handle_t { void *data; }; -struct FakeHandle: uvw::Handle { - using Handle::Handle; +struct fake_handle: uvw::handle { + using handle::handle; - template - bool init(Args &&...) { - return initialize([](auto...) { return true; }); + int init() override { + return 1; } }; TEST(Handle, Functionalities) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - ASSERT_EQ(uvw::Utilities::guessHandle(handle->category()), uvw::HandleType::ASYNC); - ASSERT_EQ(handle->type(), uvw::HandleType::ASYNC); + ASSERT_EQ(uvw::utilities::guess_handle(handle->category()), uvw::handle_type::ASYNC); + ASSERT_EQ(handle->type(), uvw::handle_type::ASYNC); ASSERT_TRUE(handle->active()); ASSERT_FALSE(handle->closing()); @@ -38,18 +37,18 @@ TEST(Handle, Functionalities) { ASSERT_NE(handle->size(), static_castsize())>(0)); - ASSERT_EQ(handle->sendBufferSize(), static_castsendBufferSize())>(0)); - ASSERT_FALSE(handle->sendBufferSize(0)); + ASSERT_LT(handle->send_buffer_size(), 0); + ASSERT_NE(0, handle->send_buffer_size(0)); - ASSERT_EQ(handle->recvBufferSize(), static_castrecvBufferSize())>(0)); - ASSERT_FALSE(handle->recvBufferSize(0)); + ASSERT_LT(handle->recv_buffer_size(), 0); + ASSERT_NE(0, handle->recv_buffer_size(0)); ASSERT_NO_THROW(handle->fd()); } TEST(Handle, InitializationFailure) { - auto loop = uvw::Loop::getDefault(); - auto resource = loop->resource(); + auto loop = uvw::loop::get_default(); + auto resource = loop->resource(); ASSERT_FALSE(static_cast(resource)); } diff --git a/test/uvw/idle.cpp b/test/uvw/idle.cpp index 042cf027..5d51cc60 100644 --- a/test/uvw/idle.cpp +++ b/test/uvw/idle.cpp @@ -2,23 +2,26 @@ #include TEST(Idle, StartAndStop) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); bool checkIdleEvent = false; - handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); - handle->on([&checkIdleEvent](const auto &, auto &hndl) { + handle->on([&checkIdleEvent](const auto &, auto &hndl) { ASSERT_FALSE(checkIdleEvent); + checkIdleEvent = true; - hndl.stop(); + + ASSERT_EQ(0, hndl.stop()); + hndl.close(); + ASSERT_TRUE(hndl.closing()); }); - handle->start(); - + ASSERT_EQ(0, handle->start()); ASSERT_TRUE(handle->active()); ASSERT_FALSE(handle->closing()); @@ -28,11 +31,11 @@ TEST(Idle, StartAndStop) { } TEST(Idle, Fake) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - handle->on([](auto &&...) { FAIL(); }); - handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); handle->start(); handle->close(); diff --git a/test/uvw/lib.cpp b/test/uvw/lib.cpp index d7d82ac4..2ef513d3 100644 --- a/test/uvw/lib.cpp +++ b/test/uvw/lib.cpp @@ -2,23 +2,23 @@ #include TEST(SharedLib, Failure) { - auto loop = uvw::Loop::getDefault(); - auto lib = loop->resource("foobar.so"); + auto loop = uvw::loop::get_default(); + auto lib = loop->resource("foobar.so"); ASSERT_FALSE(static_cast(*lib)); ASSERT_NE(lib->error(), nullptr); - ASSERT_EQ(&lib->loop(), loop.get()); + ASSERT_EQ(&lib->parent(), loop.get()); // this forces a call to the destructor to invoke uv_dlclose lib.reset(); } TEST(SharedLib, Success) { - auto loop = uvw::Loop::getDefault(); - auto lib = loop->resource(TARGET_LIB_SO); + auto loop = uvw::loop::get_default(); + auto lib = loop->resource(TARGET_LIB_SO); ASSERT_TRUE(static_cast(*lib)); - ASSERT_EQ(&lib->loop(), loop.get()); + ASSERT_EQ(&lib->parent(), loop.get()); ASSERT_EQ(lib->sym("foobar"), nullptr); ASSERT_NE(lib->sym("fake_func"), nullptr); double d{1.}; diff --git a/test/uvw/loop.cpp b/test/uvw/loop.cpp index da4f060d..142c9529 100644 --- a/test/uvw/loop.cpp +++ b/test/uvw/loop.cpp @@ -1,29 +1,28 @@ #include -#include -#include -#include +#include TEST(Loop, DefaultLoop) { - auto def = uvw::Loop::getDefault(); + auto def = uvw::loop::get_default(); ASSERT_TRUE(static_cast(def)); ASSERT_FALSE(def->alive()); ASSERT_NO_THROW(def->stop()); def->walk([](auto &) { FAIL(); }); + auto def2 = uvw::loop::get_default(); - auto def2 = uvw::Loop::getDefault(); ASSERT_EQ(def, def2); + ASSERT_EQ(0, def->close()); } TEST(Loop, Functionalities) { - auto loop = uvw::Loop::create(); - auto handle = loop->resource(); - auto req = loop->resource([] {}); + auto loop = uvw::loop::create(); + auto handle = loop->resource(); + auto req = loop->resource([] {}); - loop->on([](auto &&...) { FAIL(); }); - req->on([](auto &&...) { FAIL(); }); - handle->on([](auto &&...) { FAIL(); }); + loop->on([](auto &&...) { FAIL(); }); + req->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); ASSERT_TRUE(static_cast(handle)); ASSERT_TRUE(static_cast(req)); @@ -34,15 +33,15 @@ TEST(Loop, Functionalities) { #ifndef _MSC_VER // fork isn't implemented on Windows in libuv and it returns an error by default - ASSERT_NO_THROW(loop->fork()); + ASSERT_EQ(0, loop->fork()); #endif ASSERT_FALSE(loop->alive()); ASSERT_FALSE(loop->timeout().first); handle->start(); - handle->on([](const auto &, auto &hndl) { - hndl.loop().walk([](auto &) { + handle->on([](const auto &, auto &hndl) { + hndl.parent().walk([](auto &) { static bool trigger = true; ASSERT_TRUE(trigger); trigger = false; @@ -52,18 +51,52 @@ TEST(Loop, Functionalities) { }); ASSERT_TRUE(loop->alive()); - ASSERT_NO_THROW(loop->run()); + ASSERT_EQ(0, loop->run()); loop->walk([](auto &) { FAIL(); }); - ASSERT_NO_THROW(loop->run()); - ASSERT_NO_THROW(loop->run()); + ASSERT_EQ(0, loop->run(uvw::loop::run_mode::ONCE)); + ASSERT_EQ(0, loop->run(uvw::loop::run_mode::NOWAIT)); ASSERT_FALSE(loop->alive()); + ASSERT_EQ(0, loop->close()); +} + +TEST(Loop, Walk) { + auto loop = uvw::loop::create(); + + loop->resource(); + loop->resource(); + loop->resource(); + loop->resource(); + loop->resource(); + loop->resource(); + loop->resource(); + loop->resource(); + loop->resource(); + loop->resource(); + loop->resource(0, true); + loop->resource(); + + std::size_t count{}; + + loop->walk([&count](auto &handle) { + ++count; + handle.close(); + }); + + ASSERT_EQ(count, 12u); + + loop->run(); + loop->walk([&count](auto &handle) { --count; }); + + ASSERT_EQ(count, 12u); + + ASSERT_EQ(0, loop->close()); } TEST(Loop, UserData) { - auto loop = uvw::Loop::create(); + auto loop = uvw::loop::create(); loop->data(std::make_shared(42)); ASSERT_EQ(*std::static_pointer_cast(loop->data()), 42); @@ -73,26 +106,32 @@ TEST(Loop, UserData) { ASSERT_EQ(*std::static_pointer_cast(loop->data()), 42); ASSERT_EQ(*loop->data(), 42); + + ASSERT_EQ(0, loop->close()); } TEST(Loop, Configure) { - auto loop = uvw::Loop::create(); - ASSERT_NO_THROW(loop->configure(uvw::Loop::Configure::BLOCK_SIGNAL, 9)); - ASSERT_NO_THROW(loop->run()); + auto loop = uvw::loop::create(); + ASSERT_EQ(0, loop->configure(uvw::loop::option::IDLE_TIME)); + ASSERT_EQ(0, loop->run()); + ASSERT_EQ(0, loop->close()); } TEST(Loop, IdleTime) { - auto loop = uvw::Loop::create(); - loop->configure(uvw::Loop::Configure::IDLE_TIME); - ASSERT_EQ(loop->idleTime().count(), 0u); + auto loop = uvw::loop::create(); + loop->configure(uvw::loop::option::IDLE_TIME); + ASSERT_EQ(loop->idle_time().count(), 0u); + ASSERT_EQ(0, loop->close()); } TEST(Loop, Raw) { - auto loop = uvw::Loop::getDefault(); - const auto &cloop = uvw::Loop::getDefault(); + auto loop = uvw::loop::get_default(); + const auto &cloop = uvw::loop::get_default(); auto *raw = loop->raw(); auto *craw = cloop->raw(); ASSERT_EQ(raw, craw); + + ASSERT_EQ(0, loop->close()); } diff --git a/test/uvw/pipe.cpp b/test/uvw/pipe.cpp index 2c080d2c..341e50d3 100644 --- a/test/uvw/pipe.cpp +++ b/test/uvw/pipe.cpp @@ -8,31 +8,29 @@ TEST(Pipe, ReadWrite) { const std::string sockname = std::string{TARGET_PIPE_DIR} + std::string{"/test.sock"}; #endif - auto loop = uvw::Loop::getDefault(); - auto server = loop->resource(); - auto client = loop->resource(); + auto loop = uvw::loop::get_default(); + auto server = loop->resource(); + auto client = loop->resource(); - server->on([](const auto &, auto &) { FAIL(); }); - client->on([](const auto &, auto &) { - FAIL(); + server->on([](const auto &, auto &) { FAIL(); }); + client->on([](const auto &, auto &) { FAIL(); }); + + server->on([](const uvw::listen_event &, uvw::pipe_handle &handle) { + std::shared_ptr socket = handle.parent().resource(); + + socket->on([](const uvw::error_event &, uvw::pipe_handle &) { FAIL(); }); + socket->on([&handle](const uvw::close_event &, uvw::pipe_handle &) { handle.close(); }); + socket->on([](const uvw::end_event &, uvw::pipe_handle &sock) { sock.close(); }); + + ASSERT_EQ(0, handle.accept(*socket)); + ASSERT_EQ(0, socket->read()); }); - server->once([](const uvw::ListenEvent &, uvw::PipeHandle &handle) { - std::shared_ptr socket = handle.loop().resource(); - - socket->on([](const uvw::ErrorEvent &, uvw::PipeHandle &) { FAIL(); }); - socket->on([&handle](const uvw::CloseEvent &, uvw::PipeHandle &) { handle.close(); }); - socket->on([](const uvw::EndEvent &, uvw::PipeHandle &sock) { sock.close(); }); - - handle.accept(*socket); - socket->read(); - }); - - client->once([](const uvw::WriteEvent &, uvw::PipeHandle &handle) { + client->on([](const uvw::write_event &, uvw::pipe_handle &handle) { handle.close(); }); - client->once([](const uvw::ConnectEvent &, uvw::PipeHandle &handle) { + client->on([](const uvw::connect_event &, uvw::pipe_handle &handle) { ASSERT_TRUE(handle.writable()); ASSERT_TRUE(handle.readable()); @@ -41,8 +39,9 @@ TEST(Pipe, ReadWrite) { }); server->bind(sockname); - server->listen(); - client->connect(sockname); + + ASSERT_EQ(0, server->listen()); + ASSERT_EQ(0, client->connect(sockname)); loop->run(); } @@ -56,35 +55,35 @@ TEST(Pipe, SockPeer) { const auto peername = sockname; #endif - auto loop = uvw::Loop::getDefault(); - auto server = loop->resource(); - auto client = loop->resource(); + auto loop = uvw::loop::get_default(); + auto server = loop->resource(); + auto client = loop->resource(); - server->on([](const auto &, auto &) { FAIL(); }); - client->on([](const auto &, auto &) { FAIL(); }); + server->on([](const auto &, auto &) { FAIL(); }); + client->on([](const auto &, auto &) { FAIL(); }); - server->once([&peername](const uvw::ListenEvent &, uvw::PipeHandle &handle) { - std::shared_ptr socket = handle.loop().resource(); + server->on([&peername](const uvw::listen_event &, uvw::pipe_handle &handle) { + std::shared_ptr socket = handle.parent().resource(); - socket->on([](const uvw::ErrorEvent &, uvw::PipeHandle &) { FAIL(); }); - socket->on([&handle](const uvw::CloseEvent &, uvw::PipeHandle &) { handle.close(); }); - socket->on([](const uvw::EndEvent &, uvw::PipeHandle &sock) { sock.close(); }); - - handle.accept(*socket); - socket->read(); + socket->on([](const uvw::error_event &, uvw::pipe_handle &) { FAIL(); }); + socket->on([&handle](const uvw::close_event &, uvw::pipe_handle &) { handle.close(); }); + socket->on([](const uvw::end_event &, uvw::pipe_handle &sock) { sock.close(); }); + ASSERT_EQ(0, handle.accept(*socket)); + ASSERT_EQ(0, socket->read()); ASSERT_EQ(handle.sock(), peername); }); - client->once([&peername](const uvw::ConnectEvent &, uvw::PipeHandle &handle) { + client->on([&peername](const uvw::connect_event &, uvw::pipe_handle &handle) { ASSERT_EQ(handle.peer(), peername); handle.close(); }); server->bind(sockname); - server->listen(); - client->connect(sockname); + + ASSERT_EQ(0, server->listen()); + ASSERT_EQ(0, client->connect(sockname)); loop->run(); } @@ -98,36 +97,38 @@ TEST(Pipe, Shutdown) { auto data = std::unique_ptr(new char[3]{'a', 'b', 'c'}); - auto loop = uvw::Loop::getDefault(); - auto server = loop->resource(); - auto client = loop->resource(); + auto loop = uvw::loop::get_default(); + auto server = loop->resource(); + auto client = loop->resource(); - server->on([](const auto &, auto &) { FAIL(); }); - client->on([](const auto &, auto &) { FAIL(); }); + server->on([](const auto &, auto &) { FAIL(); }); + client->on([](const auto &, auto &) { FAIL(); }); - server->once([](const uvw::ListenEvent &, uvw::PipeHandle &handle) { - std::shared_ptr socket = handle.loop().resource(); + server->on([](const uvw::listen_event &, uvw::pipe_handle &handle) { + std::shared_ptr socket = handle.parent().resource(); - socket->on([](const uvw::ErrorEvent &, uvw::PipeHandle &) { FAIL(); }); - socket->on([&handle](const uvw::CloseEvent &, uvw::PipeHandle &) { handle.close(); }); - socket->on([](const uvw::EndEvent &, uvw::PipeHandle &sock) { sock.close(); }); + socket->on([](const uvw::error_event &, uvw::pipe_handle &) { FAIL(); }); + socket->on([&handle](const uvw::close_event &, uvw::pipe_handle &) { handle.close(); }); + socket->on([](const uvw::end_event &, uvw::pipe_handle &sock) { sock.close(); }); - handle.accept(*socket); - socket->read(); + ASSERT_EQ(0, handle.accept(*socket)); + ASSERT_EQ(0, socket->read()); }); - client->once([](const uvw::ShutdownEvent &, uvw::PipeHandle &handle) { + client->on([](const uvw::shutdown_event &, uvw::pipe_handle &handle) { handle.close(); }); - client->once([&data](const uvw::ConnectEvent &, uvw::PipeHandle &handle) { + client->on([&data](const uvw::connect_event &, uvw::pipe_handle &handle) { handle.write(data.get(), 3); - handle.shutdown(); + + ASSERT_EQ(0, handle.shutdown()); }); server->bind(sockname); - server->listen(); - client->connect(sockname); + + ASSERT_EQ(0, server->listen()); + ASSERT_EQ(0, client->connect(sockname)); loop->run(); } diff --git a/test/uvw/prepare.cpp b/test/uvw/prepare.cpp index 25eb91f4..b66920bd 100644 --- a/test/uvw/prepare.cpp +++ b/test/uvw/prepare.cpp @@ -2,23 +2,26 @@ #include TEST(Prepare, StartAndStop) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); bool checkPrepareEvent = false; - handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); - handle->on([&checkPrepareEvent](const auto &, auto &hndl) { + handle->on([&checkPrepareEvent](const auto &, auto &hndl) { ASSERT_FALSE(checkPrepareEvent); + checkPrepareEvent = true; - hndl.stop(); + + ASSERT_EQ(0, hndl.stop()); + hndl.close(); + ASSERT_TRUE(hndl.closing()); }); - handle->start(); - + ASSERT_EQ(0, handle->start()); ASSERT_TRUE(handle->active()); ASSERT_FALSE(handle->closing()); @@ -28,11 +31,11 @@ TEST(Prepare, StartAndStop) { } TEST(Prepare, Fake) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - handle->on([](auto &&...) { FAIL(); }); - handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); handle->start(); handle->close(); diff --git a/test/uvw/process.cpp b/test/uvw/process.cpp index 46cba492..9aaf3379 100644 --- a/test/uvw/process.cpp +++ b/test/uvw/process.cpp @@ -3,8 +3,8 @@ #include TEST(Process, Pid) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); ASSERT_EQ(handle->pid(), 0); @@ -12,8 +12,8 @@ TEST(Process, Pid) { } TEST(Process, Cwd) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); handle->cwd("."); @@ -21,15 +21,15 @@ TEST(Process, Cwd) { } TEST(Process, StdIO) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); - auto pipe = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); + auto pipe = loop->resource(); - uvw::ProcessHandle::disableStdIOInheritance(); - handle->stdio(*pipe, uvw::Flags::from()); - handle->stdio(uvw::StdIN, uvw::ProcessHandle::StdIO::IGNORE_STREAM); - handle->stdio(uvw::StdOUT, uvw::ProcessHandle::StdIO::IGNORE_STREAM); - handle->stdio(uvw::StdOUT, uvw::ProcessHandle::StdIO::INHERIT_FD); + uvw::process_handle::disable_stdio_inheritance(); + handle->stdio(*pipe, uvw::process_handle::stdio_flags::CREATE_PIPE | uvw::process_handle::stdio_flags::READABLE_PIPE); + handle->stdio(uvw::std_in, uvw::process_handle::stdio_flags::IGNORE_STREAM); + handle->stdio(uvw::std_out, uvw::process_handle::stdio_flags::IGNORE_STREAM); + handle->stdio(uvw::std_out, uvw::process_handle::stdio_flags::INHERIT_FD); pipe->close(); loop->run(); diff --git a/test/uvw/request.cpp b/test/uvw/request.cpp index bd25429b..715e5afa 100644 --- a/test/uvw/request.cpp +++ b/test/uvw/request.cpp @@ -3,11 +3,11 @@ #include TEST(Request, Functionalities) { - auto loop = uvw::Loop::getDefault(); - auto req = loop->resource([]() {}); + auto loop = uvw::loop::get_default(); + auto req = loop->resource([]() {}); ASSERT_NE(req->size(), decltype(req->size()){0}); - ASSERT_FALSE(req->cancel()); + ASSERT_LT(req->cancel(), 0); loop->run(); } diff --git a/test/uvw/resource.cpp b/test/uvw/resource.cpp index c2111b73..28b4828f 100644 --- a/test/uvw/resource.cpp +++ b/test/uvw/resource.cpp @@ -4,19 +4,17 @@ #include #include -struct Res: uvw::Resource {}; - TEST(Resource, Functionalities) { - ASSERT_FALSE(std::is_copy_constructible::value); - ASSERT_FALSE(std::is_copy_assignable::value); + ASSERT_FALSE(std::is_copy_constructible::value); + ASSERT_FALSE(std::is_copy_assignable::value); - ASSERT_FALSE(std::is_move_constructible::value); - ASSERT_FALSE(std::is_move_assignable::value); + ASSERT_FALSE(std::is_move_constructible::value); + ASSERT_FALSE(std::is_move_assignable::value); - auto loop = uvw::Loop::getDefault(); - auto resource = loop->resource(); + auto loop = uvw::loop::get_default(); + auto resource = loop->resource(); - ASSERT_EQ(&resource->loop(), loop.get()); + ASSERT_EQ(&resource->parent(), loop.get()); resource->data(std::make_shared(42)); diff --git a/test/uvw/signal.cpp b/test/uvw/signal.cpp index 60e45a73..1a64e8e5 100644 --- a/test/uvw/signal.cpp +++ b/test/uvw/signal.cpp @@ -3,17 +3,15 @@ #include TEST(Signal, Start) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - handle->on([](auto &&...) { FAIL(); }); - handle->on([](auto &&...) { FAIL(); }); - - handle->start(2); + handle->on([](auto &&...) { FAIL(); }); + ASSERT_EQ(0, handle->start(2)); ASSERT_EQ(2, handle->signal()); + ASSERT_EQ(0, handle->stop()); - handle->stop(); handle->close(); ASSERT_FALSE(handle->active()); @@ -23,17 +21,15 @@ TEST(Signal, Start) { } TEST(Signal, OneShot) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - handle->on([](auto &&...) { FAIL(); }); - handle->on([](auto &&...) { FAIL(); }); - - handle->oneShot(2); + handle->on([](auto &&...) { FAIL(); }); + ASSERT_EQ(0, handle->one_shot(2)); ASSERT_EQ(2, handle->signal()); + ASSERT_EQ(0, handle->stop()); - handle->stop(); handle->close(); ASSERT_FALSE(handle->active()); diff --git a/test/uvw/stream.cpp b/test/uvw/stream.cpp index c7c9fb10..613fbc7d 100644 --- a/test/uvw/stream.cpp +++ b/test/uvw/stream.cpp @@ -5,11 +5,11 @@ struct fake_stream_t { void *data; }; -struct FakeStreamHandle: uvw::StreamHandle { - using StreamHandle::StreamHandle; +struct fake_stream_handle: uvw::stream_handle { + using stream_handle::stream_handle; template - bool init(Args &&...) { - return true; + int init(Args &&...) { + return 0; } }; diff --git a/test/uvw/tcp.cpp b/test/uvw/tcp.cpp index de5dcf8b..6c435831 100644 --- a/test/uvw/tcp.cpp +++ b/test/uvw/tcp.cpp @@ -2,12 +2,12 @@ #include TEST(TCP, Functionalities) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - ASSERT_TRUE(handle->noDelay(true)); - ASSERT_TRUE(handle->keepAlive(true, uvw::TCPHandle::Time{128})); - ASSERT_TRUE(handle->simultaneousAccepts()); + ASSERT_TRUE(handle->no_delay(true)); + ASSERT_TRUE(handle->keep_alive(true, uvw::tcp_handle::time{128})); + ASSERT_TRUE(handle->simultaneous_accepts()); handle->close(); loop->run(); @@ -17,41 +17,43 @@ TEST(TCP, ReadWrite) { const std::string address = std::string{"127.0.0.1"}; const unsigned int port = 4242; - auto loop = uvw::Loop::getDefault(); - auto server = loop->resource(); - auto client = loop->resource(); + auto loop = uvw::loop::get_default(); + auto server = loop->resource(); + auto client = loop->resource(); - server->on([](const auto &, auto &) { FAIL(); }); - client->on([](const auto &, auto &) { FAIL(); }); + server->on([](const auto &, auto &) { FAIL(); }); + client->on([](const auto &, auto &) { FAIL(); }); - server->once([](const uvw::ListenEvent &, uvw::TCPHandle &handle) { - std::shared_ptr socket = handle.loop().resource(); + server->on([](const uvw::listen_event &, uvw::tcp_handle &handle) { + std::shared_ptr socket = handle.parent().resource(); - socket->on([](const uvw::ErrorEvent &, uvw::TCPHandle &) { FAIL(); }); - socket->on([&handle](const uvw::CloseEvent &, uvw::TCPHandle &) { handle.close(); }); - socket->on([](const uvw::EndEvent &, uvw::TCPHandle &sock) { sock.close(); }); + socket->on([](const uvw::error_event &, uvw::tcp_handle &) { FAIL(); }); + socket->on([&handle](const uvw::close_event &, uvw::tcp_handle &) { handle.close(); }); + socket->on([](const uvw::end_event &, uvw::tcp_handle &sock) { sock.close(); }); - handle.accept(*socket); - socket->read(); + ASSERT_EQ(0, handle.accept(*socket)); + ASSERT_EQ(0, socket->read()); }); - client->once([](const uvw::WriteEvent &, uvw::TCPHandle &handle) { + client->on([](const uvw::write_event &, uvw::tcp_handle &handle) { handle.close(); }); - client->once([](const uvw::ConnectEvent &, uvw::TCPHandle &handle) { + client->on([](const uvw::connect_event &, uvw::tcp_handle &handle) { ASSERT_TRUE(handle.writable()); ASSERT_TRUE(handle.readable()); auto dataTryWrite = std::unique_ptr(new char[1]{'a'}); - handle.tryWrite(std::move(dataTryWrite), 1); + + ASSERT_EQ(1, handle.try_write(std::move(dataTryWrite), 1)); + auto dataWrite = std::unique_ptr(new char[2]{'b', 'c'}); handle.write(std::move(dataWrite), 2); }); - server->bind(address, port); - server->listen(); - client->connect(address, port); + ASSERT_EQ(0, (server->bind(address, port))); + ASSERT_EQ(0, server->listen()); + ASSERT_EQ(0, (client->connect(address, port))); loop->run(); } @@ -60,39 +62,39 @@ TEST(TCP, SockPeer) { const std::string address = std::string{"127.0.0.1"}; const unsigned int port = 4242; - auto loop = uvw::Loop::getDefault(); - auto server = loop->resource(); - auto client = loop->resource(); + auto loop = uvw::loop::get_default(); + auto server = loop->resource(); + auto client = loop->resource(); - server->on([](const auto &, auto &) { FAIL(); }); - client->on([](const auto &, auto &) { FAIL(); }); + server->on([](const auto &, auto &) { FAIL(); }); + client->on([](const auto &, auto &) { FAIL(); }); - server->once([&address](const uvw::ListenEvent &, uvw::TCPHandle &handle) { - std::shared_ptr socket = handle.loop().resource(); + server->on([&address](const uvw::listen_event &, uvw::tcp_handle &handle) { + std::shared_ptr socket = handle.parent().resource(); - socket->on([](const uvw::ErrorEvent &, uvw::TCPHandle &) { FAIL(); }); - socket->on([&handle](const uvw::CloseEvent &, uvw::TCPHandle &) { handle.close(); }); - socket->on([](const uvw::EndEvent &, uvw::TCPHandle &sock) { sock.close(); }); + socket->on([](const uvw::error_event &, uvw::tcp_handle &) { FAIL(); }); + socket->on([&handle](const uvw::close_event &, uvw::tcp_handle &) { handle.close(); }); + socket->on([](const uvw::end_event &, uvw::tcp_handle &sock) { sock.close(); }); - handle.accept(*socket); - socket->read(); + ASSERT_EQ(0, handle.accept(*socket)); + ASSERT_EQ(0, socket->read()); - uvw::Addr addr = handle.sock(); + uvw::socket_address addr = handle.sock(); ASSERT_EQ(addr.ip, address); }); - client->once([&address](const uvw::ConnectEvent &, uvw::TCPHandle &handle) { - uvw::Addr addr = handle.peer(); + client->on([&address](const uvw::connect_event &, uvw::tcp_handle &handle) { + uvw::socket_address addr = handle.peer(); ASSERT_EQ(addr.ip, address); handle.close(); }); - server->bind(uvw::Addr{address, port}); - server->listen(); - client->connect(uvw::Addr{address, port}); + ASSERT_EQ(0, (server->bind(uvw::socket_address{address, port}))); + ASSERT_EQ(0, server->listen()); + ASSERT_EQ(0, (client->connect(uvw::socket_address{address, port}))); loop->run(); } @@ -101,62 +103,48 @@ TEST(TCP, Shutdown) { const std::string address = std::string{"127.0.0.1"}; const unsigned int port = 4242; - auto loop = uvw::Loop::getDefault(); - auto server = loop->resource(); - auto client = loop->resource(); + auto loop = uvw::loop::get_default(); + auto server = loop->resource(); + auto client = loop->resource(); - server->on([](const auto &, auto &) { FAIL(); }); - client->on([](const auto &, auto &) { FAIL(); }); + server->on([](const auto &, auto &) { FAIL(); }); + client->on([](const auto &, auto &) { FAIL(); }); - server->once([](const uvw::ListenEvent &, uvw::TCPHandle &handle) { - std::shared_ptr socket = handle.loop().resource(); + server->on([](const uvw::listen_event &, uvw::tcp_handle &handle) { + std::shared_ptr socket = handle.parent().resource(); - socket->on([](const uvw::ErrorEvent &, uvw::TCPHandle &) { FAIL(); }); - socket->on([&handle](const uvw::CloseEvent &, uvw::TCPHandle &) { handle.close(); }); - socket->on([](const uvw::EndEvent &, uvw::TCPHandle &sock) { sock.close(); }); + socket->on([](const uvw::error_event &, uvw::tcp_handle &) { FAIL(); }); + socket->on([&handle](const uvw::close_event &, uvw::tcp_handle &) { handle.close(); }); + socket->on([](const uvw::end_event &, uvw::tcp_handle &sock) { sock.close(); }); - handle.accept(*socket); - socket->read(); + ASSERT_EQ(0, handle.accept(*socket)); + ASSERT_EQ(0, socket->read()); }); - client->once([](const uvw::ShutdownEvent &, uvw::TCPHandle &handle) { + client->on([](const uvw::shutdown_event &, uvw::tcp_handle &handle) { handle.close(); }); - client->once([](const uvw::ConnectEvent &, uvw::TCPHandle &handle) { - handle.shutdown(); + client->on([](const uvw::connect_event &, uvw::tcp_handle &handle) { + ASSERT_EQ(0, handle.shutdown()); }); - server->bind(address, port); - server->listen(); - client->connect(address, port); + ASSERT_EQ(0, (server->bind(address, port))); + ASSERT_EQ(0, server->listen()); + ASSERT_EQ(0, (client->connect(address, port))); loop->run(); } TEST(TCP, WriteError) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); - - bool checkWriteSmartPtrErrorEvent = false; - bool checkWriteNakedPtrErrorEvent = false; - bool checkTryWriteSmartPtrErrorEvent = false; - bool checkTryWriteNakedPtrErrorEvent = false; + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); handle->close(); - handle->once([&checkWriteSmartPtrErrorEvent](const auto &, auto &) { checkWriteSmartPtrErrorEvent = true; }); - handle->write(std::unique_ptr{}, 0); - handle->once([&checkWriteNakedPtrErrorEvent](const auto &, auto &) { checkWriteNakedPtrErrorEvent = true; }); - handle->write(nullptr, 0); - handle->once([&checkTryWriteSmartPtrErrorEvent](const auto &, auto &) { checkTryWriteSmartPtrErrorEvent = true; }); - handle->tryWrite(std::unique_ptr{}, 0); - handle->once([&checkTryWriteNakedPtrErrorEvent](const auto &, auto &) { checkTryWriteNakedPtrErrorEvent = true; }); - handle->tryWrite(nullptr, 0); - loop->run(); + ASSERT_NE(0, (handle->write(std::unique_ptr{}, 0))); + ASSERT_NE(0, (handle->write(nullptr, 0))); - ASSERT_TRUE(checkWriteSmartPtrErrorEvent); - ASSERT_TRUE(checkWriteNakedPtrErrorEvent); - ASSERT_TRUE(checkTryWriteSmartPtrErrorEvent); - ASSERT_TRUE(checkTryWriteNakedPtrErrorEvent); + ASSERT_LT(handle->try_write(std::unique_ptr{}, 0), 0); + ASSERT_LT(handle->try_write(nullptr, 0), 0); } diff --git a/test/uvw/thread.cpp b/test/uvw/thread.cpp index fe34ff09..6960bd88 100644 --- a/test/uvw/thread.cpp +++ b/test/uvw/thread.cpp @@ -2,7 +2,7 @@ #include TEST(Thread, Run) { - auto loop = uvw::Loop::getDefault(); + auto loop = uvw::loop::get_default(); auto has_run = std::make_shared(); auto cb = [](std::shared_ptr data) { if(auto has_run = std::static_pointer_cast(data); has_run) { @@ -10,7 +10,7 @@ TEST(Thread, Run) { } }; - auto handle = loop->resource(cb, has_run); + auto handle = loop->resource(cb, has_run); ASSERT_TRUE(handle->run()); ASSERT_TRUE(handle->join()); @@ -20,8 +20,8 @@ TEST(Thread, Run) { } TEST(ThreadLocalStorage, SetGet) { - auto loop = uvw::Loop::getDefault(); - auto localStorage = loop->resource(); + auto loop = uvw::loop::get_default(); + auto localStorage = loop->resource(); auto flag{true}; localStorage->set(&flag); @@ -31,26 +31,26 @@ TEST(ThreadLocalStorage, SetGet) { } TEST(Mutex, LockUnlock) { - auto loop = uvw::Loop::getDefault(); - auto mtx = loop->resource(); + auto loop = uvw::loop::get_default(); + auto mtx = loop->resource(); mtx->lock(); #ifdef _MSC_VER // this is allowed by libuv on Windows - ASSERT_TRUE(mtx->tryLock()); + ASSERT_TRUE(mtx->try_lock()); #else - ASSERT_FALSE(mtx->tryLock()); + ASSERT_FALSE(mtx->try_lock()); #endif mtx->unlock(); - ASSERT_TRUE(mtx->tryLock()); + ASSERT_TRUE(mtx->try_lock()); #ifdef _MSC_VER // this is allowed by libuv on Windows - ASSERT_TRUE(mtx->tryLock()); + ASSERT_TRUE(mtx->try_lock()); #else - ASSERT_FALSE(mtx->tryLock()); + ASSERT_FALSE(mtx->try_lock()); #endif mtx->unlock(); @@ -59,14 +59,14 @@ TEST(Mutex, LockUnlock) { } TEST(Mutex, RecursiveLockUnlock) { - auto loop = uvw::Loop::getDefault(); - auto recursive_mtx = loop->resource(true); + auto loop = uvw::loop::get_default(); + auto recursive_mtx = loop->resource(true); recursive_mtx->lock(); recursive_mtx->unlock(); recursive_mtx->lock(); - ASSERT_TRUE(recursive_mtx->tryLock()); + ASSERT_TRUE(recursive_mtx->try_lock()); recursive_mtx->unlock(); recursive_mtx->unlock(); diff --git a/test/uvw/timer.cpp b/test/uvw/timer.cpp index 55b3be1f..0ab1c4ff 100644 --- a/test/uvw/timer.cpp +++ b/test/uvw/timer.cpp @@ -2,28 +2,34 @@ #include TEST(Timer, StartAndStop) { - auto loop = uvw::Loop::getDefault(); - auto handleNoRepeat = loop->resource(); - auto handleRepeat = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handleNoRepeat = loop->resource(); + auto handleRepeat = loop->resource(); bool checkTimerNoRepeatEvent = false; bool checkTimerRepeatEvent = false; - handleNoRepeat->on([](auto &&...) { FAIL(); }); - handleRepeat->on([](auto &&...) { FAIL(); }); + handleNoRepeat->on([](auto &&...) { FAIL(); }); + handleRepeat->on([](auto &&...) { FAIL(); }); - handleNoRepeat->on([&checkTimerNoRepeatEvent](const auto &, auto &handle) { + handleNoRepeat->on([&checkTimerNoRepeatEvent](const auto &, auto &handle) { ASSERT_FALSE(checkTimerNoRepeatEvent); + checkTimerNoRepeatEvent = true; - handle.stop(); + + ASSERT_EQ(0, handle.stop()); + handle.close(); + ASSERT_TRUE(handle.closing()); }); - handleRepeat->on([&checkTimerRepeatEvent](const auto &, auto &handle) { + handleRepeat->on([&checkTimerRepeatEvent](const auto &, auto &handle) { if(checkTimerRepeatEvent) { - handle.stop(); + ASSERT_EQ(0, handle.stop()); + handle.close(); + ASSERT_TRUE(handle.closing()); } else { checkTimerRepeatEvent = true; @@ -31,8 +37,8 @@ TEST(Timer, StartAndStop) { } }); - handleNoRepeat->start(uvw::TimerHandle::Time{0}, uvw::TimerHandle::Time{0}); - handleRepeat->start(uvw::TimerHandle::Time{0}, uvw::TimerHandle::Time{1}); + ASSERT_EQ(0, handleNoRepeat->start(uvw::timer_handle::time{0}, uvw::timer_handle::time{0})); + ASSERT_EQ(0, handleRepeat->start(uvw::timer_handle::time{0}, uvw::timer_handle::time{1})); ASSERT_TRUE(handleNoRepeat->active()); ASSERT_FALSE(handleNoRepeat->closing()); @@ -47,18 +53,14 @@ TEST(Timer, StartAndStop) { } TEST(Timer, Again) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - bool checkErrorEvent = false; bool checkTimerEvent = false; - handle->on([&checkErrorEvent](const auto &, auto &) { - ASSERT_FALSE(checkErrorEvent); - checkErrorEvent = true; - }); + handle->on([](const auto &, auto &) { FAIL(); }); - handle->on([&checkTimerEvent](const auto &, auto &hndl) { + handle->on([&checkTimerEvent](const auto &, auto &hndl) { static bool guard = false; if(guard) { @@ -68,34 +70,38 @@ TEST(Timer, Again) { ASSERT_TRUE(hndl.closing()); } else { guard = true; - hndl.again(); - ASSERT_EQ(hndl.repeat(), uvw::TimerHandle::Time{1}); + ASSERT_EQ(0, hndl.again()); + ASSERT_EQ(hndl.repeat(), uvw::timer_handle::time{1}); ASSERT_FALSE(hndl.closing()); } }); - ASSERT_NO_THROW(handle->again()); + ASSERT_NE(0, handle->again()); ASSERT_FALSE(handle->active()); - ASSERT_TRUE(checkErrorEvent); - checkErrorEvent = false; - handle->start(uvw::TimerHandle::Time{0}, uvw::TimerHandle::Time{1}); + handle->start(uvw::timer_handle::time{0}, uvw::timer_handle::time{1}); ASSERT_TRUE(handle->active()); ASSERT_FALSE(handle->closing()); loop->run(); - ASSERT_FALSE(checkErrorEvent); ASSERT_TRUE(checkTimerEvent); + + handle->close(); + + ASSERT_FALSE(handle->active()); + ASSERT_TRUE(handle->closing()); + + ASSERT_NE(0, handle->start(uvw::timer_handle::time{0}, uvw::timer_handle::time{1})); } TEST(Timer, Repeat) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - ASSERT_NO_THROW(handle->repeat(uvw::TimerHandle::Time{42})); - ASSERT_EQ(handle->repeat(), uvw::TimerHandle::Time{42}); + ASSERT_NO_THROW(handle->repeat(uvw::timer_handle::time{42})); + ASSERT_EQ(handle->repeat(), uvw::timer_handle::time{42}); ASSERT_NO_THROW(handle->close()); // this forces an internal call to the close callback @@ -104,13 +110,13 @@ TEST(Timer, Repeat) { } TEST(Timer, Fake) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - handle->on([](auto &&...) { FAIL(); }); - handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); + handle->on([](auto &&...) { FAIL(); }); - handle->start(uvw::TimerHandle::Time{0}, uvw::TimerHandle::Time{0}); + handle->start(uvw::timer_handle::time{0}, uvw::timer_handle::time{0}); handle->close(); ASSERT_FALSE(handle->active()); @@ -120,15 +126,13 @@ TEST(Timer, Fake) { } TEST(Timer, BaseHandleWalk) { - auto loop = uvw::Loop::getDefault(); - auto timer = loop->resource(); + auto loop = uvw::loop::get_default(); + auto timer = loop->resource(); - timer->on([](const auto &, uvw::TimerHandle &handle) { - handle.loop().walk(uvw::Overloaded{ - [](uvw::TimerHandle &h) { h.close(); }, - [](auto &&) {}}); + timer->on([](const auto &, uvw::timer_handle &handle) { + handle.parent().walk(uvw::overloaded{[](uvw::timer_handle &h) { h.close(); }, [](auto &&) {}}); }); - timer->start(uvw::TimerHandle::Time{100}, uvw::TimerHandle::Time{100}); + timer->start(uvw::timer_handle::time{100}, uvw::timer_handle::time{100}); loop->run(); } diff --git a/test/uvw/tty.cpp b/test/uvw/tty.cpp index 6cba5518..fb7ec357 100644 --- a/test/uvw/tty.cpp +++ b/test/uvw/tty.cpp @@ -3,29 +3,31 @@ #include TEST(TTY, Functionalities) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(uvw::StdOUT, false); - auto timer = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(uvw::std_out, false); + auto timer = loop->resource(); bool checkWriteEvent = false; - handle->on([&checkWriteEvent](const auto &, auto &hndl) { + handle->on([&checkWriteEvent](const auto &, auto &hndl) { ASSERT_FALSE(checkWriteEvent); checkWriteEvent = true; hndl.close(); }); - timer->on([handle](const auto &, auto &hndl) { + timer->on([handle](const auto &, auto &hndl) { auto data = std::make_unique('*'); - handle->write(std::move(data), 1); + + ASSERT_EQ(0, (handle->write(std::move(data), 1))); + hndl.close(); }); - ASSERT_TRUE(handle->reset()); - ASSERT_TRUE(!handle->readable() || handle->mode(uvw::TTYHandle::Mode::NORMAL)); - ASSERT_NO_THROW(handle->getWinSize()); + ASSERT_TRUE(handle->reset_mode()); + ASSERT_TRUE(!handle->readable() || handle->mode(uvw::tty_handle::tty_mode::NORMAL)); + ASSERT_NO_THROW(handle->get_win_size()); - timer->start(uvw::TimerHandle::Time{0}, uvw::TimerHandle::Time{0}); + timer->start(uvw::timer_handle::time{0}, uvw::timer_handle::time{0}); loop->run(); ASSERT_TRUE(checkWriteEvent); diff --git a/test/uvw/udp.cpp b/test/uvw/udp.cpp index 779d7381..f9bcf434 100644 --- a/test/uvw/udp.cpp +++ b/test/uvw/udp.cpp @@ -2,15 +2,15 @@ #include TEST(UDP, Functionalities) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - ASSERT_FALSE(handle->multicastMembership("0.0.0.0", "127.0.0.1", uvw::UDPHandle::Membership::JOIN_GROUP)); - ASSERT_TRUE(handle->multicastMembership("224.0.0.1", "127.0.0.1", uvw::UDPHandle::Membership::JOIN_GROUP)); - ASSERT_TRUE(handle->multicastMembership("224.0.0.1", "127.0.0.1", uvw::UDPHandle::Membership::LEAVE_GROUP)); - ASSERT_TRUE(handle->multicastLoop(true)); - ASSERT_TRUE(handle->multicastTtl(42)); - ASSERT_TRUE(handle->multicastInterface("127.0.0.1")); + ASSERT_FALSE(handle->multicast_membership("0.0.0.0", "127.0.0.1", uvw::udp_handle::membership::JOIN_GROUP)); + ASSERT_TRUE(handle->multicast_membership("224.0.0.1", "127.0.0.1", uvw::udp_handle::membership::JOIN_GROUP)); + ASSERT_TRUE(handle->multicast_membership("224.0.0.1", "127.0.0.1", uvw::udp_handle::membership::LEAVE_GROUP)); + ASSERT_TRUE(handle->multicast_loop(true)); + ASSERT_TRUE(handle->multicast_ttl(42)); + ASSERT_TRUE(handle->multicast_interface("127.0.0.1")); ASSERT_TRUE(handle->broadcast(true)); ASSERT_TRUE(handle->ttl(42)); ASSERT_FALSE(handle->ttl(0)); @@ -23,14 +23,15 @@ TEST(UDP, BindRecvStop) { const std::string address = std::string{"127.0.0.1"}; const unsigned int port = 4242; - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - handle->on([](const auto &, auto &) { FAIL(); }); + handle->on([](const auto &, auto &) { FAIL(); }); + + ASSERT_EQ(0, (handle->bind(address, port))); + ASSERT_EQ(0, handle->recv()); + ASSERT_EQ(0, handle->stop()); - handle->bind(address, port); - handle->recv(); - handle->stop(); handle->close(); loop->run(); @@ -40,28 +41,28 @@ TEST(UDP, ReadTrySend) { const std::string address = std::string{"127.0.0.1"}; const unsigned int port = 4242; - auto loop = uvw::Loop::getDefault(); - auto server = loop->resource(); - auto client = loop->resource(); + auto loop = uvw::loop::get_default(); + auto server = loop->resource(); + auto client = loop->resource(); - server->on([](const auto &, auto &) { FAIL(); }); - client->on([](const auto &, auto &) { FAIL(); }); + server->on([](const auto &, auto &) { FAIL(); }); + client->on([](const auto &, auto &) { FAIL(); }); - server->once([&client](const uvw::UDPDataEvent &, uvw::UDPHandle &handle) { + server->on([&client](const uvw::udp_data_event &, uvw::udp_handle &handle) { client->close(); handle.close(); }); - server->bind(uvw::Addr{address, port}); - server->recv(); + ASSERT_EQ(0, (server->bind(uvw::socket_address{address, port}))); + ASSERT_EQ(0, server->recv()); auto dataTrySend = std::unique_ptr(new char[1]{'a'}); - client->trySend(uvw::Addr{address, port}, dataTrySend.get(), 1); - client->trySend(address, port, nullptr, 0); + ASSERT_EQ(1, client->try_send(uvw::socket_address{address, port}, dataTrySend.get(), 1)); + ASSERT_EQ(0, client->try_send(address, port, nullptr, 0)); - client->trySend(uvw::Addr{address, port}, std::move(dataTrySend), 1); - client->trySend(address, port, std::unique_ptr{}, 0); + ASSERT_EQ(1, client->try_send(uvw::socket_address{address, port}, std::move(dataTrySend), 1)); + ASSERT_EQ(0, client->try_send(address, port, std::unique_ptr{}, 0)); loop->run(); } @@ -70,30 +71,30 @@ TEST(UDP, ReadSend) { const std::string address = std::string{"127.0.0.1"}; const unsigned int port = 4242; - auto loop = uvw::Loop::getDefault(); - auto server = loop->resource(); - auto client = loop->resource(); + auto loop = uvw::loop::get_default(); + auto server = loop->resource(); + auto client = loop->resource(); - server->on([](const auto &, auto &) { FAIL(); }); - client->on([](const auto &, auto &) { FAIL(); }); + server->on([](const auto &, auto &) { FAIL(); }); + client->on([](const auto &, auto &) { FAIL(); }); - server->once([](const uvw::UDPDataEvent &, uvw::UDPHandle &handle) { + server->on([](const uvw::udp_data_event &, uvw::udp_handle &handle) { handle.close(); }); - client->once([](const uvw::SendEvent &, uvw::UDPHandle &handle) { + client->on([](const uvw::send_event &, uvw::udp_handle &handle) { handle.close(); }); - server->bind(address, port); - server->recv(); + ASSERT_EQ(0, (server->bind(address, port))); + ASSERT_EQ(0, server->recv()); auto dataSend = std::unique_ptr(new char[2]{'b', 'c'}); - client->send(uvw::Addr{address, port}, dataSend.get(), 2); + client->send(uvw::socket_address{address, port}, dataSend.get(), 2); client->send(address, port, nullptr, 0); - client->send(uvw::Addr{address, port}, std::move(dataSend), 2); + client->send(uvw::socket_address{address, port}, std::move(dataSend), 2); client->send(address, port, std::unique_ptr{}, 0); loop->run(); @@ -103,15 +104,16 @@ TEST(UDP, Sock) { const std::string address = std::string{"127.0.0.1"}; const unsigned int port = 4242; - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); - handle->on([](const auto &, auto &) { FAIL(); }); + handle->on([](const auto &, auto &) { FAIL(); }); handle->bind(address, port); handle->recv(); - uvw::Addr sock = handle->sock(); + uvw::socket_address sock = handle->sock(); + ASSERT_EQ(sock.ip, address); ASSERT_EQ(sock.port, decltype(sock.port){port}); diff --git a/test/uvw/underlying_type.cpp b/test/uvw/underlying_type.cpp deleted file mode 100644 index bc631388..00000000 --- a/test/uvw/underlying_type.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -TEST(UnderlyingType, Functionalities) { - auto loop = uvw::Loop::getDefault(); - auto handle = uvw::AsyncHandle::create(loop); - - ASSERT_TRUE(handle); - ASSERT_EQ(&handle->loop(), loop.get()); -} - -TEST(UnderlyingType, Raw) { - auto loop = uvw::Loop::getDefault(); - auto handle = uvw::AsyncHandle::create(loop); - const auto &chandle = handle; - - auto *raw = handle->raw(); - auto *craw = chandle->raw(); - - ASSERT_EQ(raw, craw); -} diff --git a/test/uvw/util.cpp b/test/uvw/util.cpp index bb4c4f0e..31f184e8 100644 --- a/test/uvw/util.cpp +++ b/test/uvw/util.cpp @@ -6,93 +6,21 @@ template struct tag { using type = T; }; -TEST(Util, UnscopedFlags) { - enum class UnscopedEnum { - FOO = 1, - BAR = 2, - BAZ = 4, - QUUX = 8 - }; - - uvw::Flags flags{}; - - ASSERT_NO_THROW((flags = uvw::Flags::from())); - ASSERT_NO_THROW((flags = uvw::Flags{UnscopedEnum::BAZ})); - ASSERT_NO_THROW((flags = uvw::Flags{static_cast::Type>(UnscopedEnum::QUUX)})); - - ASSERT_NO_THROW((flags = uvw::Flags{std::move(flags)})); - ASSERT_NO_THROW((flags = uvw::Flags{flags})); - - flags = uvw::Flags::from(); - - ASSERT_TRUE(static_cast(flags)); - ASSERT_EQ(static_cast::Type>(flags), 9); - - ASSERT_TRUE(flags & uvw::Flags::from()); - ASSERT_FALSE(flags & UnscopedEnum::BAR); - ASSERT_FALSE(flags & uvw::Flags::from()); - ASSERT_TRUE(flags & UnscopedEnum::QUUX); - - ASSERT_NO_THROW(flags = flags | UnscopedEnum::BAR); - ASSERT_NO_THROW(flags = flags | uvw::Flags::from()); - - ASSERT_TRUE(flags & UnscopedEnum::FOO); - ASSERT_TRUE(flags & uvw::Flags::from()); - ASSERT_TRUE(flags & UnscopedEnum::BAZ); - ASSERT_TRUE(flags & uvw::Flags::from()); -} - -TEST(Util, ScopedFlags) { - enum class ScopedEnum { - FOO = 1, - BAR = 2, - BAZ = 4, - QUUX = 8 - }; - - uvw::Flags flags{}; - - ASSERT_NO_THROW((flags = uvw::Flags::from())); - ASSERT_NO_THROW((flags = uvw::Flags{ScopedEnum::BAZ})); - ASSERT_NO_THROW((flags = uvw::Flags{static_cast::Type>(ScopedEnum::QUUX)})); - - ASSERT_NO_THROW((flags = uvw::Flags{std::move(flags)})); - ASSERT_NO_THROW((flags = uvw::Flags{flags})); - - flags = uvw::Flags::from(); - - ASSERT_TRUE(static_cast(flags)); - ASSERT_EQ(static_cast::Type>(flags), 9); - - ASSERT_TRUE(flags & uvw::Flags::from()); - ASSERT_FALSE(flags & ScopedEnum::BAR); - ASSERT_FALSE(flags & uvw::Flags::from()); - ASSERT_TRUE(flags & ScopedEnum::QUUX); - - ASSERT_NO_THROW(flags = flags | ScopedEnum::BAR); - ASSERT_NO_THROW(flags = flags | uvw::Flags::from()); - - ASSERT_TRUE(flags & ScopedEnum::FOO); - ASSERT_TRUE(flags & uvw::Flags::from()); - ASSERT_TRUE(flags & ScopedEnum::BAZ); - ASSERT_TRUE(flags & uvw::Flags::from()); -} - TEST(Util, Utilities) { - ASSERT_EQ(uvw::PidType{}, uvw::PidType{}); + ASSERT_EQ(uvw::pid_type{}, uvw::pid_type{}); - ASSERT_NE(uvw::Utilities::OS::pid(), uvw::PidType{}); - ASSERT_NE(uvw::Utilities::OS::parent(), uvw::PidType{}); - ASSERT_FALSE(uvw::Utilities::OS::homedir().empty()); - ASSERT_FALSE(uvw::Utilities::OS::tmpdir().empty()); - ASSERT_NE(uvw::Utilities::OS::hostname(), ""); + ASSERT_NE(uvw::utilities::os::pid(), uvw::pid_type{}); + ASSERT_NE(uvw::utilities::os::ppid(), uvw::pid_type{}); + ASSERT_FALSE(uvw::utilities::os::homedir().empty()); + ASSERT_FALSE(uvw::utilities::os::tmpdir().empty()); + ASSERT_NE(uvw::utilities::os::hostname(), ""); - ASSERT_TRUE(uvw::Utilities::OS::env("UVW_TEST_UTIL_UTILITIES", "TRUE")); - ASSERT_TRUE(uvw::Utilities::OS::env("UVW_TEST_UTIL_UTILITIES") == "TRUE"); - ASSERT_TRUE(uvw::Utilities::OS::env("UVW_TEST_UTIL_UTILITIES", "")); - ASSERT_FALSE(uvw::Utilities::OS::env("UVW_TEST_UTIL_UTILITIES") == "TRUE"); + ASSERT_TRUE(uvw::utilities::os::env("UVW_TEST_UTIL_UTILITIES", "TRUE")); + ASSERT_TRUE(uvw::utilities::os::env("UVW_TEST_UTIL_UTILITIES") == "TRUE"); + ASSERT_TRUE(uvw::utilities::os::env("UVW_TEST_UTIL_UTILITIES", "")); + ASSERT_FALSE(uvw::utilities::os::env("UVW_TEST_UTIL_UTILITIES") == "TRUE"); - auto passwd = uvw::Utilities::OS::passwd(); + auto passwd = uvw::utilities::os::passwd(); ASSERT_TRUE(static_cast(passwd)); ASSERT_FALSE(passwd.username().empty()); @@ -105,67 +33,67 @@ TEST(Util, Utilities) { ASSERT_FALSE(passwd.shell().empty()); #endif - ASSERT_EQ(uvw::Utilities::guessHandle(uvw::FileHandle{-1}), uvw::HandleType::UNKNOWN); - ASSERT_NE(uvw::Utilities::guessHandle(uvw::StdIN), uvw::HandleType::UNKNOWN); + ASSERT_EQ(uvw::utilities::guess_handle(uvw::file_handle{-1}), uvw::handle_type::UNKNOWN); + ASSERT_NE(uvw::utilities::guess_handle(uvw::std_in), uvw::handle_type::UNKNOWN); auto guessHandle = [](auto tag, auto type) { - auto loop = uvw::Loop::getDefault(); + auto loop = uvw::loop::get_default(); auto handle = loop->resource(); - ASSERT_EQ(uvw::Utilities::guessHandle(handle->category()), type); + ASSERT_EQ(uvw::utilities::guess_handle(handle->category()), type); handle->close(); loop->run(); }; - guessHandle(tag{}, uvw::HandleType::ASYNC); - guessHandle(tag{}, uvw::HandleType::CHECK); - guessHandle(tag{}, uvw::HandleType::FS_EVENT); - guessHandle(tag{}, uvw::HandleType::FS_POLL); - guessHandle(tag{}, uvw::HandleType::IDLE); - guessHandle(tag{}, uvw::HandleType::PIPE); - guessHandle(tag{}, uvw::HandleType::PREPARE); - guessHandle(tag{}, uvw::HandleType::TCP); - guessHandle(tag{}, uvw::HandleType::TIMER); - guessHandle(tag{}, uvw::HandleType::UDP); - guessHandle(tag{}, uvw::HandleType::SIGNAL); + guessHandle(tag{}, uvw::handle_type::ASYNC); + guessHandle(tag{}, uvw::handle_type::CHECK); + guessHandle(tag{}, uvw::handle_type::FS_EVENT); + guessHandle(tag{}, uvw::handle_type::FS_POLL); + guessHandle(tag{}, uvw::handle_type::IDLE); + guessHandle(tag{}, uvw::handle_type::PIPE); + guessHandle(tag{}, uvw::handle_type::PREPARE); + guessHandle(tag{}, uvw::handle_type::TCP); + guessHandle(tag{}, uvw::handle_type::TIMER); + guessHandle(tag{}, uvw::handle_type::UDP); + guessHandle(tag{}, uvw::handle_type::SIGNAL); - auto cpuInfo = uvw::Utilities::cpuInfo(); + auto cpuInfo = uvw::utilities::cpu(); ASSERT_NE(cpuInfo.size(), decltype(cpuInfo.size()){0}); ASSERT_FALSE(cpuInfo[0].model.empty()); ASSERT_NE(cpuInfo[0].speed, decltype(cpuInfo[0].speed){0}); - auto interfaceAddresses = uvw::Utilities::interfaceAddresses(); + auto interfaceAddresses = uvw::utilities::interface_addresses(); ASSERT_NE(interfaceAddresses.size(), decltype(interfaceAddresses.size()){0}); ASSERT_FALSE(interfaceAddresses[0].name.empty()); ASSERT_FALSE(interfaceAddresses[0].address.ip.empty()); ASSERT_FALSE(interfaceAddresses[0].netmask.ip.empty()); - ASSERT_NO_THROW(uvw::Utilities::indexToName(0)); - ASSERT_NO_THROW(uvw::Utilities::indexToIid(0)); + ASSERT_NO_THROW(uvw::utilities::index_to_name(0)); + ASSERT_NO_THROW(uvw::utilities::index_to_iid(0)); - ASSERT_TRUE(uvw::Utilities::replaceAllocator( + ASSERT_TRUE(uvw::utilities::replace_allocator( [](size_t size) { return malloc(size); }, [](void *ptr, size_t size) { return realloc(ptr, size); }, [](size_t num, size_t size) { return calloc(num, size); }, [](void *ptr) { return free(ptr); })); - ASSERT_NO_THROW(uvw::Utilities::loadAverage()); - ASSERT_NE(uvw::Utilities::totalMemory(), decltype(uvw::Utilities::totalMemory()){0}); - ASSERT_NE(uvw::Utilities::uptime(), decltype(uvw::Utilities::uptime()){0}); - ASSERT_NO_THROW(uvw::Utilities::rusage()); - ASSERT_NE(uvw::Utilities::hrtime(), decltype(uvw::Utilities::hrtime()){0}); - ASSERT_FALSE(uvw::Utilities::path().empty()); - ASSERT_FALSE(uvw::Utilities::cwd().empty()); - ASSERT_TRUE(uvw::Utilities::chdir(uvw::Utilities::cwd())); + ASSERT_NO_THROW(uvw::utilities::load_average()); + ASSERT_NE(uvw::utilities::total_memory(), decltype(uvw::utilities::total_memory()){0}); + ASSERT_NE(uvw::utilities::uptime(), decltype(uvw::utilities::uptime()){0}); + ASSERT_NO_THROW(uvw::utilities::rusage()); + ASSERT_NE(uvw::utilities::hrtime(), decltype(uvw::utilities::hrtime()){0}); + ASSERT_FALSE(uvw::utilities::path().empty()); + ASSERT_FALSE(uvw::utilities::cwd().empty()); + ASSERT_TRUE(uvw::utilities::chdir(uvw::utilities::cwd())); std::unique_ptr fake{new char[1], [](void *ptr) { delete[] static_cast(ptr); }}; char *argv = fake.get(); argv[0] = '\0'; - ASSERT_NE(uvw::Utilities::setupArgs(1, &argv), nullptr); - ASSERT_NE(uvw::Utilities::processTitle(), std::string{}); - ASSERT_TRUE(uvw::Utilities::processTitle(uvw::Utilities::processTitle())); + ASSERT_NE(uvw::utilities::setup_args(1, &argv), nullptr); + ASSERT_NE(uvw::utilities::process_title(), std::string{}); + ASSERT_TRUE(uvw::utilities::process_title(uvw::utilities::process_title())); - ASSERT_NE(uvw::Utilities::availableParallelism(), 0u); + ASSERT_NE(uvw::utilities::available_parallelism(), 0u); } diff --git a/test/uvw/uv_type.cpp b/test/uvw/uv_type.cpp new file mode 100644 index 00000000..92fcffde --- /dev/null +++ b/test/uvw/uv_type.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +TEST(UvType, Functionalities) { + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); + + ASSERT_TRUE(handle); + ASSERT_EQ(&handle->parent(), loop.get()); +} + +TEST(UvType, Raw) { + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); + const auto &chandle = handle; + + auto *raw = handle->raw(); + auto *craw = chandle->raw(); + + ASSERT_EQ(raw, craw); +} diff --git a/test/uvw/work.cpp b/test/uvw/work.cpp index 10c1b6de..1d2241b7 100644 --- a/test/uvw/work.cpp +++ b/test/uvw/work.cpp @@ -4,51 +4,53 @@ #include TEST(Work, RunTask) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); bool checkTask = false; - auto req = loop->resource([&checkTask]() { + auto req = loop->resource([&checkTask]() { ASSERT_FALSE(checkTask); checkTask = true; }); - req->on([](const auto &, auto &) { FAIL(); }); + req->on([](const auto &, auto &) { FAIL(); }); - req->on([&handle](const auto &, auto &) { + req->on([&handle](const auto &, auto &) { handle->close(); }); handle->start(); - req->queue(); + + ASSERT_EQ(0, req->queue()); + loop->run(); ASSERT_TRUE(checkTask); } TEST(Work, Cancellation) { - auto loop = uvw::Loop::getDefault(); - auto handle = loop->resource(); + auto loop = uvw::loop::get_default(); + auto handle = loop->resource(); bool checkErrorEvent = false; - handle->on([](const auto &, auto &hndl) { + handle->on([](const auto &, auto &hndl) { hndl.stop(); hndl.close(); }); for(auto i = 0; i < 5 /* default uv thread pool size + 1 */; ++i) { - auto req = loop->resource([]() {}); + auto req = loop->resource([]() {}); - req->on([](const auto &, auto &) {}); - req->on([&checkErrorEvent](const auto &, auto &) { checkErrorEvent = true; }); + req->on([](const auto &, auto &) {}); + req->on([&checkErrorEvent](const auto &, auto &) { checkErrorEvent = true; }); req->queue(); req->cancel(); } - handle->start(uvw::TimerHandle::Time{500}, uvw::TimerHandle::Time{500}); + handle->start(uvw::timer_handle::time{500}, uvw::timer_handle::time{500}); loop->run(); ASSERT_TRUE(checkErrorEvent);