diff --git a/build.zig b/build.zig index 3a85057..94553ca 100644 --- a/build.zig +++ b/build.zig @@ -3,6 +3,7 @@ const std = @import("std"); const CrossTarget = std.zig.CrossTarget; const cppflags = [_][]const u8{ + "-DASIO_HAS_THREADS", "-fcolor-diagnostics", "-std=c++20", "-Wall", @@ -65,6 +66,10 @@ pub fn build(b: *std.Build) void { lib.linkLibrary(tracy_dep.artifact("tracy")); } lib.linkLibrary(asio_dep.artifact("asio")); + if (lib.rootModuleTarget().os.tag == .windows) { + lib.linkSystemLibrary("mswsock"); + lib.linkSystemLibrary("ws2_32"); + } lib.linkLibCpp(); b.installArtifact(lib); diff --git a/include/cbor/cbor_in.hpp b/include/cbor/cbor_in.hpp index a2b6bd2..e34e52b 100644 --- a/include/cbor/cbor_in.hpp +++ b/include/cbor/cbor_in.hpp @@ -3,7 +3,12 @@ #include "cbor.hpp" #include + +#if !defined(_WIN32) #include +#else +#include +#endif namespace cbor { diff --git a/include/thespian/tcp.hpp b/include/thespian/tcp.hpp index a996692..076580c 100644 --- a/include/thespian/tcp.hpp +++ b/include/thespian/tcp.hpp @@ -1,10 +1,15 @@ #pragma once #include -#include #include #include +#if !defined(_WIN32) +#include +#else +#include +#endif + using port_t = unsigned short; namespace thespian::tcp { diff --git a/src/backtrace.cpp b/src/backtrace.cpp index 5e24c3d..dcf1e6c 100644 --- a/src/backtrace.cpp +++ b/src/backtrace.cpp @@ -1,4 +1,4 @@ -#ifndef __APPLE__ +#if !defined(_WIN32) && !defined(__APPLE__) #include #include diff --git a/src/executor.hpp b/src/executor.hpp index 3237933..29feb82 100644 --- a/src/executor.hpp +++ b/src/executor.hpp @@ -5,10 +5,15 @@ #include #include #include -#include #include #include +#if !defined(_WIN32) +#include +#else +#include +#endif + using port_t = unsigned short; namespace thespian::executor { diff --git a/src/executor_asio.cpp b/src/executor_asio.cpp index 77fbc24..7577762 100644 --- a/src/executor_asio.cpp +++ b/src/executor_asio.cpp @@ -1,4 +1,3 @@ -#include "asio/error_code.hpp" #include "asio/posix/descriptor_base.hpp" #include "executor.hpp" #include @@ -11,13 +10,19 @@ #include #include #include -#include #include #include #include #include #include +#if !defined(_WIN32) +#include +#else +#include +#include +#endif + #include #include @@ -27,7 +32,6 @@ using asio::io_context; using asio::string_view; using asio::system_timer; using asio::thread; -using asio::posix::stream_descriptor; using std::atomic; using std::error_code; using std::function; @@ -46,13 +50,30 @@ using std::chrono::microseconds; using std::chrono::system_clock; using std::chrono::time_point; +#if !defined(_WIN32) +using asio::posix::stream_descriptor; +#else +using asio::windows::stream_handle; +#endif + namespace thespian::executor { const char *MAX_THREAD_STR = getenv("MAX_THREAD"); // NOLINT const auto MAX_THREAD = static_cast(atoi(MAX_THREAD_STR ? MAX_THREAD_STR : "64")); // NOLINT +#if !defined(_WIN32) const auto threads = min(sysconf(_SC_NPROCESSORS_ONLN), MAX_THREAD); +#else +namespace { +static long get_num_processors() { + SYSTEM_INFO si; + GetSystemInfo(&si); + return si.dwNumberOfProcessors; +} +} // namespace +const auto threads = min(get_num_processors(), MAX_THREAD); +#endif struct context_impl { context_impl() : asio{make_unique(threads)} {} @@ -62,8 +83,10 @@ struct context_impl { }; auto context::create() -> context { +#if !defined(_WIN32) if (::signal(SIGPIPE, SIG_IGN) == SIG_ERR) // NOLINT abort(); +#endif return {context_ref(new context_impl(), [](context_impl *p) { delete p; })}; } @@ -225,7 +248,7 @@ struct socket_impl { socket_{*ctx->asio, ::asio::ip::udp::v6()} {} auto bind(const in6_addr &ip, port_t port) -> error_code { error_code ec; - socket_.bind(to_endpoint_udp(ip, port), ec); + ec = socket_.bind(to_endpoint_udp(ip, port), ec); return ec; } [[nodiscard]] auto send_to(string_view data, in6_addr ip, port_t port) @@ -305,7 +328,7 @@ struct socket_impl { socket_{*ctx->asio, asio::ip::tcp::v6(), fd} {} auto bind(const in6_addr &ip, port_t port) -> error_code { error_code ec; - socket_.bind(to_endpoint_tcp(ip, port), ec); + ec = socket_.bind(to_endpoint_tcp(ip, port), ec); return ec; } void connect(const in6_addr &ip, port_t port, socket::connect_handler h) { @@ -382,7 +405,9 @@ void socket::write(const vector &data, write_handler h) { void socket::read(read_handler h) { ref->read(*this, move(h)); } void socket::close() { ref->close(); } +#if !defined(_WIN32) void socket::close(int fd) { ::close(fd); } +#endif auto socket::release() -> int { return ref->release(); } auto socket::local_endpoint() const -> const endpoint & { @@ -395,12 +420,12 @@ struct acceptor_impl { acceptor_{*ctx->asio, asio::ip::tcp::v6()}, socket_{*ctx->asio} {} auto bind(const in6_addr &ip, port_t port) -> error_code { error_code ec; - acceptor_.bind(to_endpoint_tcp(ip, port), ec); + ec = acceptor_.bind(to_endpoint_tcp(ip, port), ec); return ec; } auto listen() -> error_code { error_code ec; - acceptor_.listen(asio::socket_base::max_listen_connections, ec); + ec = acceptor_.listen(asio::socket_base::max_listen_connections, ec); return ec; } void accept(acceptor::handler h) { @@ -412,7 +437,9 @@ struct acceptor_impl { t = move(weak_token)](const error_code &ec) { c->pending.fetch_sub(1, memory_order_relaxed); if (auto p = t.lock()) - h(ec ? 0 : s->release(), ec); + h(ec ? static_cast(0) + : s->release(), + ec); })); } void close() { acceptor_.close(); } @@ -454,14 +481,14 @@ namespace unx { struct socket_impl { explicit socket_impl(strand &strand) - : ctx{strand.ref->ctx}, strand_{strand.ref->strand_}, socket_{ - *ctx->asio} {} + : ctx{strand.ref->ctx}, strand_{strand.ref->strand_}, + socket_{*ctx->asio} {} explicit socket_impl(strand &strand, int fd) - : ctx{strand.ref->ctx}, strand_{strand.ref->strand_}, socket_{*ctx->asio, - fd} {} + : ctx{strand.ref->ctx}, strand_{strand.ref->strand_}, + socket_{*ctx->asio, fd} {} auto bind(string_view path) -> error_code { error_code ec; - socket_.bind(path, ec); + ec = socket_.bind(path, ec); return ec; } void connect(string_view path, socket::connect_handler h) { @@ -537,12 +564,12 @@ struct acceptor_impl { socket_{*ctx->asio} {} auto bind(string_view path) -> error_code { error_code ec; - acceptor_.bind(path, ec); + ec = acceptor_.bind(path, ec); return ec; } auto listen() -> error_code { error_code ec; - acceptor_.listen(asio::socket_base::max_listen_connections, ec); + ec = acceptor_.listen(asio::socket_base::max_listen_connections, ec); return ec; } void accept(acceptor::handler h) { @@ -554,7 +581,10 @@ struct acceptor_impl { t = move(weak_token)](const error_code &ec) { c->pending.fetch_sub(1, memory_order_relaxed); if (auto p = t.lock()) - h(ec ? 0 : s->release(), ec); + h(ec ? static_cast(0) + : s->release(), + ec); })); } void close() { acceptor_.close(); } @@ -579,12 +609,13 @@ void acceptor::close() { ref->close(); } } // namespace unx +#if !defined(_WIN32) namespace file_descriptor { struct watcher_impl { explicit watcher_impl(strand &strand, int fd) - : ctx{strand.ref->ctx}, strand_{strand.ref->strand_}, fd_{*ctx->asio, - fd} {} + : ctx{strand.ref->ctx}, strand_{strand.ref->strand_}, + fd_{*ctx->asio, fd} {} void wait_read(watcher::handler h) { if (!read_in_progress_) { @@ -641,5 +672,6 @@ void watcher::wait_write(watcher::handler h) { ref->wait_write(move(h)); } void watcher::cancel() { ref->cancel(); } } // namespace file_descriptor +#endif } // namespace thespian::executor diff --git a/src/hub.cpp b/src/hub.cpp index 6ee3eba..afc693a 100644 --- a/src/hub.cpp +++ b/src/hub.cpp @@ -100,7 +100,9 @@ struct hub_impl { string_view desc; if (msg("listen", extract(desc))) { +#if !defined(_WIN32) thespian::endpoint::unx::listen(desc); +#endif } if (msg("shutdown")) diff --git a/src/instance.cpp b/src/instance.cpp index 1061e19..d235008 100644 --- a/src/instance.cpp +++ b/src/instance.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -26,13 +25,25 @@ #include #include #include -#include #include #include #include #include #include +#if !defined(_WIN32) + +#include + +#else + +#include +#include +#include +#include + +#endif + #ifdef TRACY_ENABLE #include #endif @@ -850,6 +861,7 @@ auto udp::create(string tag) -> udp { return {udp_ref(new udp_impl(move(tag)), [](udp_impl *p) { delete p; })}; } +#if !defined(_WIN32) struct file_descriptor_impl { file_descriptor_impl(const file_descriptor_impl &) = delete; file_descriptor_impl(file_descriptor_impl &&) = delete; @@ -913,6 +925,7 @@ void file_descriptor::wait_write(file_descriptor_impl *p) { p->wait_write(); } void file_descriptor::wait_read(file_descriptor_impl *p) { p->wait_read(); } void file_descriptor::cancel(file_descriptor_impl *p) { p->cancel(); } void file_descriptor::destroy(file_descriptor_impl *p) { delete p; } +#endif struct socket_impl { socket_impl(const socket_impl &) = delete; @@ -1568,6 +1581,7 @@ auto connect(in6_addr ip, port_t port, milliseconds retry_time, } // namespace tcp +#if !defined(_WIN32) namespace unx { struct connector { @@ -1651,8 +1665,8 @@ struct acceptor { string listen_path; acceptor(string_view path, mode m, handle o) - : a{::thespian::unx::acceptor::create(tag)}, owner{move(o)}, listen_path{ - path} { + : a{::thespian::unx::acceptor::create(tag)}, owner{move(o)}, + listen_path{path} { a.listen(path, m); } ~acceptor() = default; @@ -1703,6 +1717,7 @@ auto connect(string_view path, mode m, milliseconds retry_time, } } // namespace unx +#endif } // namespace endpoint namespace debug { diff --git a/test/debug.cpp b/test/debug.cpp index 0a1399c..36563fe 100644 --- a/test/debug.cpp +++ b/test/debug.cpp @@ -7,10 +7,16 @@ #include #include -#include #include #include +#if defined(_WIN32) +#include +#include +#include +#include +#endif + using cbor::buffer; using cbor::extract; using std::make_shared; diff --git a/test/endpoint_tcp.cpp b/test/endpoint_tcp.cpp index 7cdb52e..593372d 100644 --- a/test/endpoint_tcp.cpp +++ b/test/endpoint_tcp.cpp @@ -9,9 +9,15 @@ #include #include -#include #include +#if defined(_WIN32) +#include +#include +#include +#include +#endif + using cbor::any; using cbor::buffer; using cbor::extract; diff --git a/test/endpoint_unx.cpp b/test/endpoint_unx.cpp index 88233d2..f3783ad 100644 --- a/test/endpoint_unx.cpp +++ b/test/endpoint_unx.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -38,6 +37,7 @@ using thespian::unx::mode; using namespace std::chrono_literals; +#if !defined(_WIN32) namespace { struct controller { @@ -102,3 +102,12 @@ auto endpoint_unx(context &ctx, bool &result, env_t env_) -> ::result { }, "endpoint_unx", move(env_))); } + +#else + +auto endpoint_unx(context &, bool &result, env_t) -> ::result { + result = true; + return ok(); +} + +#endif diff --git a/test/ip_tcp_client_server.cpp b/test/ip_tcp_client_server.cpp index 3ba3c28..3cc630f 100644 --- a/test/ip_tcp_client_server.cpp +++ b/test/ip_tcp_client_server.cpp @@ -7,7 +7,14 @@ #include #include +#if !defined(_WIN32) #include +#else +#include +#include +#include +#include +#endif using cbor::buffer; using cbor::extract; diff --git a/test/ip_udp_echo.cpp b/test/ip_udp_echo.cpp index fb0c1bc..65264b0 100644 --- a/test/ip_udp_echo.cpp +++ b/test/ip_udp_echo.cpp @@ -6,7 +6,14 @@ #include #include +#if !defined(_WIN32) #include +#else +#include +#include +#include +#include +#endif using cbor::array; using cbor::buffer; diff --git a/test/tests.cpp b/test/tests.cpp index aa3c0aa..555cfde 100644 --- a/test/tests.cpp +++ b/test/tests.cpp @@ -16,7 +16,6 @@ #include #include #include -#include using cbor::buffer; using std::cerr; @@ -81,8 +80,10 @@ struct logger { extern "C" auto runtestcase(const char *name) -> int { mutex trace_m; +#if !defined(_WIN32) if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) // NOLINT abort(); +#endif auto gdb = getenv("JITDEBUG"); // NOLINT diff --git a/zig b/zig index e12064e..31baf97 100755 --- a/zig +++ b/zig @@ -47,10 +47,11 @@ get_zig() { get_zig if [ "$1" == "cdb" ] ; then - rm -rf zig-cache + shift + rm -rf .zig-cache rm -rf .cache/cdb - $ZIG build + $ZIG build "$@" (echo \[ ; cat .cache/cdb/* ; echo {}\]) | perl -0777 -pe 's/,\n\{\}//igs' | jq . | grep -v 'no-default-config' > compile_commands.json exit 0