diff --git a/src/uvw/fs_poll.hpp b/src/uvw/fs_poll.hpp index 514d29df..94c7df61 100644 --- a/src/uvw/fs_poll.hpp +++ b/src/uvw/fs_poll.hpp @@ -13,12 +13,26 @@ namespace uvw { +/** + * @brief FsPollEvent event. + * + * It will be emitted by the FsPollHandle according with its functionalities. + */ struct FsPollEvent: Event { explicit FsPollEvent(const Stat &p, const Stat &c) noexcept : prev(p), curr(c) { } + /** + * @brief Gets the old Stat struct. + * @return The old Stat struct. + */ const Stat & previous() const noexcept { return prev; } + + /** + * @brief Gets the new Stat struct. + * @return The new Stat struct. + */ const Stat & current() const noexcept { return curr; } private: @@ -27,6 +41,13 @@ private: }; +/** + * @brief The FsPollHandle 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. + */ 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) { FsPollHandle &fsPoll = *(static_cast(handle->data)); @@ -37,23 +58,47 @@ class FsPollHandle final: public Handle { using Handle::Handle; public: + /** + * @brief Creates a new fs poll handle. + * @param args A pointer to the loop from which the handle generated. + * @return A pointer to the newly created handle. + */ template static std::shared_ptr create(Args&&... args) { return std::shared_ptr{new FsPollHandle{std::forward(args)...}}; } + /** + * @brief Initializes the handle. + * @return True in case of success, false otherwise. + */ bool init() { return initialize(&uv_fs_poll_init); } + /** + * @brief Starts the handle. + * + * The handle will start emitting FsPollEvent when needed. + * + * @param file The path to the file to be checked. + * @param interval Milliseconds between successive checks. + */ void start(std::string file, unsigned int interval) { invoke(&uv_fs_poll_start, get(), &startCallback, file.data(), interval); } + /** + * @brief Stops the handle. + */ void stop() { invoke(&uv_fs_poll_stop, get()); } + /** + * @brief Gets the path being monitored by the handle. + * @return The path being monitored by the handle. + */ std::string path() noexcept { return details::path(&uv_fs_poll_getpath, get()); } diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index 4755d941..06d537b3 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -122,6 +122,8 @@ public: * This **must** be called on each handle before memory is released.
* In-progress requests are cancelled and this can result in an ErrorEvent * emitted. + * + * The handle will emit a CloseEvent when finished. */ void close() noexcept override { if(!closing()) { diff --git a/src/uvw/poll.hpp b/src/uvw/poll.hpp index 6ac40a74..1d53160d 100644 --- a/src/uvw/poll.hpp +++ b/src/uvw/poll.hpp @@ -89,6 +89,7 @@ public: /** * @brief Initializes the handle. + * @param fd A valid file descriptor. * @return True in case of success, false otherwise. */ bool init(int fd) { diff --git a/src/uvw/prepare.hpp b/src/uvw/prepare.hpp index 24b4aaea..42cfe2a3 100644 --- a/src/uvw/prepare.hpp +++ b/src/uvw/prepare.hpp @@ -58,6 +58,8 @@ public: * * A PrepareEvent event will be emitted once per loop iteration, right * before polling for I/O. + * + * The handle will start emitting PrepareEvent when needed. */ void start() { invoke(&uv_prepare_start, get(), &startCallback); diff --git a/src/uvw/signal.hpp b/src/uvw/signal.hpp index d6b2fcf3..e3f5da29 100644 --- a/src/uvw/signal.hpp +++ b/src/uvw/signal.hpp @@ -12,9 +12,18 @@ namespace uvw { +/** + * @brief SignalEvent event. + * + * It will be emitted by the SignalHandle according with its functionalities. + */ struct SignalEvent: Event { explicit SignalEvent(int sig) noexcept: signum(sig) { } + /** + * @brief Gets the signal being monitored by this handle. + * @return The signal being monitored by this handle. + */ int signal() const noexcept { return signum; } private: @@ -22,6 +31,17 @@ private: }; +/** + * @brief The SignalHandle handle. + * + * Signal handles implement Unix style signal handling on a per-event loop + * bases.
+ * Reception of some signals is emulated on Windows. + * + * 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) { SignalHandle &signal = *(static_cast(handle->data)); @@ -31,23 +51,46 @@ class SignalHandle final: public Handle { using Handle::Handle; public: + /** + * @brief Creates a new signal handle. + * @param args A pointer to the loop from which the handle generated. + * @return A pointer to the newly created handle. + */ template static std::shared_ptr create(Args&&... args) { return std::shared_ptr{new SignalHandle{std::forward(args)...}}; } + /** + * @brief Initializes the handle. + * @return True in case of success, false otherwise. + */ bool init() { return initialize(&uv_signal_init); } + /** + * @brief Starts the handle. + * + * The handle will start emitting SignalEvent when needed. + * + * @param signum The signal to be monitored. + */ void start(int signum) { invoke(&uv_signal_start, get(), &startCallback, signum); } + /** + * @brief Stops the handle. + */ void stop() { invoke(&uv_signal_stop, get()); } + /** + * @brief Gets the signal being monitored. + * @return The signal being monitored. + */ int signal() const noexcept { return get()->signum; } diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 6500d8aa..65db0007 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -15,19 +15,66 @@ namespace uvw { +/** + * @brief ConnectEvent event. + * + * It will be emitted by the StreamHandle according with its functionalities. + */ struct ConnectEvent: Event { }; + + +/** + * @brief EndEvent event. + * + * It will be emitted by the StreamHandle according with its functionalities. + */ struct EndEvent: Event { }; + + +/** + * @brief ListenEvent event. + * + * It will be emitted by the StreamHandle according with its functionalities. + */ struct ListenEvent: Event { }; + + +/** + * @brief ShutdownEvent event. + * + * It will be emitted by the StreamHandle according with its functionalities. + */ struct ShutdownEvent: Event { }; + + +/** + * @brief WriteEvent event. + * + * It will be emitted by the StreamHandle according with its functionalities. + */ struct WriteEvent: Event { }; +/** + * @brief DataEvent event. + * + * It will be emitted by the StreamHandle according with its functionalities. + */ struct DataEvent: Event { explicit DataEvent(std::unique_ptr ptr, ssize_t l) noexcept : dt{std::move(ptr)}, len{l} { } + /** + * @brief Gets the data read on the stream. + * @return A bunch of data read on the stream. + */ const char * data() const noexcept { return dt.get(); } + + /** + * @brief Gets the amount of data read on the stream. + * @return The amount of data read on the stream. + */ ssize_t length() const noexcept { return len; } private: @@ -92,6 +139,13 @@ public: } +/** + * @brief The StreamHandle 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. + */ template class StreamHandle: public Handle { static constexpr unsigned int DEFAULT_BACKLOG = 128; @@ -123,6 +177,13 @@ protected: using Handle::Handle; public: + /** + * @brief Shutdowns the outgoing (write) side of a duplex stream. + * + * 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. + */ void shutdown() { auto listener = [ptr = this->shared_from_this()](const auto &event, details::ShutdownReq &) { ptr->publish(event); @@ -134,27 +195,73 @@ public: shutdown->shutdown(this->template get()); } - void listen(int backlog) { + /** + * @brief Starts listening for incoming connections. + * + * When a new incoming connection is received, a ConnectEvent event is + * emitted.
+ * An ErrorEvent event will be emitted in case of errors. + * + * @param backlog Indicates the number of connections the kernel might + * queue, same as listen(2). + */ + void listen(int backlog = DEFAULT_BACKLOG) { this->invoke(&uv_listen, this->template get(), backlog, &listenCallback); } - void listen() { - listen(DEFAULT_BACKLOG); - } - + /** + * @brief Accepts incoming connections. + * + * This call is used in conjunction with `listen()` to accept incoming + * connections. Call this function after receiving a ConnectEvent 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. + * + * When the ConnectEvent 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 ConnectEvent event. + * + * **Note**: both the handles must be running on the same loop. + * + * @param ref An initialized handle to be used to accept the connection. + */ template void accept(S &ref) { this->invoke(&uv_accept, this->template get(), ref.template get()); } + /** + * @brief Starts reading data from an incoming stream. + * + * A ReadEvent 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. + */ void read() { this->invoke(&uv_read_start, this->template get(), &this->allocCallback, &readCallback); } + /** + * @brief Stops reading data from the stream. + * + * This function is idempotent and may be safely called on a stopped stream. + */ void stop() { this->invoke(&uv_read_stop, this->template get()); } + /** + * @brief Writes data to the stream. + * + * Data are written in order.
+ * A WriteEvent event will be emitted when the data have been written.
+ * An ErrorEvent wvent will be emitted in case of errors. + * + * @param data The data to be written to the stream. + * @param len The lenght of the submitted data. + */ void write(std::unique_ptr data, ssize_t len) { uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; @@ -168,6 +275,23 @@ public: write->write(this->template get(), bufs, 1); } + + /** + * @brief Extended write function for sending handles over a pipe handle. + * + * 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. + * + * A WriteEvent event will be emitted when the data have been written.
+ * An ErrorEvent wvent will be emitted in case of errors. + * + * @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. + */ template void write(S &send, std::unique_ptr data, ssize_t len) { uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; @@ -182,6 +306,17 @@ public: write->write(this->template get(), bufs, 1, send.template get()); } + /** + * @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. + * + * @param data The data to be written to the stream. + * @param len The lenght of the submitted data. + * @return Nomuber of bytes written. + */ int tryWrite(std::unique_ptr data, ssize_t len) { uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; auto bw = uv_try_write(this->template get(), bufs, 1); @@ -194,14 +329,36 @@ public: return bw; } + /** + * @brief Checks if the stream is readable. + * @return True if the stream is readable, false otherwise. + */ bool readable() const noexcept { return (uv_is_readable(this->template get()) == 1); } + /** + * @brief Checks if the stream is writable. + * @return True if the stream is writable, false otherwise. + */ bool writable() const noexcept { return (uv_is_writable(this->template get()) == 1); } + /** + * @brief Enables or disables blocking mode for a stream. + * + * When blocking mode is enabled all writes complete synchronously. The + * interface remains unchanged otherwise, e.g. completion or failure of the + * operation will still be reported through events which are emitted + * asynchronously. + * + * See the official + * [documentation](http://docs.libuv.org/en/v1.x/stream.html#c.uv_stream_set_blocking) + * for further details. + * + * @param enable True to enable blocking mode, false otherwise. + */ void blocking(bool enable = false) { this->invoke(&uv_stream_set_blocking, this->template get(), enable); }