Merge pull request #31 from cynnyx/master

WIP: Fs
This commit is contained in:
Michele Caini 2016-07-28 13:50:02 +02:00 committed by GitHub
commit b0086ff8f1
19 changed files with 165 additions and 173 deletions

View File

@ -14,13 +14,13 @@ As an example, a *handle* should be initialized before any other operation and c
#include <memory>
void listen(uvw::Loop &loop) {
std::shared_ptr<uvw::Tcp> tcp = loop.resource<uvw::Tcp>();
std::shared_ptr<uvw::TcpHandle> tcp = loop.resource<uvw::TcpHandle>();
tcp->once<uvw::ListenEvent>([](const uvw::ListenEvent &event, uvw::Tcp &srv) mutable {
std::shared_ptr<uvw::Tcp> client = srv.loop().resource<uvw::Tcp>();
tcp->once<uvw::ListenEvent>([](const uvw::ListenEvent &event, uvw::TcpHandle &srv) mutable {
std::shared_ptr<uvw::TcpHandle> client = srv.loop().resource<uvw::TcpHandle>();
client->on<uvw::CloseEvent>([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::Tcp &) mutable { ptr->close(); });
client->on<uvw::EndEvent>([](const uvw::EndEvent &, uvw::Tcp &client) { client.close(); });
client->on<uvw::CloseEvent>([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::TcpHandle &) mutable { ptr->close(); });
client->on<uvw::EndEvent>([](const uvw::EndEvent &, uvw::TcpHandle &client) { client.close(); });
srv.accept(*client);
client->read();
@ -31,11 +31,11 @@ void listen(uvw::Loop &loop) {
}
void conn(uvw::Loop &loop) {
auto tcp = loop.resource<uvw::Tcp>();
auto tcp = loop.resource<uvw::TcpHandle>();
tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::Tcp &) { /* handle errors */ });
tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TcpHandle &) { /* handle errors */ });
tcp->once<uvw::ConnectEvent>([](const uvw::ConnectEvent &, uvw::Tcp &tcp) mutable {
tcp->once<uvw::ConnectEvent>([](const uvw::ConnectEvent &, uvw::TcpHandle &tcp) mutable {
auto dataWrite = std::unique_ptr<char[]>(new char[2]{ 'b', 'c' });
tcp.write(std::move(dataWrite), 2);
tcp.close();
@ -119,13 +119,13 @@ Loops can be run using the `run`, `runOnce` and `runWait` member methods. Please
In order to create a resource and to bind it to the given loop, just do the following:
auto tcp = loop.resource<uvw::Tcp>();
auto tcp = loop.resource<uvw::TcpHandle>();
The line above will create and initialize a tcp handle, thus a shared pointer to that resource will be 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:
auto tcp = Tcp::create(loop);
auto tcp = TcpHandle::create(loop);
tcp->init();
Pretty annoying indeed. Using a loop is the recommended approach.
@ -160,7 +160,7 @@ There exist two methods to attach an event to a resource:
* `resource.once<EventType>(listener)`: the listener will be automatically removed after the first event of the given type
* `resource.on<EventType>(listener)`: to be used for long-running listeners
Both of them return an object of type `ResourceType::Connection` (as an example, `Tcp::Connection`).
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 method of the resource to remove the listener.
There exists also the `clear` member method to drop all the listeners at once.
@ -168,14 +168,14 @@ The code below shows how to create a simple tcp server using `uvw`:
```
auto loop = uvw::Loop::getDefault();
auto tcp = loop.resource<uvw::Tcp>();
auto tcp = loop.resource<uvw::TcpHandle>();
tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::Tcp &srv) { /* something went wrong */ });
tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TcpHandle &srv) { /* something went wrong */ });
tcp->on<uvw::ListenEvent>([](const uvw::ListenEvent &event, uvw::Tcp &srv) mutable {
std::shared_ptr<uvw::Tcp> client = srv.loop().resource<uvw::Tcp>();
client->once<uvw::EndEvent>([](const uvw::EndEvent &, uvw::Tcp &client) { client.close(); });
client->on<uvw::DataEvent>([](const uvw::DataEvent &, uvw::Tcp &) { /* data received */ });
tcp->on<uvw::ListenEvent>([](const uvw::ListenEvent &event, uvw::TcpHandle &srv) mutable {
std::shared_ptr<uvw::TcpHandle> client = srv.loop().resource<uvw::TcpHandle>();
client->once<uvw::EndEvent>([](const uvw::EndEvent &, uvw::TcpHandle &client) { client.close(); });
client->on<uvw::DataEvent>([](const uvw::DataEvent &, uvw::TcpHandle &) { /* data received */ });
srv.accept(*client);
client->read();
});
@ -184,8 +184,8 @@ tcp->bind("127.0.0.1", 4242);
tcp->listen();
```
Note that `uvw::Tcp` already supports _IPv6_ out-of-the-box. The statement above is equivalent to `tcp->bind<uvw::Tcp::IPv4>("127.0.0.1", 4242)`.
It's suffice to explicitly specify `uvw::Tcp::IPv6` as the underlying protocol to use it.
Note that `uvw::TcpHandle` already supports _IPv6_ out-of-the-box. The statement above is equivalent to `tcp->bind<uvw::TcpHandle::IPv4>("127.0.0.1", 4242)`.
It's suffice to explicitly specify `uvw::TcpHandle::IPv6` as the underlying protocol to use it.
The API reference is the recommended documentation for further details about resources and their methods.

View File

@ -15,9 +15,9 @@ namespace uvw {
struct AsyncEvent: Event<AsyncEvent> { };
class Async final: public Handle<Async, uv_async_t> {
class AsyncHandle final: public Handle<AsyncHandle, uv_async_t> {
static void sendCallback(uv_async_t *handle) {
Async &async = *(static_cast<Async*>(handle->data));
AsyncHandle &async = *(static_cast<AsyncHandle*>(handle->data));
async.publish(AsyncEvent{});
}
@ -25,8 +25,8 @@ class Async final: public Handle<Async, uv_async_t> {
public:
template<typename... Args>
static std::shared_ptr<Async> create(Args&&... args) {
return std::shared_ptr<Async>{new Async{std::forward<Args>(args)...}};
static std::shared_ptr<AsyncHandle> create(Args&&... args) {
return std::shared_ptr<AsyncHandle>{new AsyncHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_async_t>(&uv_async_init, &sendCallback); }

View File

@ -15,9 +15,9 @@ namespace uvw {
struct CheckEvent: Event<CheckEvent> { };
class Check final: public Handle<Check, uv_check_t> {
class CheckHandle final: public Handle<CheckHandle, uv_check_t> {
static void startCallback(uv_check_t *handle) {
Check &check = *(static_cast<Check*>(handle->data));
CheckHandle &check = *(static_cast<CheckHandle*>(handle->data));
check.publish(CheckEvent{});
}
@ -25,8 +25,8 @@ class Check final: public Handle<Check, uv_check_t> {
public:
template<typename... Args>
static std::shared_ptr<Check> create(Args&&... args) {
return std::shared_ptr<Check>{new Check{std::forward<Args>(args)...}};
static std::shared_ptr<CheckHandle> create(Args&&... args) {
return std::shared_ptr<CheckHandle>{new CheckHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_check_t>(&uv_check_init); }

View File

@ -81,6 +81,23 @@ private:
};
template<>
struct TypedEvent<details::UVFsType, details::UVFsType::OPEN>
: Event<TypedEvent<details::UVFsType, details::UVFsType::OPEN>>
{
TypedEvent(const char *p, uv_file desc) noexcept
: rPath{p}, fd{desc}
{ }
const char * path() const noexcept { return rPath; }
FileHandle descriptor() const noexcept { return fd; }
private:
const char *rPath;
uv_file fd;
};
template<>
struct TypedEvent<details::UVFsType, details::UVFsType::WRITE>
: Event<TypedEvent<details::UVFsType, details::UVFsType::WRITE>>
@ -206,29 +223,11 @@ template<details::UVFsType e>
using FsEvent = TypedEvent<details::UVFsType, e>;
class Fs final: public Request<Fs, uv_fs_t> {
static constexpr int BAD_FD = -1;
static void fsCloseCallback(uv_fs_t *req) {
auto ptr = reserve(reinterpret_cast<uv_req_t*>(req));
if(req->result) {
ptr->publish(ErrorEvent{req->result});
} else {
ptr->file = BAD_FD;
ptr->publish(FsEvent<Type::CLOSE>{req->path});
}
}
class FsReq final: public Request<FsReq, uv_fs_t> {
static void fsOpenCallback(uv_fs_t *req) {
auto ptr = reserve(reinterpret_cast<uv_req_t*>(req));
if(req->result < 0) {
ptr->publish(ErrorEvent{req->result});
} else {
ptr->file = req->result;
ptr->publish(FsEvent<Type::OPEN>{req->path});
}
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
else { ptr->publish(FsEvent<Type::OPEN>{req->path, static_cast<uv_file>(req->result)}); }
}
template<details::UVFsType e>
@ -283,22 +282,21 @@ public:
using Entry = std::pair<EntryType, std::string>;
template<typename... Args>
static std::shared_ptr<Fs> create(Args&&... args) {
return std::shared_ptr<Fs>{new Fs{std::forward<Args>(args)...}};
static std::shared_ptr<FsReq> create(Args&&... args) {
return std::shared_ptr<FsReq>{new FsReq{std::forward<Args>(args)...}};
}
~Fs() {
~FsReq() {
uv_fs_req_cleanup(get<uv_fs_t>());
}
void close() {
cleanupAndInvoke(&uv_fs_close, parent(), get<uv_fs_t>(), file, &fsCloseCallback);
void close(FileHandle file) {
cleanupAndInvoke(&uv_fs_close, parent(), get<uv_fs_t>(), file, &fsGenericCallback<Type::CLOSE>);
}
auto closeSync() {
auto closeSync(FileHandle file) {
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_close, parent(), req, file, nullptr);
if(!req->result) { file = BAD_FD; }
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::CLOSE>{req->path});
}
@ -310,8 +308,7 @@ public:
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_open, parent(), req, path.data(), flags, mode, nullptr);
auto fd = req->result;
if(fd >= 0) { file = fd; }
return std::make_pair(ErrorEvent{fd < 0 ? fd : 0}, FsEvent<Type::OPEN>{req->path});
return std::make_pair(ErrorEvent{fd < 0 ? fd : 0}, FsEvent<Type::OPEN>{req->path, static_cast<uv_file>(fd)});
}
void read(int64_t offset, unsigned int len) {
@ -332,12 +329,12 @@ public:
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::UNLINK>{req->path});
}
void write(std::unique_ptr<char[]> data, ssize_t len, int64_t offset) {
void write(FileHandle file, std::unique_ptr<char[]> data, ssize_t len, int64_t offset) {
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
cleanupAndInvoke(&uv_fs_write, parent(), get<uv_fs_t>(), file, bufs, 1, offset, &fsResultCallback<Type::WRITE>);
}
auto writeSync(std::unique_ptr<char[]> data, ssize_t len, int64_t offset) {
auto writeSync(FileHandle file, std::unique_ptr<char[]> data, ssize_t len, int64_t offset) {
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_write, parent(), get<uv_fs_t>(), file, bufs, 1, offset, nullptr);
@ -410,11 +407,11 @@ public:
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::STAT>{req->path, req->statbuf});
}
void fstat() {
void fstat(FileHandle file) {
cleanupAndInvoke(&uv_fs_fstat, parent(), get<uv_fs_t>(), file, &fsStatCallback<Type::FSTAT>);
}
auto fstatSync() {
auto fstatSync(FileHandle file) {
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file, nullptr);
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FSTAT>{req->path, req->statbuf});
@ -440,43 +437,43 @@ public:
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::RENAME>{req->path});
}
void fsync() {
void fsync(FileHandle file) {
cleanupAndInvoke(&uv_fs_fsync, parent(), get<uv_fs_t>(), file, &fsGenericCallback<Type::FSYNC>);
}
auto fsyncSync() {
auto fsyncSync(FileHandle file) {
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_fsync, parent(), req, file, nullptr);
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FSYNC>{req->path});
}
void fdatasync() {
void fdatasync(FileHandle file) {
cleanupAndInvoke(&uv_fs_fdatasync, parent(), get<uv_fs_t>(), file, &fsGenericCallback<Type::FDATASYNC>);
}
auto fdatasyncSync() {
auto fdatasyncSync(FileHandle file) {
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), req, file, nullptr);
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FDATASYNC>{req->path});
}
void ftruncate(int64_t offset) {
void ftruncate(FileHandle file, int64_t offset) {
cleanupAndInvoke(&uv_fs_ftruncate, parent(), get<uv_fs_t>(), file, offset, &fsGenericCallback<Type::FTRUNCATE>);
}
auto ftruncateSync(int64_t offset) {
auto ftruncateSync(FileHandle file, int64_t offset) {
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), req, file, offset, nullptr);
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FTRUNCATE>{req->path});
}
void sendfile(FileHandle out, int64_t offset, size_t length) {
cleanupAndInvoke(&uv_fs_sendfile, parent(), get<uv_fs_t>(), out, file, offset, length, &fsResultCallback<Type::SENDFILE>);
void sendfile(FileHandle out, FileHandle in, int64_t offset, size_t length) {
cleanupAndInvoke(&uv_fs_sendfile, parent(), get<uv_fs_t>(), out, in, offset, length, &fsResultCallback<Type::SENDFILE>);
}
auto sendfileSync(FileHandle out, int64_t offset, size_t length) {
auto sendfileSync(FileHandle out, FileHandle in, int64_t offset, size_t length) {
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, file, offset, length, nullptr);
cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, in, offset, length, nullptr);
auto bw = req->result;
return std::make_pair(ErrorEvent{bw < 0 ? bw : 0}, FsEvent<Type::SENDFILE>{req->path, bw});
}
@ -501,11 +498,11 @@ public:
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::CHMOD>{req->path});
}
void fchmod(int mode) {
void fchmod(FileHandle file, int mode) {
cleanupAndInvoke(&uv_fs_fchmod, parent(), get<uv_fs_t>(), file, mode, &fsGenericCallback<Type::FCHMOD>);
}
auto fchmodSync(int mode) {
auto fchmodSync(FileHandle file, int mode) {
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_fchmod, parent(), req, file, mode, nullptr);
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FCHMOD>{req->path});
@ -521,11 +518,11 @@ public:
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::UTIME>{req->path});
}
void futime(Time atime, Time mtime) {
void futime(FileHandle file, Time atime, Time mtime) {
cleanupAndInvoke(&uv_fs_futime, parent(), get<uv_fs_t>(), file, atime.count(), mtime.count(), &fsGenericCallback<Type::FUTIME>);
}
auto futimeSync(Time atime, Time mtime) {
auto futimeSync(FileHandle file, Time atime, Time mtime) {
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_futime, parent(), req, file, atime.count(), mtime.count(), nullptr);
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FUTIME>{req->path});
@ -582,20 +579,15 @@ public:
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::CHOWN>{req->path});
}
void fchown(Uid uid, Gid gid) {
void fchown(FileHandle file, Uid uid, Gid gid) {
cleanupAndInvoke(&uv_fs_fchown, parent(), get<uv_fs_t>(), file, uid, gid, &fsGenericCallback<Type::FCHOWN>);
}
auto fchownSync(Uid uid, Gid gid) {
auto fchownSync(FileHandle file, Uid uid, Gid gid) {
auto req = get<uv_fs_t>();
cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid, nullptr);
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FCHOWN>{req->path});
}
operator FileHandle() const noexcept { return file; }
private:
uv_file file{BAD_FD};
};

View File

@ -32,8 +32,8 @@ enum class UVFsEvent: std::underlying_type_t<uv_fs_event> {
}
struct FsMonitorEvent: Event<FsMonitorEvent> {
FsMonitorEvent(std::string fPath, Flags<details::UVFsEvent> f)
struct FsEventEvent: Event<FsEventEvent> {
FsEventEvent(std::string fPath, Flags<details::UVFsEvent> f)
: flgs{std::move(f)}, relPath{std::move(fPath)}
{ }
@ -46,11 +46,11 @@ private:
};
class FsMonitor final: public Handle<FsMonitor, uv_fs_event_t> {
class FsEventHandle final: public Handle<FsEventHandle, uv_fs_event_t> {
static void startCallback(uv_fs_event_t *handle, const char *filename, int events, int status) {
FsMonitor &fsMonitor = *(static_cast<FsMonitor*>(handle->data));
if(status) { fsMonitor.publish(ErrorEvent{status}); }
else { fsMonitor.publish(FsMonitorEvent{filename, static_cast<std::underlying_type_t<Event>>(events)}); }
FsEventHandle &fsEvent = *(static_cast<FsEventHandle*>(handle->data));
if(status) { fsEvent.publish(ErrorEvent{status}); }
else { fsEvent.publish(FsEventEvent{filename, static_cast<std::underlying_type_t<Event>>(events)}); }
}
using Handle::Handle;
@ -60,8 +60,8 @@ public:
using Event = details::UVFsEventFlags;
template<typename... Args>
static std::shared_ptr<FsMonitor> create(Args&&... args) {
return std::shared_ptr<FsMonitor>{new FsMonitor{std::forward<Args>(args)...}};
static std::shared_ptr<FsEventHandle> create(Args&&... args) {
return std::shared_ptr<FsEventHandle>{new FsEventHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_fs_event_t>(&uv_fs_event_init); }

View File

@ -27,9 +27,9 @@ private:
};
class FsPoll final: public Handle<FsPoll, uv_fs_poll_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) {
FsPoll &fsPoll = *(static_cast<FsPoll*>(handle->data));
FsPollHandle &fsPoll = *(static_cast<FsPollHandle*>(handle->data));
if(status) { fsPoll.publish(ErrorEvent{status}); }
else { fsPoll.publish(FsPollEvent{ *prev, *curr }); }
}
@ -38,8 +38,8 @@ class FsPoll final: public Handle<FsPoll, uv_fs_poll_t> {
public:
template<typename... Args>
static std::shared_ptr<FsPoll> create(Args&&... args) {
return std::shared_ptr<FsPoll>{new FsPoll{std::forward<Args>(args)...}};
static std::shared_ptr<FsPollHandle> create(Args&&... args) {
return std::shared_ptr<FsPollHandle>{new FsPollHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_fs_poll_t>(&uv_fs_poll_init); }

View File

@ -15,9 +15,9 @@ namespace uvw {
struct IdleEvent: Event<IdleEvent> { };
class Idle final: public Handle<Idle, uv_idle_t> {
class IdleHandle final: public Handle<IdleHandle, uv_idle_t> {
static void startCallback(uv_idle_t *handle) {
Idle &idle = *(static_cast<Idle*>(handle->data));
IdleHandle &idle = *(static_cast<IdleHandle*>(handle->data));
idle.publish(IdleEvent{});
}
@ -25,8 +25,8 @@ class Idle final: public Handle<Idle, uv_idle_t> {
public:
template<typename... Args>
static std::shared_ptr<Idle> create(Args&&... args) {
return std::shared_ptr<Idle>{new Idle{std::forward<Args>(args)...}};
static std::shared_ptr<IdleHandle> create(Args&&... args) {
return std::shared_ptr<IdleHandle>{new IdleHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_idle_t>(&uv_idle_init); }

View File

@ -29,15 +29,15 @@ enum class UVHandleType: std::underlying_type_t<uv_handle_type> {
}
class Pipe final: public Stream<Pipe, uv_pipe_t> {
using Stream::Stream;
class PipeHandle final: public StreamHandle<PipeHandle, uv_pipe_t> {
using StreamHandle::StreamHandle;
public:
using Pending = details::UVHandleType;
template<typename... Args>
static std::shared_ptr<Pipe> create(Args&&... args) {
return std::shared_ptr<Pipe>{new Pipe{std::forward<Args>(args)...}};
static std::shared_ptr<PipeHandle> create(Args&&... args) {
return std::shared_ptr<PipeHandle>{new PipeHandle{std::forward<Args>(args)...}};
}
bool init(bool ipc = false) { return initialize<uv_pipe_t>(&uv_pipe_init, ipc); }
@ -51,11 +51,11 @@ public:
}
void connect(std::string name) {
auto listener = [ptr = shared_from_this()](const auto &event, details::Connect &) {
auto listener = [ptr = shared_from_this()](const auto &event, details::ConnectReq &) {
ptr->publish(event);
};
auto connect = loop().resource<details::Connect>();
auto connect = loop().resource<details::ConnectReq>();
connect->once<ErrorEvent>(listener);
connect->once<ConnectEvent>(listener);
connect->connect(&uv_pipe_connect, get<uv_pipe_t>(), name.data());

View File

@ -38,9 +38,9 @@ private:
};
class Poll final: public Handle<Poll, uv_poll_t> {
class PollHandle final: public Handle<PollHandle, uv_poll_t> {
static void startCallback(uv_poll_t *handle, int status, int events) {
Poll &poll = *(static_cast<Poll*>(handle->data));
PollHandle &poll = *(static_cast<PollHandle*>(handle->data));
if(status) { poll.publish(ErrorEvent{status}); }
else { poll.publish(PollEvent{static_cast<std::underlying_type_t<Event>>(events)}); }
}
@ -51,8 +51,8 @@ public:
using Event = details::UVPollEvent;
template<typename... Args>
static std::shared_ptr<Poll> create(Args&&... args) {
return std::shared_ptr<Poll>{new Poll{std::forward<Args>(args)...}};
static std::shared_ptr<PollHandle> create(Args&&... args) {
return std::shared_ptr<PollHandle>{new PollHandle{std::forward<Args>(args)...}};
}
bool init(int fd) { return initialize<uv_poll_t>(&uv_poll_init, fd); }

View File

@ -15,9 +15,9 @@ namespace uvw {
struct PrepareEvent: Event<PrepareEvent> { };
class Prepare final: public Handle<Prepare, uv_prepare_t> {
class PrepareHandle final: public Handle<PrepareHandle, uv_prepare_t> {
static void startCallback(uv_prepare_t *handle) {
Prepare &prepare = *(static_cast<Prepare*>(handle->data));
PrepareHandle &prepare = *(static_cast<PrepareHandle*>(handle->data));
prepare.publish(PrepareEvent{});
}
@ -25,8 +25,8 @@ class Prepare final: public Handle<Prepare, uv_prepare_t> {
public:
template<typename... Args>
static std::shared_ptr<Prepare> create(Args&&... args) {
return std::shared_ptr<Prepare>{new Prepare{std::forward<Args>(args)...}};
static std::shared_ptr<PrepareHandle> create(Args&&... args) {
return std::shared_ptr<PrepareHandle>{new PrepareHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_prepare_t>(&uv_prepare_init); }

View File

@ -22,9 +22,9 @@ private:
};
class Signal final: public Handle<Signal, uv_signal_t> {
class SignalHandle final: public Handle<SignalHandle, uv_signal_t> {
static void startCallback(uv_signal_t *handle, int signum) {
Signal &signal = *(static_cast<Signal*>(handle->data));
SignalHandle &signal = *(static_cast<SignalHandle*>(handle->data));
signal.publish(SignalEvent{signum});
}
@ -32,8 +32,8 @@ class Signal final: public Handle<Signal, uv_signal_t> {
public:
template<typename... Args>
static std::shared_ptr<Signal> create(Args&&... args) {
return std::shared_ptr<Signal>{new Signal{std::forward<Args>(args)...}};
static std::shared_ptr<SignalHandle> create(Args&&... args) {
return std::shared_ptr<SignalHandle>{new SignalHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_signal_t>(&uv_signal_init); }

View File

@ -39,13 +39,13 @@ private:
namespace details {
class Connect final: public Request<Connect, uv_connect_t> {
class ConnectReq final: public Request<ConnectReq, uv_connect_t> {
using Request::Request;
public:
template<typename... Args>
static std::shared_ptr<Connect> create(Args&&... args) {
return std::shared_ptr<Connect>{new Connect{std::forward<Args>(args)...}};
static std::shared_ptr<ConnectReq> create(Args&&... args) {
return std::shared_ptr<ConnectReq>{new ConnectReq{std::forward<Args>(args)...}};
}
template<typename F, typename... Args>
@ -55,13 +55,13 @@ public:
};
class Shutdown final: public Request<Shutdown, uv_shutdown_t> {
class ShutdownReq final: public Request<ShutdownReq, uv_shutdown_t> {
using Request::Request;
public:
template<typename... Args>
static std::shared_ptr<Shutdown> create(Args&&... args) {
return std::shared_ptr<Shutdown>{new Shutdown{std::forward<Args>(args)...}};
static std::shared_ptr<ShutdownReq> create(Args&&... args) {
return std::shared_ptr<ShutdownReq>{new ShutdownReq{std::forward<Args>(args)...}};
}
void shutdown(uv_stream_t *handle) {
@ -70,13 +70,13 @@ public:
};
class Write final: public Request<Write, uv_write_t> {
class WriteReq final: public Request<WriteReq, uv_write_t> {
using Request::Request;
public:
template<typename... Args>
static std::shared_ptr<Write> create(Args&&... args) {
return std::shared_ptr<Write>{new Write{std::forward<Args>(args)...}};
static std::shared_ptr<WriteReq> create(Args&&... args) {
return std::shared_ptr<WriteReq>{new WriteReq{std::forward<Args>(args)...}};
}
void write(uv_stream_t *handle, const uv_buf_t bufs[], unsigned int nbufs) {
@ -93,7 +93,7 @@ public:
template<typename T, typename U>
class Stream: public Handle<T, U> {
class StreamHandle: public Handle<T, U> {
static constexpr unsigned int DEFAULT_BACKLOG = 128;
static void readCallback(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) {
@ -124,11 +124,11 @@ protected:
public:
void shutdown() {
auto listener = [ptr = this->shared_from_this()](const auto &event, details::Shutdown &) {
auto listener = [ptr = this->shared_from_this()](const auto &event, details::ShutdownReq &) {
ptr->publish(event);
};
auto shutdown = this->loop().template resource<details::Shutdown>();
auto shutdown = this->loop().template resource<details::ShutdownReq>();
shutdown->template once<ErrorEvent>(listener);
shutdown->template once<ShutdownEvent>(listener);
shutdown->shutdown(this->template get<uv_stream_t>());
@ -158,11 +158,11 @@ public:
void write(std::unique_ptr<char[]> data, ssize_t len) {
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
auto listener = [ptr = this->shared_from_this()](const auto &event, details::Write &) {
auto listener = [ptr = this->shared_from_this()](const auto &event, details::WriteReq &) {
ptr->publish(event);
};
auto write = this->loop().template resource<details::Write>();
auto write = this->loop().template resource<details::WriteReq>();
write->template once<ErrorEvent>(listener);
write->template once<WriteEvent>(listener);
write->write(this->template get<uv_stream_t>(), bufs, 1);
@ -172,11 +172,11 @@ public:
void write(S &send, std::unique_ptr<char[]> data, ssize_t len) {
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
auto listener = [ptr = this->shared_from_this()](const auto &event, details::Write &) {
auto listener = [ptr = this->shared_from_this()](const auto &event, details::WriteReq &) {
ptr->publish(event);
};
auto write = this->loop().template resource<details::Write>();
auto write = this->loop().template resource<details::WriteReq>();
write->template once<ErrorEvent>(listener);
write->template once<WriteEvent>(listener);
write->write(this->template get<uv_stream_t>(), bufs, 1, send.template get<uv_stream_t>());

View File

@ -27,8 +27,8 @@ enum class UVTcpFlags: std::underlying_type_t<uv_tcp_flags> {
}
class Tcp final: public Stream<Tcp, uv_tcp_t> {
using Stream::Stream;
class TcpHandle final: public StreamHandle<TcpHandle, uv_tcp_t> {
using StreamHandle::StreamHandle;
public:
using Time = std::chrono::seconds;
@ -37,8 +37,8 @@ public:
using IPv6 = details::IPv6;
template<typename... Args>
static std::shared_ptr<Tcp> create(Args&&... args) {
return std::shared_ptr<Tcp>{new Tcp{std::forward<Args>(args)...}};
static std::shared_ptr<TcpHandle> create(Args&&... args) {
return std::shared_ptr<TcpHandle>{new TcpHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_tcp_t>(&uv_tcp_init); }
@ -91,11 +91,11 @@ public:
typename details::IpTraits<I>::Type addr;
details::IpTraits<I>::AddrFunc(ip.data(), port, &addr);
auto listener = [ptr = shared_from_this()](const auto &event, details::Connect &) {
auto listener = [ptr = shared_from_this()](const auto &event, details::ConnectReq &) {
ptr->publish(event);
};
auto connect = loop().resource<details::Connect>();
auto connect = loop().resource<details::ConnectReq>();
connect->once<ErrorEvent>(listener);
connect->once<ConnectEvent>(listener);
connect->connect(&uv_tcp_connect, get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr));

View File

@ -16,9 +16,9 @@ namespace uvw {
struct TimerEvent: Event<TimerEvent> { };
class Timer final: public Handle<Timer, uv_timer_t> {
class TimerHandle final: public Handle<TimerHandle, uv_timer_t> {
static void startCallback(uv_timer_t *handle) {
Timer &timer = *(static_cast<Timer*>(handle->data));
TimerHandle &timer = *(static_cast<TimerHandle*>(handle->data));
timer.publish(TimerEvent{});
}
@ -28,8 +28,8 @@ public:
using Time = std::chrono::milliseconds;
template<typename... Args>
static std::shared_ptr<Timer> create(Args&&... args) {
return std::shared_ptr<Timer>{new Timer{std::forward<Args>(args)...}};
static std::shared_ptr<TimerHandle> create(Args&&... args) {
return std::shared_ptr<TimerHandle>{new TimerHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_timer_t>(&uv_timer_init); }

View File

@ -26,19 +26,19 @@ enum class UVTTYModeT: std::underlying_type_t<uv_tty_mode_t> {
}
class TTY final: public Stream<TTY, uv_tty_t> {
explicit TTY(std::shared_ptr<Loop> ref,
class TTYHandle final: public StreamHandle<TTYHandle, uv_tty_t> {
explicit TTYHandle(std::shared_ptr<Loop> ref,
FileHandle desc,
bool readable)
: Stream{std::move(ref)}, fd{desc}, rw{readable}
: StreamHandle{std::move(ref)}, fd{desc}, rw{readable}
{ }
public:
using Mode = details::UVTTYModeT;
template<typename... Args>
static std::shared_ptr<TTY> create(Args&&... args) {
return std::shared_ptr<TTY>{new TTY{std::forward<Args>(args)...}};
static std::shared_ptr<TTYHandle> create(Args&&... args) {
return std::shared_ptr<TTYHandle>{new TTYHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_tty_t>(&uv_tty_init, fd, rw); }

View File

@ -69,7 +69,7 @@ public:
}
class Udp final: public Handle<Udp, uv_udp_t> {
class UdpHandle final: public Handle<UdpHandle, uv_udp_t> {
using Handle::Handle;
template<typename I>
@ -77,7 +77,7 @@ class Udp final: public Handle<Udp, uv_udp_t> {
typename details::IpTraits<I>::Type *aptr = reinterpret_cast<const typename details::IpTraits<I>::Type *>(addr);
int len = sizeof(*addr);
Udp &udp = *(static_cast<Udp*>(handle->data));
UdpHandle &udp = *(static_cast<UdpHandle*>(handle->data));
// data will be destroyed no matter of what the value of nread is
std::unique_ptr<const char[]> data{buf->base};
@ -102,8 +102,8 @@ public:
using IPv6 = details::IPv6;
template<typename... Args>
static std::shared_ptr<Udp> create(Args&&... args) {
return std::shared_ptr<Udp>{new Udp{std::forward<Args>(args)...}};
static std::shared_ptr<UdpHandle> create(Args&&... args) {
return std::shared_ptr<UdpHandle>{new UdpHandle{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_udp_t>(&uv_udp_init); }

View File

@ -16,9 +16,9 @@ namespace uvw {
struct WorkEvent: Event<WorkEvent> { };
class Work final: public Request<Work, uv_work_t> {
class WorkReq final: public Request<WorkReq, uv_work_t> {
static void workCallback(uv_work_t *req) {
static_cast<Work*>(req->data)->task();
static_cast<WorkReq*>(req->data)->task();
}
using Request::Request;
@ -27,8 +27,8 @@ public:
using Task = std::function<void(void)>;
template<typename... Args>
static std::shared_ptr<Work> create(Args&&... args) {
return std::shared_ptr<Work>{new Work{std::forward<Args>(args)...}};
static std::shared_ptr<WorkReq> create(Args&&... args) {
return std::shared_ptr<WorkReq>{new WorkReq{std::forward<Args>(args)...}};
}
void queue(Task t) {

View File

@ -6,25 +6,25 @@
void listen(uvw::Loop &loop) {
std::shared_ptr<uvw::Tcp> tcp = loop.resource<uvw::Tcp>();
std::shared_ptr<uvw::TcpHandle> tcp = loop.resource<uvw::TcpHandle>();
tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::Tcp &) {
tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TcpHandle &) {
std::cout << "error " << std::endl;
});
tcp->once<uvw::ListenEvent>([](const uvw::ListenEvent &event, uvw::Tcp &srv) mutable {
tcp->once<uvw::ListenEvent>([](const uvw::ListenEvent &event, uvw::TcpHandle &srv) mutable {
std::cout << "listen" << std::endl;
std::shared_ptr<uvw::Tcp> client = srv.loop().resource<uvw::Tcp>();
std::shared_ptr<uvw::TcpHandle> client = srv.loop().resource<uvw::TcpHandle>();
client->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::Tcp &) {
client->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TcpHandle &) {
std::cout << "error " << std::endl;
});
client->on<uvw::CloseEvent>([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::Tcp &) mutable {
client->on<uvw::CloseEvent>([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::TcpHandle &) mutable {
std::cout << "close" << std::endl;
uvw::Tcp &srv = *ptr;
uvw::TcpHandle &srv = *ptr;
srv.close();
});
@ -36,12 +36,12 @@ void listen(uvw::Loop &loop) {
uvw::Addr remote = client->peer();
std::cout << "remote: " << remote.ip << " " << remote.port << std::endl;
client->on<uvw::DataEvent>([](const uvw::DataEvent &event, uvw::Tcp &) {
client->on<uvw::DataEvent>([](const uvw::DataEvent &event, uvw::TcpHandle &) {
std::cout.write(event.data(), event.length()) << std::endl;
std::cout << "data length: " << event.length() << std::endl;
});
client->on<uvw::EndEvent>([](const uvw::EndEvent &, uvw::Tcp &client) {
client->on<uvw::EndEvent>([](const uvw::EndEvent &, uvw::TcpHandle &client) {
std::cout << "end" << std::endl;
int count = 0;
client.loop().walk([&count](uvw::BaseHandle &handle) { ++count; });
@ -52,7 +52,7 @@ void listen(uvw::Loop &loop) {
client->read();
});
tcp->once<uvw::CloseEvent>([](const uvw::CloseEvent &, uvw::Tcp &) mutable {
tcp->once<uvw::CloseEvent>([](const uvw::CloseEvent &, uvw::TcpHandle &) mutable {
std::cout << "close" << std::endl;
});
@ -62,18 +62,18 @@ void listen(uvw::Loop &loop) {
void conn(uvw::Loop &loop) {
auto tcp = loop.resource<uvw::Tcp>();
auto tcp = loop.resource<uvw::TcpHandle>();
tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::Tcp &) {
tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TcpHandle &) {
std::cout << "error " << std::endl;
});
tcp->once<uvw::WriteEvent>([](const uvw::WriteEvent &, uvw::Tcp &tcp) mutable {
tcp->once<uvw::WriteEvent>([](const uvw::WriteEvent &, uvw::TcpHandle &tcp) mutable {
std::cout << "write" << std::endl;
tcp.close();
});
tcp->once<uvw::ConnectEvent>([](const uvw::ConnectEvent &, uvw::Tcp &tcp) mutable {
tcp->once<uvw::ConnectEvent>([](const uvw::ConnectEvent &, uvw::TcpHandle &tcp) mutable {
std::cout << "connect" << std::endl;
auto dataTryWrite = std::unique_ptr<char[]>(new char[1]{ 'a' });
@ -84,7 +84,7 @@ void conn(uvw::Loop &loop) {
tcp.write(std::move(dataWrite), 2);
});
tcp->once<uvw::CloseEvent>([](const uvw::CloseEvent &, uvw::Tcp &) mutable {
tcp->once<uvw::CloseEvent>([](const uvw::CloseEvent &, uvw::TcpHandle &) mutable {
std::cout << "close" << std::endl;
});

View File

@ -14,8 +14,8 @@ TEST(Loop, Basics) {
def->walk([](uvw::BaseHandle &) { ASSERT_TRUE(false); });
auto loop = uvw::Loop::create();
auto handle = loop->resource<uvw::Prepare>();
auto req = loop->resource<uvw::Work>();
auto handle = loop->resource<uvw::PrepareHandle>();
auto req = loop->resource<uvw::WorkReq>();
auto err = [](uvw::ErrorEvent, auto &) { ASSERT_TRUE(false); };
@ -29,7 +29,7 @@ TEST(Loop, Basics) {
ASSERT_FALSE(loop->alive());
handle->start();
handle->on<uvw::PrepareEvent>([](uvw::PrepareEvent, uvw::Prepare &handle) {
handle->on<uvw::PrepareEvent>([](uvw::PrepareEvent, uvw::PrepareHandle &handle) {
handle.loop().walk([](uvw::BaseHandle &) {
static bool trigger = true;
ASSERT_TRUE(trigger);