From 464154d103339643a2f122cd49e360314ab046e2 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 10:10:25 +0200 Subject: [PATCH 01/10] clean up + TODO comments (thanks to saghul) --- src/uvw/fs.hpp | 18 ++++++++---------- src/uvw/stream.hpp | 25 ++++++------------------- src/uvw/udp.hpp | 18 ++++-------------- 3 files changed, 18 insertions(+), 43 deletions(-) diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index 9689e1e0..8d95db52 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -172,6 +172,12 @@ class Fs final: public Request { static void fsReadlinkCallback(uv_fs_t *req) { // TODO - uv_fs_readlink callback + /* +[10:00] <@saghul> in readlink's case, the result is in req->ptr +[10:00] <@saghul> it's a null terminated string +[10:00] <@saghul> but in that case the result will be 0 +[10:00] <@saghul> indicating success + */ } using Request::Request; @@ -220,17 +226,9 @@ public: return std::make_pair(ErrorEvent{err}, FsEvent{}); } - void write(FileHandle file, char *data, ssize_t len, int64_t offset) { - uv_buf_t bufs[] = { uv_buf_init(data, len) }; - invoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsWriteCallback); - } - void write(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { - write(file, data.get(), len, offset); - } - - auto writeSync(FileHandle file, char *data, ssize_t len, int64_t offset) { - // TODO uv_fs_write (sync (cb null)) + uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; + invoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsWriteCallback); } auto writeSync(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 8522b710..2d7b70dd 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -155,8 +155,8 @@ public: this->invoke(&uv_read_stop, this->template get()); } - void write(char *data, ssize_t len) { - uv_buf_t bufs[] = { uv_buf_init(data, len) }; + void write(std::unique_ptr 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 &) { ptr->publish(event); @@ -168,13 +168,9 @@ public: write->write(this->template get(), bufs, 1); } - void write(std::unique_ptr data, ssize_t len) { - write(data.get(), len); - } - template - void write(S &send, char *data, ssize_t len) { - uv_buf_t bufs[] = { uv_buf_init(data, len) }; + void write(S &send, std::unique_ptr 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 &) { ptr->publish(event); @@ -186,13 +182,8 @@ public: write->write(this->template get(), bufs, 1, send.template get()); } - template - void write(S &send, std::unique_ptr data, ssize_t len) { - write(send, data.get(), len); - } - - int tryWrite(char *data, ssize_t len) { - uv_buf_t bufs[] = { uv_buf_init(data, len) }; + 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); if(bw < 0) { @@ -203,10 +194,6 @@ public: return bw; } - int tryWrite(std::unique_ptr data, ssize_t len) { - return tryWrite(data.get(), len); - } - bool readable() const noexcept { return (uv_is_readable(this->template get()) == 1); } diff --git a/src/uvw/udp.hpp b/src/uvw/udp.hpp index 1a61e163..e0779a90 100644 --- a/src/uvw/udp.hpp +++ b/src/uvw/udp.hpp @@ -156,11 +156,11 @@ public: void ttl(int val) { invoke(&uv_udp_set_ttl, get(), val > 255 ? 255 : val); } template - void send(std::string ip, unsigned int port, char *data, ssize_t len) { + void send(std::string ip, unsigned int port, std::unique_ptr data, ssize_t len) { typename details::IpTraits::Type addr; details::IpTraits::AddrFunc(ip.data(), port, &addr); - uv_buf_t bufs[] = { uv_buf_init(data, len) }; + uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; auto listener = [ptr = shared_from_this()](const auto &event, details::Send &) { ptr->publish(event); @@ -173,16 +173,11 @@ public: } template - void send(std::string ip, unsigned int port, std::unique_ptr data, ssize_t len) { - send(ip, port, data.get(), len); - } - - template - int trySend(std::string ip, unsigned int port, char *data, ssize_t len) { + int trySend(std::string ip, unsigned int port, std::unique_ptr data, ssize_t len) { typename details::IpTraits::Type addr; details::IpTraits::AddrFunc(ip.data(), port, &addr); - uv_buf_t bufs[] = { uv_buf_init(data, len) }; + uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; auto bw = uv_udp_try_send(get(), bufs, 1, reinterpret_cast(&addr)); if(bw < 0) { @@ -193,11 +188,6 @@ public: return bw; } - template - int trySend(std::string ip, unsigned int port, std::unique_ptr data, ssize_t len) { - return trySend(ip, port, data.get(), len); - } - template void recv() { invoke(&uv_udp_recv_start, get(), &allocCallback, &recvCallback); From e322a4a3de53afae69ff1ed5068ccafb0d48bdc0 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 11:09:41 +0200 Subject: [PATCH 02/10] WIP: Fs refactoring --- src/uvw/fs.hpp | 114 +++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 51 deletions(-) diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index 8d95db52..4de70211 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -182,6 +182,18 @@ class Fs final: public Request { using Request::Request; + template + auto cleanupAndInvoke(Args&&... args) { + uv_fs_req_cleanup(get()); + return invoke(std::forward(args)...); + } + + template + auto cleanupAndExec(F &&f, Args&&... args) { + uv_fs_req_cleanup(get()); + return std::forward(f)(std::forward(args)...); + } + public: using Time = std::chrono::seconds; using Type = details::UVFsType; @@ -198,37 +210,37 @@ public: } void close(FileHandle file) { - invoke(&uv_fs_close, parent(), get(), file, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_close, parent(), get(), file, &fsGenericCallback); } auto closeSync(FileHandle file) { - auto err = uv_fs_close(parent(), get(), file, nullptr); + auto err = cleanupAndExec(&uv_fs_close, parent(), get(), file, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void open(std::string path, int flags, int mode) { - invoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsGenericCallback); } auto openSync(std::string path, int flags, int mode) { - auto err = uv_fs_open(parent(), get(), path.data(), flags, mode, nullptr); + auto err = cleanupAndExec(&uv_fs_open, parent(), get(), path.data(), flags, mode, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } // TODO uv_fs_read (sync (cb null)/async) void unlink(std::string path) { - invoke(&uv_fs_unlink, parent(), get(), path.data(), &fsGenericCallback); + cleanupAndInvoke(&uv_fs_unlink, parent(), get(), path.data(), &fsGenericCallback); } auto unlinkSync(std::string path) { - auto err = uv_fs_unlink(parent(), get(), path.data(), nullptr); + auto err = cleanupAndExec(&uv_fs_unlink, parent(), get(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void write(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; - invoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsWriteCallback); + cleanupAndInvoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsWriteCallback); } auto writeSync(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { @@ -236,7 +248,7 @@ public: } void mkdir(std::string path, int mode) { - invoke(&uv_fs_mkdir, parent(), get(), path.data(), mode, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_mkdir, parent(), get(), path.data(), mode, &fsGenericCallback); } auto mkdirSync(std::string path, int mode) { @@ -245,29 +257,29 @@ public: } void mkdtemp(std::string tpl) { - invoke(&uv_fs_mkdtemp, parent(), get(), tpl.data(), &fsGenericCallback); + cleanupAndInvoke(&uv_fs_mkdtemp, parent(), get(), tpl.data(), &fsGenericCallback); } auto mkdtempSync(std::string tpl) { - auto err = uv_fs_mkdtemp(parent(), get(), tpl.data(), nullptr); + auto err = cleanupAndExec(&uv_fs_mkdtemp, parent(), get(), tpl.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void rmdir(std::string path) { - invoke(&uv_fs_rmdir, parent(), get(), path.data(), &fsGenericCallback); + cleanupAndInvoke(&uv_fs_rmdir, parent(), get(), path.data(), &fsGenericCallback); } auto rmdirSync(std::string path) { - auto err = uv_fs_rmdir(parent(), get(), path.data(), nullptr); + auto err = cleanupAndExec(&uv_fs_rmdir, parent(), get(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void scandir(std::string path, int flags) { - invoke(&uv_fs_scandir, parent(), get(), path.data(), flags, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_scandir, parent(), get(), path.data(), flags, &fsGenericCallback); } auto scandirSync(std::string path, int flags) { - auto err = uv_fs_scandir(parent(), get(), path.data(), flags, nullptr); + auto err = cleanupAndExec(&uv_fs_scandir, parent(), get(), path.data(), flags, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -286,170 +298,170 @@ public: } void stat(std::string path) { - invoke(&uv_fs_stat, parent(), get(), path.data(), &fsStatCallback); + cleanupAndInvoke(&uv_fs_stat, parent(), get(), path.data(), &fsStatCallback); } auto statSync(std::string path) { - auto err = uv_fs_stat(parent(), get(), path.data(), nullptr); + auto err = cleanupAndExec(&uv_fs_stat, parent(), get(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{get()->statbuf}); } void fstat(FileHandle file) { - invoke(&uv_fs_fstat, parent(), get(), file, &fsStatCallback); + cleanupAndInvoke(&uv_fs_fstat, parent(), get(), file, &fsStatCallback); } auto fstatSync(FileHandle file) { - auto err = uv_fs_fstat(parent(), get(), file, nullptr); + auto err = cleanupAndExec(&uv_fs_fstat, parent(), get(), file, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{get()->statbuf}); } void lstat(std::string path) { - invoke(&uv_fs_lstat, parent(), get(), path.data(), &fsStatCallback); + cleanupAndInvoke(&uv_fs_lstat, parent(), get(), path.data(), &fsStatCallback); } auto lstatSync(std::string path) { - auto err = uv_fs_lstat(parent(), get(), path.data(), nullptr); + auto err = cleanupAndExec(&uv_fs_lstat, parent(), get(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{get()->statbuf}); } void rename(std::string old, std::string path) { - invoke(&uv_fs_rename, parent(), get(), old.data(), path.data(), &fsGenericCallback); + cleanupAndInvoke(&uv_fs_rename, parent(), get(), old.data(), path.data(), &fsGenericCallback); } auto renameSync(std::string old, std::string path) { - auto err = uv_fs_rename(parent(), get(), old.data(), path.data(), nullptr); + auto err = cleanupAndExec(&uv_fs_rename, parent(), get(), old.data(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void fsync(FileHandle file) { - invoke(&uv_fs_fsync, parent(), get(), file, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_fsync, parent(), get(), file, &fsGenericCallback); } auto fsyncSync(FileHandle file) { - auto err = uv_fs_fsync(parent(), get(), file, nullptr); + auto err = cleanupAndExec(&uv_fs_fsync, parent(), get(), file, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void fdatasync(FileHandle file) { - invoke(&uv_fs_fdatasync, parent(), get(), file, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_fdatasync, parent(), get(), file, &fsGenericCallback); } auto fdatasyncSync(FileHandle file) { - auto err = uv_fs_fdatasync(parent(), get(), file, nullptr); + auto err = cleanupAndExec(&uv_fs_fdatasync, parent(), get(), file, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void ftruncate(FileHandle file, int64_t offset) { - invoke(&uv_fs_ftruncate, parent(), get(), file, offset, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_ftruncate, parent(), get(), file, offset, &fsGenericCallback); } auto ftruncateSync(FileHandle file, int64_t offset) { - auto err = uv_fs_ftruncate(parent(), get(), file, offset, nullptr); + auto err = cleanupAndExec(&uv_fs_ftruncate, parent(), get(), file, offset, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void sendfile(FileHandle out, FileHandle in, int64_t offset, size_t length) { - invoke(&uv_fs_sendfile, parent(), get(), out, in, offset, length, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_sendfile, parent(), get(), out, in, offset, length, &fsGenericCallback); } auto sendfileSync(FileHandle out, FileHandle in, int64_t offset, size_t length) { - auto err = uv_fs_sendfile(parent(), get(), out, in, offset, length, nullptr); + auto err = cleanupAndExec(&uv_fs_sendfile, parent(), get(), out, in, offset, length, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void access(std::string path, int mode) { - invoke(&uv_fs_access, parent(), get(), path.data(), mode, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_access, parent(), get(), path.data(), mode, &fsGenericCallback); } auto accessSync(std::string path, int mode) { - auto err = uv_fs_access(parent(), get(), path.data(), mode, nullptr); + auto err = cleanupAndExec(&uv_fs_access, parent(), get(), path.data(), mode, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void chmod(std::string path, int mode) { - invoke(&uv_fs_chmod, parent(), get(), path.data(), mode, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_chmod, parent(), get(), path.data(), mode, &fsGenericCallback); } auto chmodSync(std::string path, int mode) { - auto err = uv_fs_chmod(parent(), get(), path.data(), mode, nullptr); + auto err = cleanupAndExec(&uv_fs_chmod, parent(), get(), path.data(), mode, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void fchmod(FileHandle file, int mode) { - invoke(&uv_fs_fchmod, parent(), get(), file, mode, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_fchmod, parent(), get(), file, mode, &fsGenericCallback); } auto fchmodSync(FileHandle file, int mode) { - auto err = uv_fs_fchmod(parent(), get(), file, mode, nullptr); + auto err = cleanupAndExec(&uv_fs_fchmod, parent(), get(), file, mode, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void utime(std::string path, Time atime, Time mtime) { - invoke(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), &fsGenericCallback); + cleanupAndInvoke(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), &fsGenericCallback); } auto utimeSync(std::string path, Time atime, Time mtime) { - auto err = uv_fs_utime(parent(), get(), path.data(), atime.count(), mtime.count(), nullptr); + auto err = cleanupAndExec(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void futime(FileHandle file, Time atime, Time mtime) { - invoke(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), &fsGenericCallback); + cleanupAndInvoke(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), &fsGenericCallback); } auto futimeSync(FileHandle file, Time atime, Time mtime) { - auto err = uv_fs_futime(parent(), get(), file, atime.count(), mtime.count(), nullptr); + auto err = cleanupAndExec(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void link(std::string old, std::string path) { - invoke(&uv_fs_link, parent(), get(), old.data(), path.data(), &fsGenericCallback); + cleanupAndInvoke(&uv_fs_link, parent(), get(), old.data(), path.data(), &fsGenericCallback); } auto linkSync(std::string old, std::string path) { - auto err = uv_fs_link(parent(), get(), old.data(), path.data(), nullptr); + auto err = cleanupAndExec(&uv_fs_link, parent(), get(), old.data(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void symlink(std::string old, std::string path, int flags) { - invoke(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, &fsGenericCallback); } auto symlinkSync(std::string old, std::string path, int flags) { - auto err = uv_fs_symlink(parent(), get(), old.data(), path.data(), flags, nullptr); + auto err = cleanupAndExec(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void readlink(std::string path) { - invoke(&uv_fs_readlink, parent(), get(), path.data(), &fsReadlinkCallback); + cleanupAndInvoke(&uv_fs_readlink, parent(), get(), path.data(), &fsReadlinkCallback); } // TODO uv_fs_readlink (sync (cb null)) void realpath(std::string path) { - invoke(&uv_fs_realpath, parent(), get(), path.data(), &fsGenericCallback); + cleanupAndInvoke(&uv_fs_realpath, parent(), get(), path.data(), &fsGenericCallback); } auto realpathSync(std::string path) { - auto err = uv_fs_realpath(parent(), get(), path.data(), nullptr); + auto err = cleanupAndExec(&uv_fs_realpath, parent(), get(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void chown(std::string path, Uid uid, Gid gid) { - invoke(&uv_fs_chown, parent(), get(), path.data(), uid, gid, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_chown, parent(), get(), path.data(), uid, gid, &fsGenericCallback); } auto chownSync(std::string path, Uid uid, Gid gid) { - auto err = uv_fs_chown(parent(), get(), path.data(), uid, gid, nullptr); + auto err = cleanupAndExec(&uv_fs_chown, parent(), get(), path.data(), uid, gid, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } void fchown(FileHandle file, Uid uid, Gid gid) { - invoke(&uv_fs_fchown, parent(), get(), file, uid, gid, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_fchown, parent(), get(), file, uid, gid, &fsGenericCallback); } auto fchownSync(FileHandle file, Uid uid, Gid gid) { - auto err = uv_fs_fchown(parent(), get(), file, uid, gid, nullptr); + auto err = cleanupAndExec(&uv_fs_fchown, parent(), get(), file, uid, gid, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } }; From a5ba0c3c606df801bb498060053ec46bdbb0c71b Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 13:09:44 +0200 Subject: [PATCH 03/10] WIP: Fs::[readlink/readlinkSync] --- src/uvw/fs.hpp | 57 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index 4de70211..cbd70eb5 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -123,6 +123,22 @@ private: }; +template<> +struct TypedEvent + : Event> +{ + using Type = details::UVFsType; + static constexpr details::UVFsType value = details::UVFsType::READLINK; + + explicit TypedEvent(const char *d) noexcept: dt{d} { } + + const char * data() const noexcept { return dt; } + +private: + const char *dt; +}; + + template using FsEvent = TypedEvent; @@ -171,13 +187,19 @@ class Fs final: public Request { } static void fsReadlinkCallback(uv_fs_t *req) { - // TODO - uv_fs_readlink callback - /* -[10:00] <@saghul> in readlink's case, the result is in req->ptr -[10:00] <@saghul> it's a null terminated string -[10:00] <@saghul> but in that case the result will be 0 -[10:00] <@saghul> indicating success - */ + Fs &fs = *(static_cast(req->data)); + + auto ptr = fs.shared_from_this(); + (void)ptr; + + fs.reset(); + + if(req->result) { + int err = req->result; + fs.publish(ErrorEvent{err}); + } else { + fs.publish(FsEvent{static_cast(req->ptr)}); + } } using Request::Request; @@ -302,8 +324,9 @@ public: } auto statSync(std::string path) { - auto err = cleanupAndExec(&uv_fs_stat, parent(), get(), path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{get()->statbuf}); + auto req = get(); + auto err = cleanupAndExec(&uv_fs_stat, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->statbuf}); } void fstat(FileHandle file) { @@ -311,8 +334,9 @@ public: } auto fstatSync(FileHandle file) { - auto err = cleanupAndExec(&uv_fs_fstat, parent(), get(), file, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{get()->statbuf}); + auto req = get(); + auto err = cleanupAndExec(&uv_fs_fstat, parent(), req, file, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->statbuf}); } void lstat(std::string path) { @@ -320,8 +344,9 @@ public: } auto lstatSync(std::string path) { - auto err = cleanupAndExec(&uv_fs_lstat, parent(), get(), path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{get()->statbuf}); + auto req = get(); + auto err = cleanupAndExec(&uv_fs_lstat, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->statbuf}); } void rename(std::string old, std::string path) { @@ -436,7 +461,11 @@ public: cleanupAndInvoke(&uv_fs_readlink, parent(), get(), path.data(), &fsReadlinkCallback); } - // TODO uv_fs_readlink (sync (cb null)) + auto readlinkSync(std::string path) { + auto req = get(); + auto err = cleanupAndExec(&uv_fs_readlink, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{static_cast(req->ptr)}); + } void realpath(std::string path) { cleanupAndInvoke(&uv_fs_realpath, parent(), get(), path.data(), &fsGenericCallback); From ffd49ff0b35520bc781c24aeb94d4c48920381d9 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 15:14:14 +0200 Subject: [PATCH 04/10] WIP: Fs refactoring --- src/uvw/fs.hpp | 52 ++++++++++++++++++++++---------------------- src/uvw/handle.hpp | 7 ++++++ src/uvw/request.hpp | 32 ++++++++++++++------------- src/uvw/resource.hpp | 7 ------ src/uvw/stream.hpp | 8 +++---- src/uvw/udp.hpp | 2 +- src/uvw/work.hpp | 2 +- 7 files changed, 56 insertions(+), 54 deletions(-) diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index cbd70eb5..bdec013b 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -211,7 +211,7 @@ class Fs final: public Request { } template - auto cleanupAndExec(F &&f, Args&&... args) { + auto cleanupAndInvokeSync(F &&f, Args&&... args) { uv_fs_req_cleanup(get()); return std::forward(f)(std::forward(args)...); } @@ -236,7 +236,7 @@ public: } auto closeSync(FileHandle file) { - auto err = cleanupAndExec(&uv_fs_close, parent(), get(), file, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_close, parent(), get(), file, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -245,7 +245,7 @@ public: } auto openSync(std::string path, int flags, int mode) { - auto err = cleanupAndExec(&uv_fs_open, parent(), get(), path.data(), flags, mode, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_open, parent(), get(), path.data(), flags, mode, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -256,7 +256,7 @@ public: } auto unlinkSync(std::string path) { - auto err = cleanupAndExec(&uv_fs_unlink, parent(), get(), path.data(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_unlink, parent(), get(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -283,7 +283,7 @@ public: } auto mkdtempSync(std::string tpl) { - auto err = cleanupAndExec(&uv_fs_mkdtemp, parent(), get(), tpl.data(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), get(), tpl.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -292,7 +292,7 @@ public: } auto rmdirSync(std::string path) { - auto err = cleanupAndExec(&uv_fs_rmdir, parent(), get(), path.data(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_rmdir, parent(), get(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -301,7 +301,7 @@ public: } auto scandirSync(std::string path, int flags) { - auto err = cleanupAndExec(&uv_fs_scandir, parent(), get(), path.data(), flags, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_scandir, parent(), get(), path.data(), flags, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -325,7 +325,7 @@ public: auto statSync(std::string path) { auto req = get(); - auto err = cleanupAndExec(&uv_fs_stat, parent(), req, path.data(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_stat, parent(), req, path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{req->statbuf}); } @@ -335,7 +335,7 @@ public: auto fstatSync(FileHandle file) { auto req = get(); - auto err = cleanupAndExec(&uv_fs_fstat, parent(), req, file, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{req->statbuf}); } @@ -345,7 +345,7 @@ public: auto lstatSync(std::string path) { auto req = get(); - auto err = cleanupAndExec(&uv_fs_lstat, parent(), req, path.data(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_lstat, parent(), req, path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{req->statbuf}); } @@ -354,7 +354,7 @@ public: } auto renameSync(std::string old, std::string path) { - auto err = cleanupAndExec(&uv_fs_rename, parent(), get(), old.data(), path.data(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_rename, parent(), get(), old.data(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -363,7 +363,7 @@ public: } auto fsyncSync(FileHandle file) { - auto err = cleanupAndExec(&uv_fs_fsync, parent(), get(), file, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_fsync, parent(), get(), file, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -372,7 +372,7 @@ public: } auto fdatasyncSync(FileHandle file) { - auto err = cleanupAndExec(&uv_fs_fdatasync, parent(), get(), file, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), get(), file, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -381,7 +381,7 @@ public: } auto ftruncateSync(FileHandle file, int64_t offset) { - auto err = cleanupAndExec(&uv_fs_ftruncate, parent(), get(), file, offset, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), get(), file, offset, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -390,7 +390,7 @@ public: } auto sendfileSync(FileHandle out, FileHandle in, int64_t offset, size_t length) { - auto err = cleanupAndExec(&uv_fs_sendfile, parent(), get(), out, in, offset, length, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_sendfile, parent(), get(), out, in, offset, length, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -399,7 +399,7 @@ public: } auto accessSync(std::string path, int mode) { - auto err = cleanupAndExec(&uv_fs_access, parent(), get(), path.data(), mode, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_access, parent(), get(), path.data(), mode, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -408,7 +408,7 @@ public: } auto chmodSync(std::string path, int mode) { - auto err = cleanupAndExec(&uv_fs_chmod, parent(), get(), path.data(), mode, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_chmod, parent(), get(), path.data(), mode, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -417,7 +417,7 @@ public: } auto fchmodSync(FileHandle file, int mode) { - auto err = cleanupAndExec(&uv_fs_fchmod, parent(), get(), file, mode, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_fchmod, parent(), get(), file, mode, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -426,7 +426,7 @@ public: } auto utimeSync(std::string path, Time atime, Time mtime) { - auto err = cleanupAndExec(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -435,7 +435,7 @@ public: } auto futimeSync(FileHandle file, Time atime, Time mtime) { - auto err = cleanupAndExec(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -444,7 +444,7 @@ public: } auto linkSync(std::string old, std::string path) { - auto err = cleanupAndExec(&uv_fs_link, parent(), get(), old.data(), path.data(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_link, parent(), get(), old.data(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -453,7 +453,7 @@ public: } auto symlinkSync(std::string old, std::string path, int flags) { - auto err = cleanupAndExec(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -463,7 +463,7 @@ public: auto readlinkSync(std::string path) { auto req = get(); - auto err = cleanupAndExec(&uv_fs_readlink, parent(), req, path.data(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_readlink, parent(), req, path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{static_cast(req->ptr)}); } @@ -472,7 +472,7 @@ public: } auto realpathSync(std::string path) { - auto err = cleanupAndExec(&uv_fs_realpath, parent(), get(), path.data(), nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_realpath, parent(), get(), path.data(), nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -481,7 +481,7 @@ public: } auto chownSync(std::string path, Uid uid, Gid gid) { - auto err = cleanupAndExec(&uv_fs_chown, parent(), get(), path.data(), uid, gid, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_chown, parent(), get(), path.data(), uid, gid, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } @@ -490,7 +490,7 @@ public: } auto fchownSync(FileHandle file, Uid uid, Gid gid) { - auto err = cleanupAndExec(&uv_fs_fchown, parent(), get(), file, uid, gid, nullptr); + auto err = cleanupAndInvokeSync(&uv_fs_fchown, parent(), get(), file, uid, gid, nullptr); return std::make_pair(ErrorEvent{err}, FsEvent{}); } }; diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index 2e54f226..48e4d3de 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -63,6 +63,13 @@ protected: return this->self(); } + template + auto invoke(F &&f, Args&&... args) { + auto err = std::forward(f)(std::forward(args)...); + if(err) { Emitter::publish(ErrorEvent{err}); } + return err; + } + public: bool active() const noexcept override { return !(uv_is_active(this->template get()) == 0); diff --git a/src/uvw/request.hpp b/src/uvw/request.hpp index 11569f52..d8891158 100644 --- a/src/uvw/request.hpp +++ b/src/uvw/request.hpp @@ -13,8 +13,11 @@ namespace uvw { template class Request: public Resource { +protected: + using Resource::Resource; + template - static void execCallback(R *req, int status) { + static void defaultCallback(R *req, int status) { T &res = *(static_cast(req->data)); auto ptr = res.shared_from_this(); @@ -29,27 +32,26 @@ class Request: public Resource { } } -protected: - using Resource::Resource; - - template - auto exec(F &&f, Args&&... args) - -> std::enable_if_t))>>::value, int> { - auto ret = this->invoke(std::forward(f), std::forward(args)..., &execCallback); - if(0 == ret) { this->leak(); } - return ret; + template + auto invoke(F &&f, Args&&... args) + -> std::enable_if_t>::value, int> { + auto err = std::forward(f)(std::forward(args)...); + if(err) { Emitter::publish(ErrorEvent{err}); } + else { this->leak(); } + return err; } - template - auto exec(F &&f, Args&&... args) - -> std::enable_if_t))>>::value> { - std::forward(f)(std::forward(args)..., &execCallback); + template + auto invoke(F &&f, Args&&... args) + -> std::enable_if_t>::value> { + std::forward(f)(std::forward(args)...); this->leak(); } public: void cancel() { - this->invoke(&uv_cancel, this->template get()); + auto err = uv_cancel(this->template get()); + if(err) { Emitter::publish(ErrorEvent{err}); } } std::size_t size() const noexcept { diff --git a/src/uvw/resource.hpp b/src/uvw/resource.hpp index d92ad1ee..c614cb4e 100644 --- a/src/uvw/resource.hpp +++ b/src/uvw/resource.hpp @@ -35,13 +35,6 @@ protected: template auto get() const noexcept { return reinterpret_cast(&resource); } - template - auto invoke(F &&f, Args&&... args) { - auto err = std::forward(f)(std::forward(args)...); - if(err) { Emitter::publish(ErrorEvent{err}); } - return err; - } - public: Resource(const Resource &) = delete; Resource(Resource &&) = delete; diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 2d7b70dd..bd26d1ae 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -50,7 +50,7 @@ public: template void connect(F &&f, Args... args) { - exec(std::forward(f), get(), std::forward(args)...); + invoke(std::forward(f), get(), std::forward(args)..., &defaultCallback); } }; @@ -65,7 +65,7 @@ public: } void shutdown(uv_stream_t *handle) { - exec(&uv_shutdown, get(), handle); + invoke(&uv_shutdown, get(), handle, &defaultCallback); } }; @@ -80,11 +80,11 @@ public: } void write(uv_stream_t *handle, const uv_buf_t bufs[], unsigned int nbufs) { - exec(&uv_write, get(), handle, bufs, nbufs); + invoke(&uv_write, get(), handle, bufs, nbufs, &defaultCallback); } void write(uv_stream_t *handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t *send) { - exec(&uv_write2, get(), handle, bufs, nbufs, send); + invoke(&uv_write2, get(), handle, bufs, nbufs, send, &defaultCallback); } }; diff --git a/src/uvw/udp.hpp b/src/uvw/udp.hpp index e0779a90..c279efaa 100644 --- a/src/uvw/udp.hpp +++ b/src/uvw/udp.hpp @@ -61,7 +61,7 @@ public: } void send(uv_udp_t *handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr) { - exec(&uv_udp_send, get(), handle, bufs, nbufs, addr); + invoke(&uv_udp_send, get(), handle, bufs, nbufs, addr, &defaultCallback); } }; diff --git a/src/uvw/work.hpp b/src/uvw/work.hpp index 93324682..6450378b 100644 --- a/src/uvw/work.hpp +++ b/src/uvw/work.hpp @@ -32,7 +32,7 @@ public: } void queue(Task t) { - if(0 == exec(&uv_queue_work, parent(), get(), &workCallback)) { + if(0 == invoke(&uv_queue_work, parent(), get(), &workCallback, &defaultCallback)) { task = std::move(t); } } From 762565e95be40df52fa2d11114bb2742531cedd3 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 16:21:58 +0200 Subject: [PATCH 05/10] WIP: Fs, write is ready and added path to fs events --- src/uvw/fs.hpp | 201 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 131 insertions(+), 70 deletions(-) diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index bdec013b..c8f325d8 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -70,8 +70,31 @@ template struct TypedEvent : Event> { - using Type = details::UVFsType; - static constexpr details::UVFsType value = e; + TypedEvent(const char *p) noexcept + : rPath{p} + { } + + const char * path() const noexcept { return rPath; } + +private: + const char *rPath; +}; + + +template<> +struct TypedEvent + : Event> +{ + TypedEvent(const char *p, ssize_t s) noexcept + : rPath{p}, sz{s} + { } + + const char * path() const noexcept { return rPath; } + ssize_t amount() const noexcept { return sz; } + +private: + const char *rPath; + const ssize_t sz; }; @@ -79,14 +102,15 @@ template<> struct TypedEvent : Event> { - using Type = details::UVFsType; - static constexpr details::UVFsType value = details::UVFsType::STAT; - - TypedEvent(const Stat &s): fsStat{s} { } + TypedEvent(const char *p, const Stat &s) noexcept + : rPath{p}, fsStat{s} + { } + const char * path() const noexcept { return rPath; } const Stat & stat() const noexcept { return fsStat; } private: + const char *rPath; Stat fsStat; }; @@ -95,14 +119,15 @@ template<> struct TypedEvent : Event> { - using Type = details::UVFsType; - static constexpr details::UVFsType value = details::UVFsType::FSTAT; - - TypedEvent(const Stat &s): fsStat{s} { } + TypedEvent(const char *p, const Stat &s) noexcept + : rPath{p}, fsStat{s} + { } + const char * path() const noexcept { return rPath; } const Stat & stat() const noexcept { return fsStat; } private: + const char *rPath; Stat fsStat; }; @@ -111,14 +136,15 @@ template<> struct TypedEvent : Event> { - using Type = details::UVFsType; - static constexpr details::UVFsType value = details::UVFsType::LSTAT; - - TypedEvent(const Stat &s): fsStat{s} { } + TypedEvent(const char *p, const Stat &s) noexcept + : rPath{p}, fsStat{s} + { } + const char * path() const noexcept { return rPath; } const Stat & stat() const noexcept { return fsStat; } private: + const char *rPath; Stat fsStat; }; @@ -127,14 +153,15 @@ template<> struct TypedEvent : Event> { - using Type = details::UVFsType; - static constexpr details::UVFsType value = details::UVFsType::READLINK; - - explicit TypedEvent(const char *d) noexcept: dt{d} { } + explicit TypedEvent(const char *p, const char *d) noexcept + : rPath{p}, dt{d} + { } + const char * path() const noexcept { return rPath; } const char * data() const noexcept { return dt; } private: + const char *rPath; const char *dt; }; @@ -157,7 +184,7 @@ class Fs final: public Request { int err = req->result; fs.publish(ErrorEvent{err}); } else { - fs.publish(FsEvent{}); + fs.publish(FsEvent{req->path}); } } @@ -166,7 +193,19 @@ class Fs final: public Request { } static void fsWriteCallback(uv_fs_t *req) { - // TODO - uv_fs_write callback + Fs &fs = *(static_cast(req->data)); + + auto ptr = fs.shared_from_this(); + (void)ptr; + + fs.reset(); + + if(req->result) { + int err = req->result; + fs.publish(ErrorEvent{err}); + } else { + fs.publish(FsEvent{req->path, req->result}); + } } template @@ -182,7 +221,7 @@ class Fs final: public Request { int err = req->result; fs.publish(ErrorEvent{err}); } else { - fs.publish(FsEvent{req->statbuf}); + fs.publish(FsEvent{req->path, req->statbuf}); } } @@ -198,7 +237,7 @@ class Fs final: public Request { int err = req->result; fs.publish(ErrorEvent{err}); } else { - fs.publish(FsEvent{static_cast(req->ptr)}); + fs.publish(FsEvent{req->path, static_cast(req->ptr)}); } } @@ -236,8 +275,9 @@ public: } auto closeSync(FileHandle file) { - auto err = cleanupAndInvokeSync(&uv_fs_close, parent(), get(), file, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_close, parent(), req, file, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void open(std::string path, int flags, int mode) { @@ -245,8 +285,9 @@ public: } auto openSync(std::string path, int flags, int mode) { - auto err = cleanupAndInvokeSync(&uv_fs_open, parent(), get(), path.data(), flags, mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_open, parent(), req, path.data(), flags, mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } // TODO uv_fs_read (sync (cb null)/async) @@ -256,8 +297,9 @@ public: } auto unlinkSync(std::string path) { - auto err = cleanupAndInvokeSync(&uv_fs_unlink, parent(), get(), path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_unlink, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void write(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { @@ -274,8 +316,9 @@ public: } auto mkdirSync(std::string path, int mode) { - auto err = uv_fs_mkdir(parent(), get(), path.data(), mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = uv_fs_mkdir(parent(), req, path.data(), mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void mkdtemp(std::string tpl) { @@ -283,8 +326,9 @@ public: } auto mkdtempSync(std::string tpl) { - auto err = cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), get(), tpl.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), req, tpl.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void rmdir(std::string path) { @@ -292,8 +336,9 @@ public: } auto rmdirSync(std::string path) { - auto err = cleanupAndInvokeSync(&uv_fs_rmdir, parent(), get(), path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_rmdir, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void scandir(std::string path, int flags) { @@ -301,8 +346,9 @@ public: } auto scandirSync(std::string path, int flags) { - auto err = cleanupAndInvokeSync(&uv_fs_scandir, parent(), get(), path.data(), flags, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_scandir, parent(), req, path.data(), flags, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } std::pair scandirNext() { @@ -326,7 +372,7 @@ public: auto statSync(std::string path) { auto req = get(); auto err = cleanupAndInvokeSync(&uv_fs_stat, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->statbuf}); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->statbuf}); } void fstat(FileHandle file) { @@ -336,7 +382,7 @@ public: auto fstatSync(FileHandle file) { auto req = get(); auto err = cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->statbuf}); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->statbuf}); } void lstat(std::string path) { @@ -346,7 +392,7 @@ public: auto lstatSync(std::string path) { auto req = get(); auto err = cleanupAndInvokeSync(&uv_fs_lstat, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->statbuf}); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->statbuf}); } void rename(std::string old, std::string path) { @@ -354,8 +400,9 @@ public: } auto renameSync(std::string old, std::string path) { - auto err = cleanupAndInvokeSync(&uv_fs_rename, parent(), get(), old.data(), path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_rename, parent(), req, old.data(), path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void fsync(FileHandle file) { @@ -363,8 +410,9 @@ public: } auto fsyncSync(FileHandle file) { - auto err = cleanupAndInvokeSync(&uv_fs_fsync, parent(), get(), file, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_fsync, parent(), req, file, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void fdatasync(FileHandle file) { @@ -372,8 +420,9 @@ public: } auto fdatasyncSync(FileHandle file) { - auto err = cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), get(), file, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), req, file, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void ftruncate(FileHandle file, int64_t offset) { @@ -381,8 +430,9 @@ public: } auto ftruncateSync(FileHandle file, int64_t offset) { - auto err = cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), get(), file, offset, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), req, file, offset, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void sendfile(FileHandle out, FileHandle in, int64_t offset, size_t length) { @@ -390,8 +440,9 @@ public: } auto sendfileSync(FileHandle out, FileHandle in, int64_t offset, size_t length) { - auto err = cleanupAndInvokeSync(&uv_fs_sendfile, parent(), get(), out, in, offset, length, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, in, offset, length, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void access(std::string path, int mode) { @@ -399,8 +450,9 @@ public: } auto accessSync(std::string path, int mode) { - auto err = cleanupAndInvokeSync(&uv_fs_access, parent(), get(), path.data(), mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_access, parent(), req, path.data(), mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void chmod(std::string path, int mode) { @@ -408,8 +460,9 @@ public: } auto chmodSync(std::string path, int mode) { - auto err = cleanupAndInvokeSync(&uv_fs_chmod, parent(), get(), path.data(), mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_chmod, parent(), req, path.data(), mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void fchmod(FileHandle file, int mode) { @@ -417,8 +470,9 @@ public: } auto fchmodSync(FileHandle file, int mode) { - auto err = cleanupAndInvokeSync(&uv_fs_fchmod, parent(), get(), file, mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_fchmod, parent(), req, file, mode, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void utime(std::string path, Time atime, Time mtime) { @@ -426,8 +480,9 @@ public: } auto utimeSync(std::string path, Time atime, Time mtime) { - auto err = cleanupAndInvokeSync(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_utime, parent(), req, path.data(), atime.count(), mtime.count(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void futime(FileHandle file, Time atime, Time mtime) { @@ -435,8 +490,9 @@ public: } auto futimeSync(FileHandle file, Time atime, Time mtime) { - auto err = cleanupAndInvokeSync(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_futime, parent(), req, file, atime.count(), mtime.count(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void link(std::string old, std::string path) { @@ -444,8 +500,9 @@ public: } auto linkSync(std::string old, std::string path) { - auto err = cleanupAndInvokeSync(&uv_fs_link, parent(), get(), old.data(), path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_link, parent(), req, old.data(), path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void symlink(std::string old, std::string path, int flags) { @@ -453,8 +510,9 @@ public: } auto symlinkSync(std::string old, std::string path, int flags) { - auto err = cleanupAndInvokeSync(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_symlink, parent(), req, old.data(), path.data(), flags, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void readlink(std::string path) { @@ -464,7 +522,7 @@ public: auto readlinkSync(std::string path) { auto req = get(); auto err = cleanupAndInvokeSync(&uv_fs_readlink, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{static_cast(req->ptr)}); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path, static_cast(req->ptr)}); } void realpath(std::string path) { @@ -472,8 +530,9 @@ public: } auto realpathSync(std::string path) { - auto err = cleanupAndInvokeSync(&uv_fs_realpath, parent(), get(), path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_realpath, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void chown(std::string path, Uid uid, Gid gid) { @@ -481,8 +540,9 @@ public: } auto chownSync(std::string path, Uid uid, Gid gid) { - auto err = cleanupAndInvokeSync(&uv_fs_chown, parent(), get(), path.data(), uid, gid, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_chown, parent(), req, path.data(), uid, gid, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } void fchown(FileHandle file, Uid uid, Gid gid) { @@ -490,8 +550,9 @@ public: } auto fchownSync(FileHandle file, Uid uid, Gid gid) { - auto err = cleanupAndInvokeSync(&uv_fs_fchown, parent(), get(), file, uid, gid, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{}); + auto req = get(); + auto err = cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); } }; From 228309d9a7268e29ddf8bc32ddd509501ed0fae4 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 16:47:35 +0200 Subject: [PATCH 06/10] code reusing --- src/uvw/fs.hpp | 64 +++++++++------------------------------------ src/uvw/request.hpp | 21 +++++++-------- 2 files changed, 21 insertions(+), 64 deletions(-) diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index c8f325d8..9daf3068 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -173,19 +173,9 @@ using FsEvent = TypedEvent; class Fs final: public Request { template static void fsGenericCallback(uv_fs_t *req) { - Fs &fs = *(static_cast(req->data)); - - auto ptr = fs.shared_from_this(); - (void)ptr; - - fs.reset(); - - if(req->result) { - int err = req->result; - fs.publish(ErrorEvent{err}); - } else { - fs.publish(FsEvent{req->path}); - } + auto ptr = reserve(reinterpret_cast(req)); + if(req->result) { ptr->publish(ErrorEvent{static_cast(req->result)}); } + else { ptr->publish(FsEvent{req->path}); } } static void fsReadCallback(uv_fs_t *req) { @@ -193,52 +183,22 @@ class Fs final: public Request { } static void fsWriteCallback(uv_fs_t *req) { - Fs &fs = *(static_cast(req->data)); - - auto ptr = fs.shared_from_this(); - (void)ptr; - - fs.reset(); - - if(req->result) { - int err = req->result; - fs.publish(ErrorEvent{err}); - } else { - fs.publish(FsEvent{req->path, req->result}); - } + auto ptr = reserve(reinterpret_cast(req)); + if(req->result) { ptr->publish(ErrorEvent{static_cast(req->result)}); } + else { ptr->publish(FsEvent{req->path, req->result}); } } template static void fsStatCallback(uv_fs_t *req) { - Fs &fs = *(static_cast(req->data)); - - auto ptr = fs.shared_from_this(); - (void)ptr; - - fs.reset(); - - if(req->result) { - int err = req->result; - fs.publish(ErrorEvent{err}); - } else { - fs.publish(FsEvent{req->path, req->statbuf}); - } + auto ptr = reserve(reinterpret_cast(req)); + if(req->result) { ptr->publish(ErrorEvent{static_cast(req->result)}); } + else { ptr->publish(FsEvent{req->path, req->statbuf}); } } static void fsReadlinkCallback(uv_fs_t *req) { - Fs &fs = *(static_cast(req->data)); - - auto ptr = fs.shared_from_this(); - (void)ptr; - - fs.reset(); - - if(req->result) { - int err = req->result; - fs.publish(ErrorEvent{err}); - } else { - fs.publish(FsEvent{req->path, static_cast(req->ptr)}); - } + auto ptr = reserve(reinterpret_cast(req)); + if(req->result) { ptr->publish(ErrorEvent{static_cast(req->result)}); } + else { ptr->publish(FsEvent{req->path, static_cast(req->ptr)}); } } using Request::Request; diff --git a/src/uvw/request.hpp b/src/uvw/request.hpp index d8891158..4c062836 100644 --- a/src/uvw/request.hpp +++ b/src/uvw/request.hpp @@ -16,20 +16,17 @@ class Request: public Resource { protected: using Resource::Resource; + static auto reserve(uv_req_t *req) { + auto ptr = static_cast(req->data)->shared_from_this(); + ptr->reset(); + return ptr; + } + template static void defaultCallback(R *req, int status) { - T &res = *(static_cast(req->data)); - - auto ptr = res.shared_from_this(); - (void)ptr; - - res.reset(); - - if(status) { - res.publish(ErrorEvent{status}); - } else { - res.publish(E{}); - } + auto ptr = reserve(reinterpret_cast(req)); + if(status) { ptr->publish(ErrorEvent{status}); } + else { ptr->publish(E{}); } } template From e39410607a40589ee427a54adb234b799eba83ce Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 17:02:19 +0200 Subject: [PATCH 07/10] WIP: Fs::writeSync --- src/uvw/fs.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index 9daf3068..ae338843 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -268,7 +268,10 @@ public: } auto writeSync(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { - // TODO uv_fs_write (sync (cb null)) + uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; + auto req = get(); + auto err = uv_fs_write(parent(), get(), file, bufs, 1, offset, nullptr); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->result}); } void mkdir(std::string path, int mode) { From ea93560c7cb312e5ecebc2b216f931ed7a5e572a Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 18:09:08 +0200 Subject: [PATCH 08/10] minor changes --- src/uvw/event.hpp | 3 +++ src/uvw/tty.hpp | 4 +--- src/uvw/util.hpp | 5 +++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/uvw/event.hpp b/src/uvw/event.hpp index 7ae29444..300e186b 100644 --- a/src/uvw/event.hpp +++ b/src/uvw/event.hpp @@ -34,6 +34,9 @@ struct Event: BaseEvent { struct ErrorEvent: Event { explicit ErrorEvent(int code = 0) noexcept: ec(code) { } + template::value>> + explicit ErrorEvent(U val) noexcept: ec{static_cast(val)} { } + const char * what() const noexcept { return uv_strerror(ec); } int code() const noexcept { return ec; } diff --git a/src/uvw/tty.hpp b/src/uvw/tty.hpp index c1e2102a..636e006a 100644 --- a/src/uvw/tty.hpp +++ b/src/uvw/tty.hpp @@ -30,9 +30,7 @@ class TTY final: public Stream { explicit TTY(std::shared_ptr ref, FileHandle desc, bool readable) - : Stream{std::move(ref)}, - fd{static_cast(desc)}, - rw{readable} + : Stream{std::move(ref)}, fd{desc}, rw{readable} { } public: diff --git a/src/uvw/util.hpp b/src/uvw/util.hpp index c8a7cfde..db2b69d6 100644 --- a/src/uvw/util.hpp +++ b/src/uvw/util.hpp @@ -47,7 +47,12 @@ private: template struct UVTypeWrapper { using Type = T; + + template::value>> + constexpr UVTypeWrapper(U val): value{static_cast(val)} { } + constexpr UVTypeWrapper(Type val): value{val} { } + constexpr operator Type() const noexcept { return value; } private: const Type value; From 1b2486342b1d52c849661a303e683d1ed5971922 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 18:09:49 +0200 Subject: [PATCH 09/10] WIP: fixed Fs --- src/uvw/fs.hpp | 96 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 18 deletions(-) diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index ae338843..e88d61ab 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -81,6 +81,23 @@ private: }; +template<> +struct TypedEvent + : Event> +{ + TypedEvent(const char *p, ssize_t desc) noexcept + : rPath{p}, fd{desc} + { } + + const char * path() const noexcept { return rPath; } + FileHandle file() const noexcept { return fd; } + +private: + const char *rPath; + const FileHandle fd; +}; + + template<> struct TypedEvent : Event> @@ -98,6 +115,23 @@ private: }; +template<> +struct TypedEvent + : Event> +{ + TypedEvent(const char *p, ssize_t s) noexcept + : rPath{p}, sz{s} + { } + + const char * path() const noexcept { return rPath; } + ssize_t amount() const noexcept { return sz; } + +private: + const char *rPath; + const ssize_t sz; +}; + + template<> struct TypedEvent : Event> @@ -149,20 +183,39 @@ private: }; +template<> +struct TypedEvent + : Event> +{ + TypedEvent(const char *p, ssize_t s) noexcept + : rPath{p}, sz{s} + { } + + const char * path() const noexcept { return rPath; } + ssize_t amount() const noexcept { return sz; } + +private: + const char *rPath; + const ssize_t sz; +}; + + template<> struct TypedEvent : Event> { - explicit TypedEvent(const char *p, const char *d) noexcept - : rPath{p}, dt{d} + explicit TypedEvent(const char *p, const char *d, ssize_t l) noexcept + : rPath{p}, dt{d}, len{l} { } const char * path() const noexcept { return rPath; } const char * data() const noexcept { return dt; } + ssize_t length() const noexcept { return len; } private: const char *rPath; const char *dt; + const ssize_t len; }; @@ -174,7 +227,7 @@ class Fs final: public Request { template static void fsGenericCallback(uv_fs_t *req) { auto ptr = reserve(reinterpret_cast(req)); - if(req->result) { ptr->publish(ErrorEvent{static_cast(req->result)}); } + if(req->result) { ptr->publish(ErrorEvent{req->result}); } else { ptr->publish(FsEvent{req->path}); } } @@ -182,23 +235,24 @@ class Fs final: public Request { // TODO - uv_fs_read callback } - static void fsWriteCallback(uv_fs_t *req) { + template + static void fsResultCallback(uv_fs_t *req) { auto ptr = reserve(reinterpret_cast(req)); - if(req->result) { ptr->publish(ErrorEvent{static_cast(req->result)}); } - else { ptr->publish(FsEvent{req->path, req->result}); } + if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); } + else { ptr->publish(FsEvent{req->path, req->result}); } } template static void fsStatCallback(uv_fs_t *req) { auto ptr = reserve(reinterpret_cast(req)); - if(req->result) { ptr->publish(ErrorEvent{static_cast(req->result)}); } + if(req->result) { ptr->publish(ErrorEvent{req->result}); } else { ptr->publish(FsEvent{req->path, req->statbuf}); } } static void fsReadlinkCallback(uv_fs_t *req) { auto ptr = reserve(reinterpret_cast(req)); - if(req->result) { ptr->publish(ErrorEvent{static_cast(req->result)}); } - else { ptr->publish(FsEvent{req->path, static_cast(req->ptr)}); } + if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); } + else { ptr->publish(FsEvent{req->path, static_cast(req->ptr), req->result}); } } using Request::Request; @@ -241,16 +295,22 @@ public: } void open(std::string path, int flags, int mode) { - cleanupAndInvoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsResultCallback); } auto openSync(std::string path, int flags, int mode) { auto req = get(); auto err = cleanupAndInvokeSync(&uv_fs_open, parent(), req, path.data(), flags, mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->result}); } - // TODO uv_fs_read (sync (cb null)/async) + void read(FileHandle file, int64_t offset, unsigned int len) { + // TODO uv_fs_read (async) + } + + auto readSync(FileHandle file, int64_t offset, unsigned int len) { + // TODO uv_fs_read (sync (cb null)) + } void unlink(std::string path) { cleanupAndInvoke(&uv_fs_unlink, parent(), get(), path.data(), &fsGenericCallback); @@ -264,7 +324,7 @@ public: void write(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; - cleanupAndInvoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsWriteCallback); + cleanupAndInvoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsResultCallback); } auto writeSync(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { @@ -305,13 +365,13 @@ public: } void scandir(std::string path, int flags) { - cleanupAndInvoke(&uv_fs_scandir, parent(), get(), path.data(), flags, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_scandir, parent(), get(), path.data(), flags, &fsResultCallback); } auto scandirSync(std::string path, int flags) { auto req = get(); auto err = cleanupAndInvokeSync(&uv_fs_scandir, parent(), req, path.data(), flags, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->result}); } std::pair scandirNext() { @@ -399,13 +459,13 @@ public: } void sendfile(FileHandle out, FileHandle in, int64_t offset, size_t length) { - cleanupAndInvoke(&uv_fs_sendfile, parent(), get(), out, in, offset, length, &fsGenericCallback); + cleanupAndInvoke(&uv_fs_sendfile, parent(), get(), out, in, offset, length, &fsResultCallback); } auto sendfileSync(FileHandle out, FileHandle in, int64_t offset, size_t length) { auto req = get(); auto err = cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, in, offset, length, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->result}); } void access(std::string path, int mode) { @@ -485,7 +545,7 @@ public: auto readlinkSync(std::string path) { auto req = get(); auto err = cleanupAndInvokeSync(&uv_fs_readlink, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path, static_cast(req->ptr)}); + return std::make_pair(ErrorEvent{err}, FsEvent{req->path, static_cast(req->ptr), req->result}); } void realpath(std::string path) { From f10bb33cf951ccad780e723aecdd303eef950e0f Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 27 Jul 2016 20:13:50 +0200 Subject: [PATCH 10/10] WIP: Fs review --- src/uvw/fs.hpp | 219 +++++++++++++++++++++++++---------------------- src/uvw/util.hpp | 5 -- 2 files changed, 119 insertions(+), 105 deletions(-) diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index e88d61ab..ff8f8eff 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -81,23 +81,6 @@ private: }; -template<> -struct TypedEvent - : Event> -{ - TypedEvent(const char *p, ssize_t desc) noexcept - : rPath{p}, fd{desc} - { } - - const char * path() const noexcept { return rPath; } - FileHandle file() const noexcept { return fd; } - -private: - const char *rPath; - const FileHandle fd; -}; - - template<> struct TypedEvent : Event> @@ -224,6 +207,30 @@ using FsEvent = TypedEvent; class Fs final: public Request { + static constexpr int BAD_FD = -1; + + static void fsCloseCallback(uv_fs_t *req) { + auto ptr = reserve(reinterpret_cast(req)); + + if(req->result) { + ptr->publish(ErrorEvent{req->result}); + } else { + ptr->file = BAD_FD; + ptr->publish(FsEvent{req->path}); + } + } + + static void fsOpenCallback(uv_fs_t *req) { + auto ptr = reserve(reinterpret_cast(req)); + + if(req->result < 0) { + ptr->publish(ErrorEvent{req->result}); + } else { + ptr->file = req->result; + ptr->publish(FsEvent{req->path}); + } + } + template static void fsGenericCallback(uv_fs_t *req) { auto ptr = reserve(reinterpret_cast(req)); @@ -258,15 +265,15 @@ class Fs final: public Request { using Request::Request; template - auto cleanupAndInvoke(Args&&... args) { + void cleanupAndInvoke(Args&&... args) { uv_fs_req_cleanup(get()); - return invoke(std::forward(args)...); + invoke(std::forward(args)...); } template - auto cleanupAndInvokeSync(F &&f, Args&&... args) { + void cleanupAndInvokeSync(F &&f, Args&&... args) { uv_fs_req_cleanup(get()); - return std::forward(f)(std::forward(args)...); + std::forward(f)(std::forward(args)...); } public: @@ -284,31 +291,34 @@ public: uv_fs_req_cleanup(get()); } - void close(FileHandle file) { - cleanupAndInvoke(&uv_fs_close, parent(), get(), file, &fsGenericCallback); + void close() { + cleanupAndInvoke(&uv_fs_close, parent(), get(), file, &fsCloseCallback); } - auto closeSync(FileHandle file) { + auto closeSync() { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_close, parent(), req, file, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_close, parent(), req, file, nullptr); + if(!req->result) { file = BAD_FD; } + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void open(std::string path, int flags, int mode) { - cleanupAndInvoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsResultCallback); + cleanupAndInvoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsOpenCallback); } auto openSync(std::string path, int flags, int mode) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_open, parent(), req, path.data(), flags, mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->result}); + 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{req->path}); } - void read(FileHandle file, int64_t offset, unsigned int len) { + void read(int64_t offset, unsigned int len) { // TODO uv_fs_read (async) } - auto readSync(FileHandle file, int64_t offset, unsigned int len) { + auto readSync(int64_t offset, unsigned int len) { // TODO uv_fs_read (sync (cb null)) } @@ -318,20 +328,21 @@ public: auto unlinkSync(std::string path) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_unlink, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_unlink, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } - void write(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { + void write(std::unique_ptr data, ssize_t len, int64_t offset) { uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; cleanupAndInvoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsResultCallback); } - auto writeSync(FileHandle file, std::unique_ptr data, ssize_t len, int64_t offset) { + auto writeSync(std::unique_ptr data, ssize_t len, int64_t offset) { uv_buf_t bufs[] = { uv_buf_init(data.get(), len) }; auto req = get(); - auto err = uv_fs_write(parent(), get(), file, bufs, 1, offset, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->result}); + cleanupAndInvokeSync(&uv_fs_write, parent(), get(), file, bufs, 1, offset, nullptr); + auto bw = req->result; + return std::make_pair(ErrorEvent{bw < 0 ? bw : 0}, FsEvent{req->path, bw}); } void mkdir(std::string path, int mode) { @@ -340,8 +351,8 @@ public: auto mkdirSync(std::string path, int mode) { auto req = get(); - auto err = uv_fs_mkdir(parent(), req, path.data(), mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_mkdir, parent(), req, path.data(), mode, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void mkdtemp(std::string tpl) { @@ -350,8 +361,8 @@ public: auto mkdtempSync(std::string tpl) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), req, tpl.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), req, tpl.data(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void rmdir(std::string path) { @@ -360,8 +371,8 @@ public: auto rmdirSync(std::string path) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_rmdir, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_rmdir, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void scandir(std::string path, int flags) { @@ -370,8 +381,9 @@ public: auto scandirSync(std::string path, int flags) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_scandir, parent(), req, path.data(), flags, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->result}); + cleanupAndInvokeSync(&uv_fs_scandir, parent(), req, path.data(), flags, nullptr); + auto sz = req->result; + return std::make_pair(ErrorEvent{sz < 0 ? sz : 0}, FsEvent{req->path, sz}); } std::pair scandirNext() { @@ -394,18 +406,18 @@ public: auto statSync(std::string path) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_stat, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->statbuf}); + cleanupAndInvokeSync(&uv_fs_stat, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path, req->statbuf}); } - void fstat(FileHandle file) { + void fstat() { cleanupAndInvoke(&uv_fs_fstat, parent(), get(), file, &fsStatCallback); } - auto fstatSync(FileHandle file) { + auto fstatSync() { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->statbuf}); + cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path, req->statbuf}); } void lstat(std::string path) { @@ -414,8 +426,8 @@ public: auto lstatSync(std::string path) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_lstat, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->statbuf}); + cleanupAndInvokeSync(&uv_fs_lstat, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path, req->statbuf}); } void rename(std::string old, std::string path) { @@ -424,48 +436,49 @@ public: auto renameSync(std::string old, std::string path) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_rename, parent(), req, old.data(), path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_rename, parent(), req, old.data(), path.data(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } - void fsync(FileHandle file) { + void fsync() { cleanupAndInvoke(&uv_fs_fsync, parent(), get(), file, &fsGenericCallback); } - auto fsyncSync(FileHandle file) { + auto fsyncSync() { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_fsync, parent(), req, file, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_fsync, parent(), req, file, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } - void fdatasync(FileHandle file) { + void fdatasync() { cleanupAndInvoke(&uv_fs_fdatasync, parent(), get(), file, &fsGenericCallback); } - auto fdatasyncSync(FileHandle file) { + auto fdatasyncSync() { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), req, file, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), req, file, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } - void ftruncate(FileHandle file, int64_t offset) { + void ftruncate(int64_t offset) { cleanupAndInvoke(&uv_fs_ftruncate, parent(), get(), file, offset, &fsGenericCallback); } - auto ftruncateSync(FileHandle file, int64_t offset) { + auto ftruncateSync(int64_t offset) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), req, file, offset, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), req, file, offset, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } - void sendfile(FileHandle out, FileHandle in, int64_t offset, size_t length) { - cleanupAndInvoke(&uv_fs_sendfile, parent(), get(), out, in, offset, length, &fsResultCallback); + void sendfile(FileHandle out, int64_t offset, size_t length) { + cleanupAndInvoke(&uv_fs_sendfile, parent(), get(), out, file, offset, length, &fsResultCallback); } - auto sendfileSync(FileHandle out, FileHandle in, int64_t offset, size_t length) { + auto sendfileSync(FileHandle out, int64_t offset, size_t length) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, in, offset, length, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path, req->result}); + cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, file, offset, length, nullptr); + auto bw = req->result; + return std::make_pair(ErrorEvent{bw < 0 ? bw : 0}, FsEvent{req->path, bw}); } void access(std::string path, int mode) { @@ -474,8 +487,8 @@ public: auto accessSync(std::string path, int mode) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_access, parent(), req, path.data(), mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_access, parent(), req, path.data(), mode, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void chmod(std::string path, int mode) { @@ -484,18 +497,18 @@ public: auto chmodSync(std::string path, int mode) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_chmod, parent(), req, path.data(), mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_chmod, parent(), req, path.data(), mode, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } - void fchmod(FileHandle file, int mode) { + void fchmod(int mode) { cleanupAndInvoke(&uv_fs_fchmod, parent(), get(), file, mode, &fsGenericCallback); } - auto fchmodSync(FileHandle file, int mode) { + auto fchmodSync(int mode) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_fchmod, parent(), req, file, mode, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_fchmod, parent(), req, file, mode, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void utime(std::string path, Time atime, Time mtime) { @@ -504,18 +517,18 @@ public: auto utimeSync(std::string path, Time atime, Time mtime) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_utime, parent(), req, path.data(), atime.count(), mtime.count(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_utime, parent(), req, path.data(), atime.count(), mtime.count(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } - void futime(FileHandle file, Time atime, Time mtime) { + void futime(Time atime, Time mtime) { cleanupAndInvoke(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), &fsGenericCallback); } - auto futimeSync(FileHandle file, Time atime, Time mtime) { + auto futimeSync(Time atime, Time mtime) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_futime, parent(), req, file, atime.count(), mtime.count(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_futime, parent(), req, file, atime.count(), mtime.count(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void link(std::string old, std::string path) { @@ -524,8 +537,8 @@ public: auto linkSync(std::string old, std::string path) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_link, parent(), req, old.data(), path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_link, parent(), req, old.data(), path.data(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void symlink(std::string old, std::string path, int flags) { @@ -534,8 +547,8 @@ public: auto symlinkSync(std::string old, std::string path, int flags) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_symlink, parent(), req, old.data(), path.data(), flags, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_symlink, parent(), req, old.data(), path.data(), flags, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void readlink(std::string path) { @@ -544,8 +557,9 @@ public: auto readlinkSync(std::string path) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_readlink, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path, static_cast(req->ptr), req->result}); + cleanupAndInvokeSync(&uv_fs_readlink, parent(), req, path.data(), nullptr); + auto bw = req->result; + return std::make_pair(ErrorEvent{bw < 0 ? bw : 0}, FsEvent{req->path, static_cast(req->ptr), bw}); } void realpath(std::string path) { @@ -554,8 +568,8 @@ public: auto realpathSync(std::string path) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_realpath, parent(), req, path.data(), nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_realpath, parent(), req, path.data(), nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } void chown(std::string path, Uid uid, Gid gid) { @@ -564,19 +578,24 @@ public: auto chownSync(std::string path, Uid uid, Gid gid) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_chown, parent(), req, path.data(), uid, gid, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_chown, parent(), req, path.data(), uid, gid, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } - void fchown(FileHandle file, Uid uid, Gid gid) { + void fchown(Uid uid, Gid gid) { cleanupAndInvoke(&uv_fs_fchown, parent(), get(), file, uid, gid, &fsGenericCallback); } - auto fchownSync(FileHandle file, Uid uid, Gid gid) { + auto fchownSync(Uid uid, Gid gid) { auto req = get(); - auto err = cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid, nullptr); - return std::make_pair(ErrorEvent{err}, FsEvent{req->path}); + cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid, nullptr); + return std::make_pair(ErrorEvent{req->result}, FsEvent{req->path}); } + + operator FileHandle() const noexcept { return file; } + +private: + uv_file file{BAD_FD}; }; diff --git a/src/uvw/util.hpp b/src/uvw/util.hpp index db2b69d6..c8a7cfde 100644 --- a/src/uvw/util.hpp +++ b/src/uvw/util.hpp @@ -47,12 +47,7 @@ private: template struct UVTypeWrapper { using Type = T; - - template::value>> - constexpr UVTypeWrapper(U val): value{static_cast(val)} { } - constexpr UVTypeWrapper(Type val): value{val} { } - constexpr operator Type() const noexcept { return value; } private: const Type value;