Merge pull request #33 from cynnyx/master
review Fs* + added ProcessHandle + AOB
This commit is contained in:
commit
1f34323202
@ -10,6 +10,7 @@
|
||||
#include "uvw/pipe.hpp"
|
||||
#include "uvw/poll.hpp"
|
||||
#include "uvw/prepare.hpp"
|
||||
#include "uvw/process.hpp"
|
||||
#include "uvw/signal.hpp"
|
||||
#include "uvw/tcp.hpp"
|
||||
#include "uvw/timer.hpp"
|
||||
|
||||
@ -29,9 +29,13 @@ public:
|
||||
return std::shared_ptr<AsyncHandle>{new AsyncHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_async_t>(&uv_async_init, &sendCallback); }
|
||||
bool init() {
|
||||
return initialize<uv_async_t>(&uv_async_init, &sendCallback);
|
||||
}
|
||||
|
||||
void send() { invoke(&uv_async_send, get<uv_async_t>()); }
|
||||
void send() {
|
||||
invoke(&uv_async_send, get<uv_async_t>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -29,10 +29,17 @@ public:
|
||||
return std::shared_ptr<CheckHandle>{new CheckHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_check_t>(&uv_check_init); }
|
||||
bool init() {
|
||||
return initialize<uv_check_t>(&uv_check_init);
|
||||
}
|
||||
|
||||
void start() { invoke(&uv_check_start, get<uv_check_t>(), &startCallback); }
|
||||
void stop() { invoke(&uv_check_stop, get<uv_check_t>()); }
|
||||
void start() {
|
||||
invoke(&uv_check_start, get<uv_check_t>(), &startCallback);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
invoke(&uv_check_stop, get<uv_check_t>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ namespace uvw {
|
||||
template<typename T>
|
||||
class Emitter {
|
||||
struct BaseHandler {
|
||||
virtual ~BaseHandler() = default;
|
||||
virtual ~BaseHandler() noexcept = default;
|
||||
virtual bool empty() const noexcept = 0;
|
||||
};
|
||||
|
||||
|
||||
327
src/uvw/fs.hpp
327
src/uvw/fs.hpp
@ -81,23 +81,6 @@ 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::READ>
|
||||
: Event<TypedEvent<details::UVFsType, details::UVFsType::READ>>
|
||||
@ -242,57 +225,41 @@ template<details::UVFsType e>
|
||||
using FsEvent = TypedEvent<details::UVFsType, e>;
|
||||
|
||||
|
||||
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->publish(FsEvent<Type::OPEN>{req->path, static_cast<uv_file>(req->result)}); }
|
||||
}
|
||||
|
||||
static void fsReadCallback(uv_fs_t *req) {
|
||||
auto ptr = reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
|
||||
else { ptr->publish(FsEvent<Type::READ>{req->path, std::move(ptr->data), req->result}); }
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class FsRequest: public Request<T, uv_fs_t> {
|
||||
protected:
|
||||
template<details::UVFsType e>
|
||||
static void fsGenericCallback(uv_fs_t *req) {
|
||||
auto ptr = reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
auto ptr = Request<T, uv_fs_t>::reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
|
||||
else { ptr->publish(FsEvent<e>{req->path}); }
|
||||
}
|
||||
|
||||
template<details::UVFsType e>
|
||||
static void fsResultCallback(uv_fs_t *req) {
|
||||
auto ptr = reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
auto ptr = Request<T, uv_fs_t>::reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
|
||||
else { ptr->publish(FsEvent<e>{req->path, req->result}); }
|
||||
}
|
||||
|
||||
template<details::UVFsType e>
|
||||
static void fsStatCallback(uv_fs_t *req) {
|
||||
auto ptr = reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
auto ptr = Request<T, uv_fs_t>::reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
|
||||
else { ptr->publish(FsEvent<e>{req->path, req->statbuf}); }
|
||||
}
|
||||
|
||||
static void fsReadlinkCallback(uv_fs_t *req) {
|
||||
auto ptr = reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
|
||||
else { ptr->publish(FsEvent<Type::READLINK>{req->path, static_cast<char *>(req->ptr), req->result}); }
|
||||
}
|
||||
|
||||
using Request::Request;
|
||||
using Request<T, uv_fs_t>::Request;
|
||||
|
||||
template<typename... Args>
|
||||
void cleanupAndInvoke(Args&&... args) {
|
||||
uv_fs_req_cleanup(get<uv_fs_t>());
|
||||
invoke(std::forward<Args>(args)...);
|
||||
uv_fs_req_cleanup(this->template get<uv_fs_t>());
|
||||
this->invoke(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename F, typename... Args>
|
||||
void cleanupAndInvokeSync(F &&f, Args&&... args) {
|
||||
uv_fs_req_cleanup(get<uv_fs_t>());
|
||||
uv_fs_req_cleanup(this->template get<uv_fs_t>());
|
||||
std::forward<F>(f)(std::forward<Args>(args)..., nullptr);
|
||||
}
|
||||
|
||||
@ -301,23 +268,60 @@ public:
|
||||
using Type = details::UVFsType;
|
||||
using EntryType = details::UVDirentTypeT;
|
||||
using Entry = std::pair<EntryType, std::string>;
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<FsReq> create(Args&&... args) {
|
||||
return std::shared_ptr<FsReq>{new FsReq{std::forward<Args>(args)...}};
|
||||
|
||||
class FileReq final: public FsRequest<FileReq> {
|
||||
static constexpr uv_file BAD_FD = -1;
|
||||
|
||||
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 = static_cast<uv_file>(req->result);
|
||||
ptr->publish(FsEvent<Type::OPEN>{req->path});
|
||||
}
|
||||
}
|
||||
|
||||
~FsReq() {
|
||||
static void fsCloseCallback(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 = BAD_FD;
|
||||
ptr->publish(FsEvent<Type::CLOSE>{req->path});
|
||||
}
|
||||
}
|
||||
|
||||
static void fsReadCallback(uv_fs_t *req) {
|
||||
auto ptr = reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
|
||||
else { ptr->publish(FsEvent<Type::READ>{req->path, std::move(ptr->data), req->result}); }
|
||||
}
|
||||
|
||||
using FsRequest::FsRequest;
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<FileReq> create(Args&&... args) {
|
||||
return std::shared_ptr<FileReq>{new FileReq{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
~FileReq() noexcept {
|
||||
uv_fs_req_cleanup(get<uv_fs_t>());
|
||||
}
|
||||
|
||||
void close(FileHandle file) {
|
||||
cleanupAndInvoke(&uv_fs_close, parent(), get<uv_fs_t>(), file, &fsGenericCallback<Type::CLOSE>);
|
||||
void close() {
|
||||
cleanupAndInvoke(&uv_fs_close, parent(), get<uv_fs_t>(), file, &fsCloseCallback);
|
||||
}
|
||||
|
||||
auto closeSync(FileHandle file) {
|
||||
auto closeSync() {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_close, parent(), req, file);
|
||||
if(req->result >= 0) { file = BAD_FD; }
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::CLOSE>{req->path});
|
||||
}
|
||||
|
||||
@ -328,17 +332,18 @@ public:
|
||||
auto openSync(std::string path, int flags, int mode) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_open, parent(), req, path.data(), flags, mode);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::OPEN>{req->path, static_cast<uv_file>(req->result)});
|
||||
if(req->result >= 0) { file = static_cast<uv_file>(req->result); }
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::OPEN>{req->path});
|
||||
}
|
||||
|
||||
void read(FileHandle file, int64_t offset, unsigned int len) {
|
||||
void read(int64_t offset, unsigned int len) {
|
||||
data = std::unique_ptr<char[]>{new char[len]};
|
||||
buffer = uv_buf_init(data.get(), len);
|
||||
uv_buf_t bufs[] = { buffer };
|
||||
cleanupAndInvoke(&uv_fs_read, parent(), get<uv_fs_t>(), file, bufs, 1, offset, &fsReadCallback);
|
||||
}
|
||||
|
||||
auto readSync(FileHandle file, int64_t offset, unsigned int len) {
|
||||
auto readSync(int64_t offset, unsigned int len) {
|
||||
data = std::unique_ptr<char[]>{new char[len]};
|
||||
buffer = uv_buf_init(data.get(), len);
|
||||
uv_buf_t bufs[] = { buffer };
|
||||
@ -347,6 +352,126 @@ public:
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::READ>{req->path, std::move(data), req->result});
|
||||
}
|
||||
|
||||
void write(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) {
|
||||
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);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::WRITE>{req->path, req->result});
|
||||
}
|
||||
|
||||
void fstat() {
|
||||
cleanupAndInvoke(&uv_fs_fstat, parent(), get<uv_fs_t>(), file, &fsStatCallback<Type::FSTAT>);
|
||||
}
|
||||
|
||||
auto fstatSync() {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FSTAT>{req->path, req->statbuf});
|
||||
}
|
||||
|
||||
void fsync() {
|
||||
cleanupAndInvoke(&uv_fs_fsync, parent(), get<uv_fs_t>(), file, &fsGenericCallback<Type::FSYNC>);
|
||||
}
|
||||
|
||||
auto fsyncSync() {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fsync, parent(), req, file);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FSYNC>{req->path});
|
||||
}
|
||||
|
||||
void fdatasync() {
|
||||
cleanupAndInvoke(&uv_fs_fdatasync, parent(), get<uv_fs_t>(), file, &fsGenericCallback<Type::FDATASYNC>);
|
||||
}
|
||||
|
||||
auto fdatasyncSync() {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), req, file);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FDATASYNC>{req->path});
|
||||
}
|
||||
|
||||
void ftruncate(int64_t offset) {
|
||||
cleanupAndInvoke(&uv_fs_ftruncate, parent(), get<uv_fs_t>(), file, offset, &fsGenericCallback<Type::FTRUNCATE>);
|
||||
}
|
||||
|
||||
auto ftruncateSync(int64_t offset) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), req, file, offset);
|
||||
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>);
|
||||
}
|
||||
|
||||
auto sendfileSync(FileHandle out, int64_t offset, size_t length) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, file, offset, length);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::SENDFILE>{req->path, req->result});
|
||||
}
|
||||
|
||||
void fchmod(int mode) {
|
||||
cleanupAndInvoke(&uv_fs_fchmod, parent(), get<uv_fs_t>(), file, mode, &fsGenericCallback<Type::FCHMOD>);
|
||||
}
|
||||
|
||||
auto fchmodSync(int mode) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fchmod, parent(), req, file, mode);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FCHMOD>{req->path});
|
||||
}
|
||||
|
||||
void futime(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 req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_futime, parent(), req, file, atime.count(), mtime.count());
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FUTIME>{req->path});
|
||||
}
|
||||
|
||||
void fchown(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 req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FCHOWN>{req->path});
|
||||
}
|
||||
|
||||
operator FileHandle() const noexcept { return file; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<char[]> data{nullptr};
|
||||
uv_buf_t buffer{};
|
||||
uv_file file{BAD_FD};
|
||||
};
|
||||
|
||||
|
||||
class FsReq final: public FsRequest<FsReq> {
|
||||
using FsRequest::FsRequest;
|
||||
|
||||
static void fsReadlinkCallback(uv_fs_t *req) {
|
||||
auto ptr = reserve(reinterpret_cast<uv_req_t*>(req));
|
||||
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
|
||||
else { ptr->publish(FsEvent<Type::READLINK>{req->path, static_cast<char *>(req->ptr), req->result}); }
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<FsReq> create(Args&&... args) {
|
||||
return std::shared_ptr<FsReq>{new FsReq{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
~FsReq() noexcept {
|
||||
uv_fs_req_cleanup(get<uv_fs_t>());
|
||||
}
|
||||
|
||||
void unlink(std::string path) {
|
||||
cleanupAndInvoke(&uv_fs_unlink, parent(), get<uv_fs_t>(), path.data(), &fsGenericCallback<Type::UNLINK>);
|
||||
}
|
||||
@ -357,18 +482,6 @@ public:
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::UNLINK>{req->path});
|
||||
}
|
||||
|
||||
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(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);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::WRITE>{req->path, req->result});
|
||||
}
|
||||
|
||||
void mkdir(std::string path, int mode) {
|
||||
cleanupAndInvoke(&uv_fs_mkdir, parent(), get<uv_fs_t>(), path.data(), mode, &fsGenericCallback<Type::MKDIR>);
|
||||
}
|
||||
@ -433,16 +546,6 @@ public:
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::STAT>{req->path, req->statbuf});
|
||||
}
|
||||
|
||||
void fstat(FileHandle file) {
|
||||
cleanupAndInvoke(&uv_fs_fstat, parent(), get<uv_fs_t>(), file, &fsStatCallback<Type::FSTAT>);
|
||||
}
|
||||
|
||||
auto fstatSync(FileHandle file) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FSTAT>{req->path, req->statbuf});
|
||||
}
|
||||
|
||||
void lstat(std::string path) {
|
||||
cleanupAndInvoke(&uv_fs_lstat, parent(), get<uv_fs_t>(), path.data(), &fsStatCallback<Type::LSTAT>);
|
||||
}
|
||||
@ -463,46 +566,6 @@ public:
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::RENAME>{req->path});
|
||||
}
|
||||
|
||||
void fsync(FileHandle file) {
|
||||
cleanupAndInvoke(&uv_fs_fsync, parent(), get<uv_fs_t>(), file, &fsGenericCallback<Type::FSYNC>);
|
||||
}
|
||||
|
||||
auto fsyncSync(FileHandle file) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fsync, parent(), req, file);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FSYNC>{req->path});
|
||||
}
|
||||
|
||||
void fdatasync(FileHandle file) {
|
||||
cleanupAndInvoke(&uv_fs_fdatasync, parent(), get<uv_fs_t>(), file, &fsGenericCallback<Type::FDATASYNC>);
|
||||
}
|
||||
|
||||
auto fdatasyncSync(FileHandle file) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), req, file);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FDATASYNC>{req->path});
|
||||
}
|
||||
|
||||
void ftruncate(FileHandle file, int64_t offset) {
|
||||
cleanupAndInvoke(&uv_fs_ftruncate, parent(), get<uv_fs_t>(), file, offset, &fsGenericCallback<Type::FTRUNCATE>);
|
||||
}
|
||||
|
||||
auto ftruncateSync(FileHandle file, int64_t offset) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), req, file, offset);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FTRUNCATE>{req->path});
|
||||
}
|
||||
|
||||
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, FileHandle in, int64_t offset, size_t length) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, in, offset, length);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::SENDFILE>{req->path, req->result});
|
||||
}
|
||||
|
||||
void access(std::string path, int mode) {
|
||||
cleanupAndInvoke(&uv_fs_access, parent(), get<uv_fs_t>(), path.data(), mode, &fsGenericCallback<Type::ACCESS>);
|
||||
}
|
||||
@ -523,16 +586,6 @@ public:
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::CHMOD>{req->path});
|
||||
}
|
||||
|
||||
void fchmod(FileHandle file, int mode) {
|
||||
cleanupAndInvoke(&uv_fs_fchmod, parent(), get<uv_fs_t>(), file, mode, &fsGenericCallback<Type::FCHMOD>);
|
||||
}
|
||||
|
||||
auto fchmodSync(FileHandle file, int mode) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fchmod, parent(), req, file, mode);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FCHMOD>{req->path});
|
||||
}
|
||||
|
||||
void utime(std::string path, Time atime, Time mtime) {
|
||||
cleanupAndInvoke(&uv_fs_utime, parent(), get<uv_fs_t>(), path.data(), atime.count(), mtime.count(), &fsGenericCallback<Type::UTIME>);
|
||||
}
|
||||
@ -543,16 +596,6 @@ public:
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::UTIME>{req->path});
|
||||
}
|
||||
|
||||
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(FileHandle file, Time atime, Time mtime) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_futime, parent(), req, file, atime.count(), mtime.count());
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FUTIME>{req->path});
|
||||
}
|
||||
|
||||
void link(std::string old, std::string path) {
|
||||
cleanupAndInvoke(&uv_fs_link, parent(), get<uv_fs_t>(), old.data(), path.data(), &fsGenericCallback<Type::LINK>);
|
||||
}
|
||||
@ -602,20 +645,6 @@ public:
|
||||
cleanupAndInvokeSync(&uv_fs_chown, parent(), req, path.data(), uid, gid);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::CHOWN>{req->path});
|
||||
}
|
||||
|
||||
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(FileHandle file, Uid uid, Gid gid) {
|
||||
auto req = get<uv_fs_t>();
|
||||
cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid);
|
||||
return std::make_pair(ErrorEvent{req->result}, FsEvent<Type::FCHOWN>{req->path});
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<char[]> data;
|
||||
uv_buf_t buffer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -64,14 +64,21 @@ public:
|
||||
return std::shared_ptr<FsEventHandle>{new FsEventHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_fs_event_t>(&uv_fs_event_init); }
|
||||
bool init() {
|
||||
return initialize<uv_fs_event_t>(&uv_fs_event_init);
|
||||
}
|
||||
|
||||
void start(std::string path, Flags<Watch> flags = Flags<Watch>{}) {
|
||||
invoke(&uv_fs_event_start, get<uv_fs_event_t>(), &startCallback, path.data(), flags);
|
||||
}
|
||||
|
||||
void stop() { invoke(&uv_fs_event_stop, get<uv_fs_event_t>()); }
|
||||
std::string path() noexcept { return details::path(&uv_fs_event_getpath, get<uv_fs_event_t>()); }
|
||||
void stop() {
|
||||
invoke(&uv_fs_event_stop, get<uv_fs_event_t>());
|
||||
}
|
||||
|
||||
std::string path() noexcept {
|
||||
return details::path(&uv_fs_event_getpath, get<uv_fs_event_t>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -42,14 +42,21 @@ public:
|
||||
return std::shared_ptr<FsPollHandle>{new FsPollHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_fs_poll_t>(&uv_fs_poll_init); }
|
||||
bool init() {
|
||||
return initialize<uv_fs_poll_t>(&uv_fs_poll_init);
|
||||
}
|
||||
|
||||
void start(std::string file, unsigned int interval) {
|
||||
invoke(&uv_fs_poll_start, get<uv_fs_poll_t>(), &startCallback, file.data(), interval);
|
||||
}
|
||||
|
||||
void stop() { invoke(&uv_fs_poll_stop, get<uv_fs_poll_t>()); }
|
||||
std::string path() noexcept { return details::path(&uv_fs_poll_getpath, get<uv_fs_poll_t>()); }
|
||||
void stop() {
|
||||
invoke(&uv_fs_poll_stop, get<uv_fs_poll_t>());
|
||||
}
|
||||
|
||||
std::string path() noexcept {
|
||||
return details::path(&uv_fs_poll_getpath, get<uv_fs_poll_t>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -29,10 +29,17 @@ public:
|
||||
return std::shared_ptr<IdleHandle>{new IdleHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_idle_t>(&uv_idle_init); }
|
||||
bool init() {
|
||||
return initialize<uv_idle_t>(&uv_idle_init);
|
||||
}
|
||||
|
||||
void start() { invoke(&uv_idle_start, get<uv_idle_t>(), &startCallback); }
|
||||
void stop() { invoke(&uv_idle_stop, get<uv_idle_t>()); }
|
||||
void start() {
|
||||
invoke(&uv_idle_start, get<uv_idle_t>(), &startCallback);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
invoke(&uv_idle_stop, get<uv_idle_t>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -40,7 +40,9 @@ public:
|
||||
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); }
|
||||
bool init(bool ipc = false) {
|
||||
return initialize<uv_pipe_t>(&uv_pipe_init, ipc);
|
||||
}
|
||||
|
||||
void open(FileHandle file) {
|
||||
invoke(&uv_pipe_open, get<uv_pipe_t>(), file);
|
||||
@ -61,11 +63,21 @@ public:
|
||||
connect->connect(&uv_pipe_connect, get<uv_pipe_t>(), name.data());
|
||||
}
|
||||
|
||||
std::string sock() const noexcept { return details::path(&uv_pipe_getsockname, get<uv_pipe_t>()); }
|
||||
std::string peer() const noexcept { return details::path(&uv_pipe_getpeername, get<uv_pipe_t>()); }
|
||||
std::string sock() const noexcept {
|
||||
return details::path(&uv_pipe_getsockname, get<uv_pipe_t>());
|
||||
}
|
||||
|
||||
void pending(int count) noexcept { uv_pipe_pending_instances(get<uv_pipe_t>(), count); }
|
||||
int pending() noexcept { return uv_pipe_pending_count(get<uv_pipe_t>()); }
|
||||
std::string peer() const noexcept {
|
||||
return details::path(&uv_pipe_getpeername, get<uv_pipe_t>());
|
||||
}
|
||||
|
||||
void pending(int count) noexcept {
|
||||
uv_pipe_pending_instances(get<uv_pipe_t>(), count);
|
||||
}
|
||||
|
||||
int pending() noexcept {
|
||||
return uv_pipe_pending_count(get<uv_pipe_t>());
|
||||
}
|
||||
|
||||
Pending receive() noexcept {
|
||||
auto type = uv_pipe_pending_type(get<uv_pipe_t>());
|
||||
|
||||
@ -55,11 +55,21 @@ public:
|
||||
return std::shared_ptr<PollHandle>{new PollHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init(int fd) { return initialize<uv_poll_t>(&uv_poll_init, fd); }
|
||||
bool init(int fd) {
|
||||
return initialize<uv_poll_t>(&uv_poll_init, fd);
|
||||
}
|
||||
|
||||
void start(Flags<Event> flags) { invoke(&uv_poll_start, get<uv_poll_t>(), flags, &startCallback); }
|
||||
void start(Event event) { start(Flags<Event>{event}); }
|
||||
void stop() { invoke(&uv_poll_stop, get<uv_poll_t>()); }
|
||||
void start(Flags<Event> flags) {
|
||||
invoke(&uv_poll_start, get<uv_poll_t>(), flags, &startCallback);
|
||||
}
|
||||
|
||||
void start(Event event) {
|
||||
start(Flags<Event>{event});
|
||||
}
|
||||
|
||||
void stop() {
|
||||
invoke(&uv_poll_stop, get<uv_poll_t>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -29,10 +29,17 @@ public:
|
||||
return std::shared_ptr<PrepareHandle>{new PrepareHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_prepare_t>(&uv_prepare_init); }
|
||||
bool init() {
|
||||
return initialize<uv_prepare_t>(&uv_prepare_init);
|
||||
}
|
||||
|
||||
void start() { invoke(&uv_prepare_start, get<uv_prepare_t>(), &startCallback); }
|
||||
void stop() { invoke(&uv_prepare_stop, get<uv_prepare_t>()); }
|
||||
void start() {
|
||||
invoke(&uv_prepare_start, get<uv_prepare_t>(), &startCallback);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
invoke(&uv_prepare_stop, get<uv_prepare_t>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
145
src/uvw/process.hpp
Normal file
145
src/uvw/process.hpp
Normal file
@ -0,0 +1,145 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <uv.h>
|
||||
#include "event.hpp"
|
||||
#include "handle.hpp"
|
||||
#include "stream.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
|
||||
namespace uvw {
|
||||
|
||||
|
||||
namespace details {
|
||||
|
||||
|
||||
enum class UVProcessFlags: std::underlying_type_t<uv_process_flags> {
|
||||
PROCESS_SETUID = UV_PROCESS_SETUID,
|
||||
PROCESS_SETGID = UV_PROCESS_SETGID,
|
||||
PROCESS_WINDOWS_VERBATIM_ARGUMENTS = UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
|
||||
PROCESS_DETACHED = UV_PROCESS_DETACHED,
|
||||
PROCESS_WINDOWS_HIDE = UV_PROCESS_WINDOWS_HIDE
|
||||
};
|
||||
|
||||
|
||||
enum class UVStdIOFlags: std::underlying_type_t<uv_stdio_flags> {
|
||||
IGNORE = UV_IGNORE,
|
||||
CREATE_PIPE = UV_CREATE_PIPE,
|
||||
INHERIT_FD = UV_INHERIT_FD,
|
||||
INHERIT_STREAM = UV_INHERIT_STREAM,
|
||||
READABLE_PIPE = UV_READABLE_PIPE,
|
||||
WRITABLE_PIPE = UV_WRITABLE_PIPE
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct ExitEvent: Event<ExitEvent> { };
|
||||
|
||||
|
||||
class ProcessHandle final: public Handle<ProcessHandle, uv_process_t> {
|
||||
static void exitCallback(uv_process_t *handle, int64_t exitStatus, int termSignal) {
|
||||
ProcessHandle &process = *(static_cast<ProcessHandle*>(handle->data));
|
||||
process.publish(ExitEvent{});
|
||||
}
|
||||
|
||||
using Handle::Handle;
|
||||
|
||||
public:
|
||||
using Process = details::UVProcessFlags;
|
||||
using StdIO = details::UVStdIOFlags;
|
||||
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<ProcessHandle> create(Args&&... args) {
|
||||
return std::shared_ptr<ProcessHandle>{new ProcessHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
static void disableStdIOInheritance() noexcept {
|
||||
uv_disable_stdio_inheritance();
|
||||
}
|
||||
|
||||
bool init() const noexcept { return true; }
|
||||
|
||||
void spawn(const char *file, char **args, char **env = nullptr) {
|
||||
uv_process_options_t po;
|
||||
|
||||
po.exit_cb = &exitCallback;
|
||||
|
||||
po.file = file;
|
||||
po.args = args;
|
||||
po.env = env;
|
||||
|
||||
po.cwd = poCwd.data();
|
||||
po.flags = poFlags;
|
||||
po.stdio_count = poStdio.size();
|
||||
po.stdio = poStdio.data();
|
||||
po.uid = poUid;
|
||||
po.gid = poGid;
|
||||
|
||||
invoke(&uv_spawn, parent(), get<uv_process_t>(), &po);
|
||||
}
|
||||
|
||||
void kill(int signum) {
|
||||
invoke(&uv_process_kill, get<uv_process_t>(), signum);
|
||||
}
|
||||
|
||||
static bool kill(int pid, int signum) noexcept {
|
||||
return (0 == uv_kill(pid, signum));
|
||||
}
|
||||
|
||||
int pid() noexcept {
|
||||
return get<uv_process_t>()->pid;
|
||||
}
|
||||
|
||||
ProcessHandle& cwd(std::string &path) noexcept {
|
||||
poCwd = path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ProcessHandle& flags(Flags<Process> flags) noexcept {
|
||||
poFlags = flags;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
ProcessHandle& stdio(Flags<StdIO> flags, StreamHandle<T, U> &stream) {
|
||||
uv_stdio_container_t container;
|
||||
container.flags = flags;
|
||||
container.data.stream = stream.get<uv_stream_t>();
|
||||
poStdio.push_back(std::move(container));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ProcessHandle& stdio(Flags<StdIO> flags, FileHandle fd) {
|
||||
uv_stdio_container_t container;
|
||||
container.flags = flags;
|
||||
container.data.fd = fd;
|
||||
poStdio.push_back(std::move(container));
|
||||
return *this;
|
||||
}
|
||||
|
||||
ProcessHandle& uid(Uid id) {
|
||||
poUid = id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ProcessHandle& gid(Gid id) {
|
||||
poGid = id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string poCwd;
|
||||
Flags<Process> poFlags;
|
||||
std::vector<uv_stdio_container_t> poStdio;
|
||||
Uid poUid;
|
||||
Gid poGid;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@ -27,13 +27,19 @@ protected:
|
||||
this->template get<U>()->data = static_cast<T*>(this);
|
||||
}
|
||||
|
||||
auto parent() const noexcept { return pLoop->loop.get(); }
|
||||
auto parent() const noexcept {
|
||||
return pLoop->loop.get();
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
auto get() noexcept { return reinterpret_cast<R*>(&resource); }
|
||||
auto get() noexcept {
|
||||
return reinterpret_cast<R*>(&resource);
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
auto get() const noexcept { return reinterpret_cast<const R*>(&resource); }
|
||||
auto get() const noexcept {
|
||||
return reinterpret_cast<const R*>(&resource);
|
||||
}
|
||||
|
||||
public:
|
||||
Resource(const Resource &) = delete;
|
||||
|
||||
@ -9,9 +9,17 @@ namespace uvw {
|
||||
|
||||
template<typename T>
|
||||
struct Self: std::enable_shared_from_this<T> {
|
||||
void leak() noexcept { ptr = this->shared_from_this(); }
|
||||
void reset() noexcept { ptr.reset(); }
|
||||
bool self() const noexcept { return static_cast<bool>(ptr); }
|
||||
void leak() noexcept {
|
||||
ptr = this->shared_from_this();
|
||||
}
|
||||
|
||||
void reset() noexcept {
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
bool self() const noexcept {
|
||||
return static_cast<bool>(ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<void> ptr{nullptr};
|
||||
|
||||
@ -36,12 +36,21 @@ public:
|
||||
return std::shared_ptr<SignalHandle>{new SignalHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_signal_t>(&uv_signal_init); }
|
||||
bool init() {
|
||||
return initialize<uv_signal_t>(&uv_signal_init);
|
||||
}
|
||||
|
||||
void start(int signum) { invoke(&uv_signal_start, get<uv_signal_t>(), &startCallback, signum); }
|
||||
void stop() { invoke(&uv_signal_stop, get<uv_signal_t>()); }
|
||||
void start(int signum) {
|
||||
invoke(&uv_signal_start, get<uv_signal_t>(), &startCallback, signum);
|
||||
}
|
||||
|
||||
int signal() const noexcept { return get<uv_signal_t>()->signum; }
|
||||
void stop() {
|
||||
invoke(&uv_signal_stop, get<uv_signal_t>());
|
||||
}
|
||||
|
||||
int signal() const noexcept {
|
||||
return get<uv_signal_t>()->signum;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -41,7 +41,9 @@ public:
|
||||
return std::shared_ptr<TcpHandle>{new TcpHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_tcp_t>(&uv_tcp_init); }
|
||||
bool init() {
|
||||
return initialize<uv_tcp_t>(&uv_tcp_init);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
bool init(T&& t, Args&&... args) {
|
||||
@ -102,7 +104,9 @@ public:
|
||||
}
|
||||
|
||||
template<typename I = IPv4>
|
||||
void connect(Addr addr) { connect<I>(addr.ip, addr.port); }
|
||||
void connect(Addr addr) {
|
||||
connect<I>(addr.ip, addr.port);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -32,14 +32,29 @@ public:
|
||||
return std::shared_ptr<TimerHandle>{new TimerHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_timer_t>(&uv_timer_init); }
|
||||
bool init() {
|
||||
return initialize<uv_timer_t>(&uv_timer_init);
|
||||
}
|
||||
|
||||
void start(Time timeout, Time repeat) { invoke(&uv_timer_start, get<uv_timer_t>(), &startCallback, timeout.count(), repeat.count()); }
|
||||
void stop() { invoke(&uv_timer_stop, get<uv_timer_t>()); }
|
||||
void again() { invoke(&uv_timer_again, get<uv_timer_t>()); }
|
||||
void start(Time timeout, Time repeat) {
|
||||
invoke(&uv_timer_start, get<uv_timer_t>(), &startCallback, timeout.count(), repeat.count());
|
||||
}
|
||||
|
||||
void repeat(Time repeat) { uv_timer_set_repeat(get<uv_timer_t>(), repeat.count()); }
|
||||
Time repeat() { return Time{uv_timer_get_repeat(get<uv_timer_t>())}; }
|
||||
void stop() {
|
||||
invoke(&uv_timer_stop, get<uv_timer_t>());
|
||||
}
|
||||
|
||||
void again() {
|
||||
invoke(&uv_timer_again, get<uv_timer_t>());
|
||||
}
|
||||
|
||||
void repeat(Time repeat) {
|
||||
uv_timer_set_repeat(get<uv_timer_t>(), repeat.count());
|
||||
}
|
||||
|
||||
Time repeat() {
|
||||
return Time{uv_timer_get_repeat(get<uv_timer_t>())};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -16,6 +16,13 @@ namespace uvw {
|
||||
namespace details {
|
||||
|
||||
|
||||
struct ResetModeMemo {
|
||||
~ResetModeMemo() {
|
||||
uv_tty_reset_mode();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
enum class UVTTYModeT: std::underlying_type_t<uv_tty_mode_t> {
|
||||
NORMAL = UV_TTY_MODE_NORMAL,
|
||||
RAW = UV_TTY_MODE_RAW,
|
||||
@ -29,8 +36,12 @@ enum class UVTTYModeT: std::underlying_type_t<uv_tty_mode_t> {
|
||||
class TTYHandle final: public StreamHandle<TTYHandle, uv_tty_t> {
|
||||
explicit TTYHandle(std::shared_ptr<Loop> ref,
|
||||
FileHandle desc,
|
||||
bool readable)
|
||||
: StreamHandle{std::move(ref)}, fd{desc}, rw{readable}
|
||||
bool readable,
|
||||
std::shared_ptr<details::ResetModeMemo> rmm)
|
||||
: StreamHandle{std::move(ref)},
|
||||
memo{std::move(rmm)},
|
||||
fd{desc},
|
||||
rw{readable}
|
||||
{ }
|
||||
|
||||
public:
|
||||
@ -38,10 +49,15 @@ public:
|
||||
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<TTYHandle> create(Args&&... args) {
|
||||
return std::shared_ptr<TTYHandle>{new TTYHandle{std::forward<Args>(args)...}};
|
||||
static std::weak_ptr<details::ResetModeMemo> rmm;
|
||||
auto ptr = rmm.lock();
|
||||
if(!ptr) { rmm = ptr = std::make_shared<details::ResetModeMemo>(); }
|
||||
return std::shared_ptr<TTYHandle>{new TTYHandle{std::forward<Args>(args)..., ptr}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_tty_t>(&uv_tty_init, fd, rw); }
|
||||
bool init() {
|
||||
return initialize<uv_tty_t>(&uv_tty_init, fd, rw);
|
||||
}
|
||||
|
||||
void mode(Mode m) {
|
||||
// uv_tty_set_mode is inline, it cannot be used with invoke directly
|
||||
@ -50,7 +66,9 @@ public:
|
||||
}, get<uv_tty_t>(), static_cast<std::underlying_type_t<Mode>>(m));
|
||||
}
|
||||
|
||||
void reset() { invoke(&uv_tty_reset_mode); }
|
||||
void reset() noexcept {
|
||||
invoke(&uv_tty_reset_mode);
|
||||
}
|
||||
|
||||
WinSize getWinSize() {
|
||||
std::pair<int, int> size{0, 0};
|
||||
@ -70,6 +88,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<details::ResetModeMemo> memo;
|
||||
FileHandle::Type fd;
|
||||
int rw;
|
||||
};
|
||||
|
||||
@ -106,7 +106,9 @@ public:
|
||||
return std::shared_ptr<UdpHandle>{new UdpHandle{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
bool init() { return initialize<uv_udp_t>(&uv_udp_init); }
|
||||
bool init() {
|
||||
return initialize<uv_udp_t>(&uv_udp_init);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
bool init(T&& t, Args&&... args) {
|
||||
@ -152,8 +154,13 @@ public:
|
||||
invoke(&uv_udp_set_multicast_interface, get<uv_udp_t>(), interface.data());
|
||||
}
|
||||
|
||||
void broadcast(bool enable = false) { invoke(&uv_udp_set_broadcast, get<uv_udp_t>(), enable); }
|
||||
void ttl(int val) { invoke(&uv_udp_set_ttl, get<uv_udp_t>(), val > 255 ? 255 : val); }
|
||||
void broadcast(bool enable = false) {
|
||||
invoke(&uv_udp_set_broadcast, get<uv_udp_t>(), enable);
|
||||
}
|
||||
|
||||
void ttl(int val) {
|
||||
invoke(&uv_udp_set_ttl, get<uv_udp_t>(), val > 255 ? 255 : val);
|
||||
}
|
||||
|
||||
template<typename I = IPv4>
|
||||
void send(std::string ip, unsigned int port, std::unique_ptr<char[]> data, ssize_t len) {
|
||||
@ -193,7 +200,9 @@ public:
|
||||
invoke(&uv_udp_recv_start, get<uv_udp_t>(), &allocCallback, &recvCallback<I>);
|
||||
}
|
||||
|
||||
void stop() { invoke(&uv_udp_recv_stop, get<uv_udp_t>()); }
|
||||
void stop() {
|
||||
invoke(&uv_udp_recv_stop, get<uv_udp_t>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -30,10 +30,20 @@ public:
|
||||
|
||||
~Flags() noexcept { static_assert(std::is_enum<E>::value, "!"); }
|
||||
|
||||
constexpr Flags operator|(const Flags& f) const noexcept { return Flags(flags | f.flags); }
|
||||
constexpr Flags& operator=(const Flags &f) noexcept {
|
||||
flags = f.flags;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Flags& operator=(Flags &&f) noexcept {
|
||||
flags = std::move(f.flags);
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Flags operator|(const Flags &f) const noexcept { return Flags(flags | f.flags); }
|
||||
constexpr Flags operator|(E flag) const noexcept { return Flags(flags | toInnerType(flag)); }
|
||||
|
||||
constexpr Flags operator&(const Flags& f) const noexcept { return Flags(flags & f.flags); }
|
||||
constexpr Flags operator&(const Flags &f) const noexcept { return Flags(flags & f.flags); }
|
||||
constexpr Flags operator&(E flag) const noexcept { return Flags(flags & toInnerType(flag)); }
|
||||
|
||||
explicit constexpr operator bool() const noexcept { return !(flags == InnerType{}); }
|
||||
|
||||
@ -17,24 +17,26 @@ struct WorkEvent: Event<WorkEvent> { };
|
||||
|
||||
|
||||
class WorkReq final: public Request<WorkReq, uv_work_t> {
|
||||
using InternalTask = std::function<void(void)>;
|
||||
|
||||
static void workCallback(uv_work_t *req) {
|
||||
static_cast<WorkReq*>(req->data)->task();
|
||||
}
|
||||
|
||||
using Request::Request;
|
||||
explicit WorkReq(std::shared_ptr<Loop> ref, InternalTask t)
|
||||
: Request{std::move(ref)}, task{t}
|
||||
{ }
|
||||
|
||||
public:
|
||||
using Task = std::function<void(void)>;
|
||||
using Task = InternalTask;
|
||||
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<WorkReq> create(Args&&... args) {
|
||||
return std::shared_ptr<WorkReq>{new WorkReq{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
void queue(Task t) {
|
||||
if(0 == invoke(&uv_queue_work, parent(), get<uv_work_t>(), &workCallback, &defaultCallback<uv_work_t, WorkEvent>)) {
|
||||
task = std::move(t);
|
||||
}
|
||||
void queue() {
|
||||
invoke(&uv_queue_work, parent(), get<uv_work_t>(), &workCallback, &defaultCallback<uv_work_t, WorkEvent>);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -15,7 +15,7 @@ TEST(Loop, Basics) {
|
||||
|
||||
auto loop = uvw::Loop::create();
|
||||
auto handle = loop->resource<uvw::PrepareHandle>();
|
||||
auto req = loop->resource<uvw::WorkReq>();
|
||||
auto req = loop->resource<uvw::WorkReq>([](){});
|
||||
|
||||
auto err = [](uvw::ErrorEvent, auto &) { ASSERT_TRUE(false); };
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user