diff --git a/.github/workflows/ci.macos.arm.yml b/.github/workflows/ci.macos.arm.yml index 453df4ab..dc0883e0 100644 --- a/.github/workflows/ci.macos.arm.yml +++ b/.github/workflows/ci.macos.arm.yml @@ -6,7 +6,7 @@ on: jobs: macOS14-arm: - runs-on: macos-14 + runs-on: macos-15 steps: - uses: szenius/set-timezone@v2.0 @@ -31,7 +31,7 @@ jobs: -D CMAKE_BUILD_TYPE=MinSizeRel \ -D PHOTON_ENABLE_SASL=ON \ -D PHOTON_ENABLE_LIBCURL=ON \ - -D OPENSSL_ROOT_DIR=/opt/homebrew/Cellar/openssl@1.1/1.1.1w + -D OPENSSL_ROOT_DIR=/opt/homebrew/Cellar/openssl@3/3.6.0 cmake --build ${{github.workspace}}/build -j $(sysctl -n hw.logicalcpu) - name: Test diff --git a/.github/workflows/ci.macos.x86_64.yml b/.github/workflows/ci.macos.x86_64.yml index f11219d6..8e544ba5 100644 --- a/.github/workflows/ci.macos.x86_64.yml +++ b/.github/workflows/ci.macos.x86_64.yml @@ -6,7 +6,7 @@ on: jobs: macOS13-x86: - runs-on: macos-13 + runs-on: macos-15 steps: - uses: szenius/set-timezone@v2.0 @@ -31,7 +31,7 @@ jobs: -D CMAKE_BUILD_TYPE=MinSizeRel \ -D PHOTON_ENABLE_SASL=ON \ -D PHOTON_ENABLE_LIBCURL=ON \ - -D OPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 + -D OPENSSL_ROOT_DIR=/opt/homebrew/Cellar/openssl@3/3.6.0 cmake --build ${{github.workspace}}/build -j $(sysctl -n hw.logicalcpu) - name: Test diff --git a/common/estring.h b/common/estring.h index c779477a..b0ec6498 100644 --- a/common/estring.h +++ b/common/estring.h @@ -195,10 +195,10 @@ class estring_view : public std::string_view } iterator& operator++() { - _part = _host->find_part(_part.end()); + _part = _host->find_part(_part.end() + 1); return *this; } - iterator& operator++(int) + iterator operator++(int) { auto ret = *this; ++(*this); @@ -206,7 +206,8 @@ class estring_view : public std::string_view } bool operator == (const iterator& rhs) const { - return _part == rhs._part; + return _part.data() == rhs._part.data() && + _part.length() == rhs._part.length(); } bool operator != (const iterator& rhs) const { diff --git a/common/test/test.cpp b/common/test/test.cpp index d8a7ac93..b33f7d85 100644 --- a/common/test/test.cpp +++ b/common/test/test.cpp @@ -865,6 +865,51 @@ TEST(estring, test) EXPECT_EQ(a[1], "q3r1234"); EXPECT_EQ(a[2], "poiu"); + sp = s.split(cs, false); + it = sp.begin(); + front = *it; + remainder = it.remainder(); + LOG_DEBUG(VALUE(front), VALUE(remainder)); + EXPECT_EQ(front, "alskdjf"); + EXPECT_EQ(remainder, ";;,q3r1234;poiu"); + it ++; + front = *it; + remainder = it.remainder(); + LOG_DEBUG(VALUE(front), VALUE(remainder)); + EXPECT_EQ(front, ""); + EXPECT_EQ(remainder, ";,q3r1234;poiu"); + it ++; + front = *it; + remainder = it.remainder(); + LOG_DEBUG(VALUE(front), VALUE(remainder)); + EXPECT_EQ(front, ""); + EXPECT_EQ(remainder, ",q3r1234;poiu"); + it ++; + front = *it; + remainder = it.remainder(); + LOG_DEBUG(VALUE(front), VALUE(remainder)); + EXPECT_EQ(front, ""); + EXPECT_EQ(remainder, "q3r1234;poiu"); + it ++; + front = *it; + remainder = it.remainder(); + LOG_DEBUG(VALUE(front), VALUE(remainder)); + EXPECT_EQ(front, "q3r1234"); + EXPECT_EQ(remainder, "poiu"); + + a.clear(); + for (auto x: sp) + { + a.push_back(x); + LOG_DEBUG(x); + } + + EXPECT_EQ(a.size(), 6); + EXPECT_EQ(a[0], "alskdjf"); + EXPECT_EQ(a[4], "q3r1234"); + EXPECT_EQ(a[5], "poiu"); + + auto sv = s;//.view(); EXPECT_TRUE(sv.starts_with("alskdjf")); EXPECT_FALSE(sv.starts_with("alsk32")); diff --git a/net/utils.cpp b/net/utils.cpp index e3fcbbb2..c8aaf5de 100644 --- a/net/utils.cpp +++ b/net/utils.cpp @@ -266,36 +266,59 @@ class DefaultResolver : public Resolver { struct IPAddrList : public intrusive_list, spinlock { ~IPAddrList() { delete_all(); } }; + struct ResolveCtx { + std::string host; + Delegate filter; + spinlock lock; + IPAddrList *addrs; + photon::semaphore sem; + }; IPAddr do_resolve(std::string_view host, Delegate filter) { auto ctr = [&]() -> IPAddrList* { auto addrs = new IPAddrList(); - photon::semaphore sem; - std::thread([&]() { - auto now = std::chrono::steady_clock::now(); + std::shared_ptr ctx = std::make_shared(); + ctx->addrs = addrs; + ctx->host = std::string(host); + ctx->filter = filter; + std::thread([ctx]() { IPAddrList ret; auto cb = [&](IPAddr addr) -> int { - if (filter && !filter.fire(addr)) + SCOPED_LOCK(ctx->lock); + if (ctx->filter && !ctx->filter.fire(addr)) return 0; ret.push_back(new IPAddrNode(addr)); return 0; }; - _gethostbyname(host, cb); - auto time_elapsed = std::chrono::duration_cast( - std::chrono::steady_clock::now() - now).count(); - if ((uint64_t)time_elapsed <= resolve_timeout_) { - addrs->push_back(std::move(ret)); - sem.signal(1); - } else { - LOG_ERROR("resolve timeout"); - while(!ret.empty()) - delete ret.pop_front(); + _gethostbyname(ctx->host, cb); + { + SCOPED_LOCK(ctx->lock); + if (ctx->addrs) { + ctx->addrs->push_back(std::move(ret)); + ctx->sem.signal(1); + } else { + LOG_ERROR("resolve timeout"); + while(!ret.empty()) + delete ret.pop_front(); + } } }).detach(); - sem.wait(1, resolve_timeout_); + ctx->sem.wait(1, resolve_timeout_); + { + SCOPED_LOCK(ctx->lock); + ctx->addrs = nullptr; + ctx->filter = {}; + } + if (addrs->empty()) { + delete addrs; + return nullptr; + } return addrs; }; auto ips = dnscache_.borrow(host, ctr); - if (ips->empty()) LOG_ERRNO_RETURN(0, IPAddr(), "Domain resolution for '`' failed", host); + if (!ips || ips->empty()) { + ips.recycle(true); + LOG_ERRNO_RETURN(0, IPAddr(), "Domain resolution for '`' failed", host); + } SCOPED_LOCK(*ips); auto ret = ips->front(); ips->node = ret->next(); // access in round robin order