commit
3005b01b1e
@ -13,12 +13,26 @@
|
||||
namespace uvw {
|
||||
|
||||
|
||||
/**
|
||||
* @brief FsPollEvent event.
|
||||
*
|
||||
* It will be emitted by the FsPollHandle according with its functionalities.
|
||||
*/
|
||||
struct FsPollEvent: Event<FsPollEvent> {
|
||||
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<FsPollHandle, uv_fs_poll_t> {
|
||||
static void startCallback(uv_fs_poll_t *handle, int status, const uv_stat_t *prev, const uv_stat_t *curr) {
|
||||
FsPollHandle &fsPoll = *(static_cast<FsPollHandle*>(handle->data));
|
||||
@ -37,23 +58,47 @@ class FsPollHandle final: public Handle<FsPollHandle, uv_fs_poll_t> {
|
||||
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<typename... Args>
|
||||
static std::shared_ptr<FsPollHandle> create(Args&&... args) {
|
||||
return std::shared_ptr<FsPollHandle>{new FsPollHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the handle.
|
||||
* @return True in case of success, false otherwise.
|
||||
*/
|
||||
bool init() {
|
||||
return initialize<uv_fs_poll_t>(&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<uv_fs_poll_t>(), &startCallback, file.data(), interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the handle.
|
||||
*/
|
||||
void stop() {
|
||||
invoke(&uv_fs_poll_stop, get<uv_fs_poll_t>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @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<uv_fs_poll_t>());
|
||||
}
|
||||
|
||||
@ -122,6 +122,8 @@ public:
|
||||
* This **must** be called on each handle before memory is released.<br/>
|
||||
* 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()) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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<uv_prepare_t>(), &startCallback);
|
||||
|
||||
@ -12,9 +12,18 @@
|
||||
namespace uvw {
|
||||
|
||||
|
||||
/**
|
||||
* @brief SignalEvent event.
|
||||
*
|
||||
* It will be emitted by the SignalHandle according with its functionalities.
|
||||
*/
|
||||
struct SignalEvent: Event<SignalEvent> {
|
||||
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.<br/>
|
||||
* 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<SignalHandle, uv_signal_t> {
|
||||
static void startCallback(uv_signal_t *handle, int signum) {
|
||||
SignalHandle &signal = *(static_cast<SignalHandle*>(handle->data));
|
||||
@ -31,23 +51,46 @@ class SignalHandle final: public Handle<SignalHandle, uv_signal_t> {
|
||||
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<typename... Args>
|
||||
static std::shared_ptr<SignalHandle> create(Args&&... args) {
|
||||
return std::shared_ptr<SignalHandle>{new SignalHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the handle.
|
||||
* @return True in case of success, false otherwise.
|
||||
*/
|
||||
bool init() {
|
||||
return initialize<uv_signal_t>(&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<uv_signal_t>(), &startCallback, signum);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the handle.
|
||||
*/
|
||||
void stop() {
|
||||
invoke(&uv_signal_stop, get<uv_signal_t>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the signal being monitored.
|
||||
* @return The signal being monitored.
|
||||
*/
|
||||
int signal() const noexcept {
|
||||
return get<uv_signal_t>()->signum;
|
||||
}
|
||||
|
||||
@ -15,19 +15,66 @@
|
||||
namespace uvw {
|
||||
|
||||
|
||||
/**
|
||||
* @brief ConnectEvent event.
|
||||
*
|
||||
* It will be emitted by the StreamHandle according with its functionalities.
|
||||
*/
|
||||
struct ConnectEvent: Event<ConnectEvent> { };
|
||||
|
||||
|
||||
/**
|
||||
* @brief EndEvent event.
|
||||
*
|
||||
* It will be emitted by the StreamHandle according with its functionalities.
|
||||
*/
|
||||
struct EndEvent: Event<EndEvent> { };
|
||||
|
||||
|
||||
/**
|
||||
* @brief ListenEvent event.
|
||||
*
|
||||
* It will be emitted by the StreamHandle according with its functionalities.
|
||||
*/
|
||||
struct ListenEvent: Event<ListenEvent> { };
|
||||
|
||||
|
||||
/**
|
||||
* @brief ShutdownEvent event.
|
||||
*
|
||||
* It will be emitted by the StreamHandle according with its functionalities.
|
||||
*/
|
||||
struct ShutdownEvent: Event<ShutdownEvent> { };
|
||||
|
||||
|
||||
/**
|
||||
* @brief WriteEvent event.
|
||||
*
|
||||
* It will be emitted by the StreamHandle according with its functionalities.
|
||||
*/
|
||||
struct WriteEvent: Event<WriteEvent> { };
|
||||
|
||||
|
||||
/**
|
||||
* @brief DataEvent event.
|
||||
*
|
||||
* It will be emitted by the StreamHandle according with its functionalities.
|
||||
*/
|
||||
struct DataEvent: Event<DataEvent> {
|
||||
explicit DataEvent(std::unique_ptr<const char[]> 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<typename T, typename U>
|
||||
class StreamHandle: public Handle<T, U> {
|
||||
static constexpr unsigned int DEFAULT_BACKLOG = 128;
|
||||
@ -123,6 +177,13 @@ protected:
|
||||
using Handle<T, U>::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.<br/>
|
||||
* 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<uv_stream_t>());
|
||||
}
|
||||
|
||||
void listen(int backlog) {
|
||||
/**
|
||||
* @brief Starts listening for incoming connections.
|
||||
*
|
||||
* When a new incoming connection is received, a ConnectEvent event is
|
||||
* emitted.<br/>
|
||||
* 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<uv_stream_t>(), 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.<br>
|
||||
* 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.<br/>
|
||||
* 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<typename S>
|
||||
void accept(S &ref) {
|
||||
this->invoke(&uv_accept, this->template get<uv_stream_t>(), ref.template get<uv_stream_t>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.<br/>
|
||||
* An EndEvent event will be emitted when there is no more data to read.
|
||||
*/
|
||||
void read() {
|
||||
this->invoke(&uv_read_start, this->template get<uv_stream_t>(), &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<uv_stream_t>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes data to the stream.
|
||||
*
|
||||
* Data are written in order.<br/>
|
||||
* A WriteEvent event will be emitted when the data have been written.<br/>
|
||||
* 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<char[]> data, ssize_t len) {
|
||||
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
|
||||
|
||||
@ -168,6 +275,23 @@ public:
|
||||
write->write(this->template get<uv_stream_t>(), 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.<br/>
|
||||
* 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<typename S>
|
||||
void write(S &send, std::unique_ptr<char[]> data, ssize_t len) {
|
||||
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
|
||||
@ -182,6 +306,17 @@ public:
|
||||
write->write(this->template get<uv_stream_t>(), bufs, 1, send.template get<uv_stream_t>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.<br/>
|
||||
* 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<char[]> data, ssize_t len) {
|
||||
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
|
||||
auto bw = uv_try_write(this->template get<uv_stream_t>(), 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<uv_stream_t>()) == 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<uv_stream_t>()) == 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<uv_stream_t>(), enable);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user