diff --git a/CMakeLists.txt b/CMakeLists.txt index a8dce7d..bc6456a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,19 +35,6 @@ FetchContent_Declare( FetchContent_MakeAvailable(abseil) # Abseil provides targets like absl::base, absl::strings, etc. -# --- External Dependency: co --- -# cpp_toolbelt depends on co, so we need to fetch and make it available. -FetchContent_Declare( - co - GIT_REPOSITORY https://github.com/dallison/co.git - GIT_TAG cf1252b2f5952d7cba83b67dd69288971c0a2b57 - # Pass architecture settings to co's CMake build - CMAKE_ARGS - CMAKE_OSX_ARCHITECTURES="${CMAKE_OSX_ARCHITECTURES}" -) -FetchContent_MakeAvailable(co) -# co provides the 'co' target. - # --- toolbelt Library Target --- # Corresponds to //toolbelt:toolbelt in Bazel # Source files are omitted here for manual addition by the user. @@ -67,6 +54,8 @@ add_library(toolbelt STATIC toolbelt/payload_buffer.h toolbelt/pipe.cc toolbelt/pipe.h + toolbelt/poller.cc + toolbelt/poller.h toolbelt/sockets.cc toolbelt/sockets.h toolbelt/table.cc @@ -88,7 +77,6 @@ target_link_libraries(toolbelt PUBLIC absl::log # Added as it's used by toolbelt/logging absl::time # Added as it's used by toolbelt/time absl::synchronization # Added as it's used by toolbelt/utilities/thread_pool - co # Link against the co library ) # Note: If there are tests in cpp_toolbelt, they would need a separate target diff --git a/MODULE.bazel b/MODULE.bazel index 2927f4d..6ac0fca 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -15,4 +15,9 @@ bazel_dep(name = "rules_cc", version = "0.2.17") # module_name = "coroutines", # path = "../co", # ) +git_override( + module_name = "coroutines", + commit = "88c4013c209bc0815cf7a8b20579b4f353c1b1be", + remote = "https://github.com/mikael-s-persson/co.git", +) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 574c750..6bba316 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1,5 +1,5 @@ { - "lockFileVersion": 24, + "lockFileVersion": 28, "registryFileHashes": { "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", @@ -14,22 +14,30 @@ "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", "https://bcr.bazel.build/modules/apple_support/1.22.1/MODULE.bazel": "90bd1a660590f3ceffbdf524e37483094b29352d85317060b2327fff8f3f4458", - "https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442", - "https://bcr.bazel.build/modules/apple_support/1.23.1/source.json": "d888b44312eb0ad2c21a91d026753f330caa48a25c9b2102fae75eb2b0dcfdd2", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", - "https://bcr.bazel.build/modules/bazel_features/1.30.0/source.json": "b07e17f067fe4f69f90b03b36ef1e08fe0d1f3cac254c1241a1818773e3423bc", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", @@ -43,12 +51,11 @@ "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", "https://bcr.bazel.build/modules/bazel_skylib/1.9.0/MODULE.bazel": "72997b29dfd95c3fa0d0c48322d05590418edef451f8db8db5509c57875fb4b7", "https://bcr.bazel.build/modules/bazel_skylib/1.9.0/source.json": "7ad77c1e8c1b84222d9b3f3cae016a76639435744c19330b0b37c0a3c9da7dc0", - "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", - "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", - "https://bcr.bazel.build/modules/coroutines/3.3.1/MODULE.bazel": "96746c200b0890b9a124713598fc0eb028cb7bf04a796e393573179ce5a4d34f", - "https://bcr.bazel.build/modules/coroutines/3.3.1/source.json": "c79ca39719820a3cef8fea46a5c204f0ca1ee725acd4f2799266441faf53484d", + "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", + "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", @@ -58,8 +65,11 @@ "https://bcr.bazel.build/modules/googletest/1.17.0.bcr.2/source.json": "3664514073a819992320ffbce5825e4238459df344d8b01748af2208f8d2e1eb", "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", - "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", @@ -74,12 +84,13 @@ "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", - "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", - "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", - "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", "https://bcr.bazel.build/modules/pybind11_bazel/2.13.6/MODULE.bazel": "2d746fda559464b253b2b2e6073cb51643a2ac79009ca02100ebbc44b4548656", @@ -91,10 +102,12 @@ "https://bcr.bazel.build/modules/re2/2025-08-12.bcr.1/source.json": "a8ae7c09533bf67f9f6e5122d884d5741600b09d78dca6fc0f2f8d2ee0c2d957", "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", - "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", @@ -103,38 +116,36 @@ "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", "https://bcr.bazel.build/modules/rules_cc/0.1.4/MODULE.bazel": "bb03a452a7527ac25a7518fb86a946ef63df860b9657d8323a0c50f8504fb0b9", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", - "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e", "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", - "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", - "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", - "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", - "https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615", - "https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc", "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", + "https://bcr.bazel.build/modules/rules_java/9.1.0/source.json": "da589573c1dee2c9ac4a568b301269a2e8191110ff0345c1a959fa7ea6c4dfd6", "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", - "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", - "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", - "https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/source.json": "5426f412d0a7fc6b611643376c7e4a82dec991491b9ce5cb1cfdd25fe2e92be4", "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", @@ -148,8 +159,8 @@ "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", - "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", - "https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", @@ -158,18 +169,29 @@ "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", "https://bcr.bazel.build/modules/rules_python/0.34.0/MODULE.bazel": "1d623d026e075b78c9fde483a889cda7996f5da4f36dffb24c246ab30f06513a", "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", - "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", "https://bcr.bazel.build/modules/rules_python/1.5.1/MODULE.bazel": "acfe65880942d44a69129d4c5c3122d57baaf3edf58ae5a6bd4edea114906bf5", - "https://bcr.bazel.build/modules/rules_python/1.5.1/source.json": "aa903e1bcbdfa1580f2b8e2d55100b7c18bc92d779ebb507fec896c75635f7bd", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", - "https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", - "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", - "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", @@ -181,11 +203,11 @@ "moduleExtensions": { "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { "general": { - "bzlTransitiveDigest": "rL/34P1aFDq2GqVC2zCFgQ8nTuOC6ziogocpvG50Qz8=", + "bzlTransitiveDigest": "+Kp6j204mBZ3mxlIDDR0gBoP45BZ4jYRhRAcB8sU0qc=", "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [ + "REPO_MAPPING:rules_kotlin+,bazel_tools bazel_tools" + ], "generatedRepoSpecs": { "com_github_jetbrains_kotlin_git": { "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", @@ -233,23 +255,185 @@ ] } } - }, - "recordedRepoMappingEntries": [ - [ - "rules_kotlin+", - "bazel_tools", - "bazel_tools" - ] - ] + } + } + }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "dzD8Q2YmrP3fz8saWLHPmlwPLO91ImtTmP/c9JKTStM=", + "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", + "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", + "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", + "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", + "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", + "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", + "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", + "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", + "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", + "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", + "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", + "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", + "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", + "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", + "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" + ], + "generatedRepoSpecs": { + "rules_python_internal": { + "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", + "attributes": { + "transition_setting_generators": {}, + "transition_settings": [] + } + }, + "pypi__build": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", + "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", + "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", + "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", + "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", + "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", + "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", + "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", + "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__wheel": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", + "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", + "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + } } }, "@@rules_python+//python/uv:uv.bzl%uv": { "general": { - "bzlTransitiveDigest": "8vT1ddXtljNxYD0tJkksqzeKE6xqx4Ix+tXthAppjTI=", - "usagesDigest": "WYhzIw9khRBy34H1GxV5+fI1yi07O90NmCXosPUdHWQ=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,platforms platforms" + ], "generatedRepoSpecs": { "uv": { "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", @@ -269,21 +453,10 @@ "toolchain_target_settings": {} } } - }, - "recordedRepoMappingEntries": [ - [ - "rules_python+", - "bazel_tools", - "bazel_tools" - ], - [ - "rules_python+", - "platforms", - "platforms" - ] - ] + } } } }, - "facts": {} + "facts": {}, + "factsVersions": {} } diff --git a/toolbelt/BUILD.bazel b/toolbelt/BUILD.bazel index 4fad7ab..df90bb4 100644 --- a/toolbelt/BUILD.bazel +++ b/toolbelt/BUILD.bazel @@ -11,6 +11,7 @@ cc_library( "logging.cc", "payload_buffer.cc", "pipe.cc", + "poller.cc", "sockets.cc", "table.cc", "triggerfd.cc", @@ -26,6 +27,7 @@ cc_library( "mutex.h", "payload_buffer.h", "pipe.h", + "poller.h", "sockets.h", "table.h", "triggerfd.h", @@ -37,7 +39,6 @@ cc_library( "@abseil-cpp//absl/strings", "@abseil-cpp//absl/strings:str_format", "@abseil-cpp//absl/types:span", - "@coroutines//:co", ], ) @@ -91,6 +92,7 @@ cc_test( "@abseil-cpp//absl/status:status_matchers", "@abseil-cpp//absl/status:statusor", "@googletest//:gtest_main", + "@coroutines//:co", ], ) @@ -105,6 +107,7 @@ cc_test( "@abseil-cpp//absl/status:status_matchers", "@abseil-cpp//absl/status:statusor", "@googletest//:gtest_main", + "@coroutines//:co", ], ) diff --git a/toolbelt/fd.cc b/toolbelt/fd.cc index a160646..74c4097 100644 --- a/toolbelt/fd.cc +++ b/toolbelt/fd.cc @@ -16,7 +16,7 @@ void CloseAllFds(std::function predicate) { } absl::StatusOr FileDescriptor::Read(void *buffer, size_t length, - const co::Coroutine *c) { + const Poller *c) { char *buf = reinterpret_cast(buffer); size_t total = 0; while (total < length) { @@ -58,7 +58,7 @@ absl::StatusOr FileDescriptor::Read(void *buffer, size_t length, } absl::StatusOr FileDescriptor::Write(const void *buffer, size_t length, - const co::Coroutine *c) { + const Poller *c) { const char *buf = reinterpret_cast(buffer); size_t total = 0; diff --git a/toolbelt/fd.h b/toolbelt/fd.h index 5760b56..a3e66f0 100644 --- a/toolbelt/fd.h +++ b/toolbelt/fd.h @@ -18,7 +18,7 @@ #include #include #include -#include "co/coroutine.h" +#include "toolbelt/poller.h" namespace toolbelt { @@ -188,9 +188,9 @@ class FileDescriptor { return absl::OkStatus(); } - absl::StatusOr Read(void* buffer, size_t length, const co::Coroutine* c = nullptr); + absl::StatusOr Read(void* buffer, size_t length, const Poller* c = nullptr); absl::StatusOr Write(const void* buffer, size_t length, - const co::Coroutine* c = nullptr); + const Poller* c = nullptr); private: // Reference counted OS fd, shared among all FileDescriptors with the // same OS fd, provided you don't create two FileDescriptors with the diff --git a/toolbelt/pipe.cc b/toolbelt/pipe.cc index 0cb8312..a4b1c3d 100644 --- a/toolbelt/pipe.cc +++ b/toolbelt/pipe.cc @@ -83,7 +83,7 @@ absl::Status Pipe::SetPipeSize(size_t size) { } absl::StatusOr Pipe::Read(char *buffer, size_t length, - const co::Coroutine *c) { + const Poller *c) { size_t total = 0; ScopedRead sc(*this, c); @@ -123,7 +123,7 @@ absl::StatusOr Pipe::Read(char *buffer, size_t length, } absl::StatusOr Pipe::Write(const char *buffer, size_t length, - const co::Coroutine *c) { + const Poller *c) { size_t total = 0; ScopedWrite sc(*this, c); diff --git a/toolbelt/pipe.h b/toolbelt/pipe.h index cfe4749..addabfe 100644 --- a/toolbelt/pipe.h +++ b/toolbelt/pipe.h @@ -3,7 +3,7 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_format.h" -#include "co/coroutine.h" +#include "toolbelt/poller.h" #include "toolbelt/fd.h" #include @@ -66,9 +66,9 @@ class Pipe { absl::Status SetPipeSize(size_t size); virtual absl::StatusOr Read(char *buffer, size_t length, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); virtual absl::StatusOr Write(const char *buffer, size_t length, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); protected: // RAII classes for keeping coroutines from interleaving reads or writes on a @@ -78,15 +78,12 @@ class Pipe { // // Same applies to non-coroutine use except we block with a sleep. struct ScopedRead { - ScopedRead(Pipe &p, const co::Coroutine *c) : pipe(p) { + ScopedRead(Pipe &p, const Poller *c) : pipe(p) { while (pipe.read_in_progress_) { if (c) { c->Yield(); } else { - if (!pipe.read_.IsNonBlocking()) { - break; - } - std::this_thread::sleep_for(std::chrono::microseconds(10)); + PosixPoller{/*yield_sleep_ns=*/10000ULL}.Yield(); } } pipe.read_in_progress_ = true; @@ -97,15 +94,12 @@ class Pipe { }; struct ScopedWrite { - ScopedWrite(Pipe &p, const co::Coroutine *c) : pipe(p) { + ScopedWrite(Pipe &p, const Poller *c) : pipe(p) { while (pipe.write_in_progress_) { if (c) { c->Yield(); } else { - if (!pipe.write_.IsNonBlocking()) { - break; - } - std::this_thread::sleep_for(std::chrono::microseconds(10)); + PosixPoller{/*yield_sleep_ns=*/10000ULL}.Yield(); } } pipe.write_in_progress_ = true; @@ -151,15 +145,15 @@ template class SharedPtrPipe : public Pipe { // You can't use raw buffers with shared ptr pipes. absl::StatusOr Read(char *, size_t , - const co::Coroutine * = nullptr) override { + const Poller * = nullptr) override { return absl::InternalError("Not supported on SharedPtrPipe"); } absl::StatusOr Write(const char *, size_t , - const co::Coroutine *c = nullptr) override { + const Poller *c = nullptr) override { return absl::InternalError("Not supported on SharedPtrPipe"); } - absl::StatusOr> Read(const co::Coroutine *c = nullptr) { + absl::StatusOr> Read(const Poller *c = nullptr) { char buffer[sizeof(std::shared_ptr)]; size_t length = sizeof(buffer); size_t total = 0; @@ -205,7 +199,7 @@ template class SharedPtrPipe : public Pipe { } // This makes the pipe an owner of the pointer. - absl::Status Write(std::shared_ptr p, const co::Coroutine *c = nullptr) { + absl::Status Write(std::shared_ptr p, const Poller *c = nullptr) { // On entry, ref count for p = N char buffer[sizeof(std::shared_ptr)]; diff --git a/toolbelt/pipe_test.cc b/toolbelt/pipe_test.cc index 30be8a5..62b43ff 100644 --- a/toolbelt/pipe_test.cc +++ b/toolbelt/pipe_test.cc @@ -4,6 +4,7 @@ #include "absl/status/status_matchers.h" #include "co/coroutine.h" +#include "co/coroutine_scheduler.h" #include "pipe.h" #include #include @@ -65,14 +66,14 @@ TEST(PipeTest, CoroutinePipeReadAndWrite) { ASSERT_OK(p); auto pipe = std::move(*p); - co::Coroutine reader(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe](co::Coroutine *c) { char buffer[20]; auto r = pipe.Read(buffer, 5, c); ASSERT_OK(r); ASSERT_EQ(*r, 5); ASSERT_EQ(std::string_view(buffer, *r), "Hello"); }); - co::Coroutine writer(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine writer(scheduler, [&pipe](co::Coroutine *c) { const char *msg = "Hello"; auto s = pipe.Write(msg, 5, c); ASSERT_OK(s); @@ -88,14 +89,14 @@ TEST(PipeTest, CoroutinePipeReadAndWriteNonblocking) { auto pipe = std::move(*p); ASSERT_OK(pipe.SetNonBlocking(true, true)); - co::Coroutine reader(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe](co::Coroutine *c) { char buffer[20]; auto r = pipe.Read(buffer, 5, c); ASSERT_OK(r); ASSERT_EQ(*r, 5); ASSERT_EQ(std::string_view(buffer, *r), "Hello"); }); - co::Coroutine writer(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine writer(scheduler, [&pipe](co::Coroutine *c) { const char *msg = "Hello"; auto s = pipe.Write(msg, 5, c); ASSERT_OK(s); @@ -110,13 +111,13 @@ TEST(PipeTest, CoroutinePtrPipeReadAndWrite) { ASSERT_OK(p); auto pipe = std::move(*p); - co::Coroutine reader(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe](co::Coroutine *c) { auto t = pipe.Read(c); ASSERT_OK(t); ASSERT_EQ(1, (*t)->a); ASSERT_EQ(2, (*t)->b); }); - co::Coroutine writer(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine writer(scheduler, [&pipe](co::Coroutine *c) { auto t = std::make_shared(1, 2); ASSERT_OK(pipe.Write(t, c)); }); @@ -130,13 +131,13 @@ TEST(PipeTest, CoroutinePtrPipeReadAndWriteNonblocking) { auto pipe = std::move(*p); ASSERT_OK(pipe.SetNonBlocking(true, true)); - co::Coroutine reader(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe](co::Coroutine *c) { auto t = pipe.Read(c); ASSERT_OK(t); ASSERT_EQ(1, (*t)->a); ASSERT_EQ(2, (*t)->b); }); - co::Coroutine writer(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine writer(scheduler, [&pipe](co::Coroutine *c) { auto t = std::make_shared(1, 2); ASSERT_OK(pipe.Write(t, c)); }); @@ -153,7 +154,7 @@ TEST(PipeTest, CoroutineFullPipeReadAndWrite) { constexpr int kMessageSize = 4; constexpr int kNumMessages = kPipeSize / kMessageSize; - co::Coroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { char buffer[20]; auto r = pipe.Read(buffer, kMessageSize, c); @@ -162,7 +163,7 @@ TEST(PipeTest, CoroutineFullPipeReadAndWrite) { ASSERT_EQ(std::string_view(buffer, *r), "1234"); } }); - co::Coroutine writer(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine writer(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { const char *msg = "1234"; auto s = pipe.Write(msg, kMessageSize, c); @@ -188,7 +189,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWrite) { constexpr int kMessageSize = 4; constexpr int kNumMessages = 10 * kPipeSize / kMessageSize; - co::Coroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { char buffer[20]; auto r = pipe.Read(buffer, kMessageSize, c); @@ -197,7 +198,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWrite) { ASSERT_EQ(std::string_view(buffer, *r), "1234"); } }); - co::Coroutine writer(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine writer(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { const char *msg = "1234"; auto s = pipe.Write(msg, kMessageSize, c); @@ -220,7 +221,7 @@ TEST(PipeTest, CoroutineFullPipeReadAndWriteNonblocking) { constexpr int kNumMessages = kPipeSize / kMessageSize; ASSERT_OK(pipe.SetNonBlocking(true, true)); - co::Coroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { char buffer[20]; auto r = pipe.Read(buffer, kMessageSize, c); @@ -229,7 +230,7 @@ TEST(PipeTest, CoroutineFullPipeReadAndWriteNonblocking) { ASSERT_EQ(std::string_view(buffer, *r), "1234"); } }); - co::Coroutine writer(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine writer(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { const char *msg = "1234"; auto s = pipe.Write(msg, kMessageSize, c); @@ -256,7 +257,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWriteNonblocking) { constexpr int kNumMessages = 10 * kPipeSize / kMessageSize; ASSERT_OK(pipe.SetNonBlocking(true, true)); - co::Coroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { char buffer[20]; auto r = pipe.Read(buffer, kMessageSize, c); @@ -265,7 +266,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWriteNonblocking) { ASSERT_EQ(std::string_view(buffer, *r), "1234"); } }); - co::Coroutine writer(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine writer(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { const char *msg = "1234"; auto s = pipe.Write(msg, kMessageSize, c); @@ -283,7 +284,7 @@ TEST(PipeTest, CoroutinePipeReadAndMultiWrite) { ASSERT_OK(p); auto pipe = std::move(*p); - co::Coroutine reader(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe](co::Coroutine *c) { char buffer[20]; auto r = pipe.Read(buffer, 5, c); ASSERT_OK(r); @@ -296,14 +297,14 @@ TEST(PipeTest, CoroutinePipeReadAndMultiWrite) { ASSERT_EQ(std::string_view(buffer, *r), "54321"); }); - co::Coroutine writer1(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine writer1(scheduler, [&pipe](co::Coroutine *c) { const char *msg = "12345"; auto s = pipe.Write(msg, 5, c); ASSERT_OK(s); ASSERT_EQ(*s, 5); }); - co::Coroutine writer2(scheduler, [&pipe](co::Coroutine *c) { + co::ScheduledCoroutine writer2(scheduler, [&pipe](co::Coroutine *c) { const char *msg = "54321"; auto s = pipe.Write(msg, 5, c); ASSERT_OK(s); @@ -326,7 +327,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWriteMultiwriter) { constexpr int kMessageSize = 4; constexpr int kNumMessages = 10 * kPipeSize / kMessageSize; - co::Coroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages * 2; i++) { char buffer[20]; auto r = pipe.Read(buffer, kMessageSize, c); @@ -339,7 +340,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWriteMultiwriter) { } }); - co::Coroutine writer1(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine writer1(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { const char *msg = "1234"; auto s = pipe.Write(msg, kMessageSize, c); @@ -348,7 +349,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWriteMultiwriter) { } }); - co::Coroutine writer2(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine writer2(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { const char *msg = "4321"; auto s = pipe.Write(msg, kMessageSize, c); @@ -375,7 +376,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWriteMultiwriterNonblocking) { constexpr int kNumMessages = 10 * kPipeSize / kMessageSize; ASSERT_OK(pipe.SetNonBlocking(true, true)); - co::Coroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine reader(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages * 2; i++) { char buffer[20]; auto r = pipe.Read(buffer, kMessageSize, c); @@ -388,7 +389,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWriteMultiwriterNonblocking) { } }); - co::Coroutine writer1(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine writer1(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { const char *msg = "1234"; auto s = pipe.Write(msg, kMessageSize, c); @@ -397,7 +398,7 @@ TEST(PipeTest, CoroutineOverFullPipeReadAndWriteMultiwriterNonblocking) { } }); - co::Coroutine writer2(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { + co::ScheduledCoroutine writer2(scheduler, [&pipe, kMessageSize](co::Coroutine *c) { for (int i = 0; i < kNumMessages; i++) { const char *msg = "4321"; auto s = pipe.Write(msg, kMessageSize, c); diff --git a/toolbelt/poller.cc b/toolbelt/poller.cc new file mode 100644 index 0000000..e9dfc90 --- /dev/null +++ b/toolbelt/poller.cc @@ -0,0 +1,60 @@ +// Copyright 2026 Mikael Persson +// All Rights Reserved +// See LICENSE file for licensing information. +#include "toolbelt/poller.h" + +#include +#include +#include + +namespace toolbelt { + +PosixPoller::PosixPoller(uint64_t yield_sleep_ns) : Poller(), yield_sleep_ns_(yield_sleep_ns) {} + +void PosixPoller::Yield() const { + if (yield_sleep_ns_ == 0) { + std::this_thread::yield(); + } else { + std::this_thread::sleep_for(std::chrono::nanoseconds(yield_sleep_ns_)); + } +} + +void PosixPoller::Nanosleep(uint64_t ns) const { + std::this_thread::sleep_for(std::chrono::nanoseconds(ns)); +} + +void PosixPoller::AddToUserWaitFds(int fd, uint32_t event_mask) const { + user_fds_.push_back({.fd = fd, .events = short(event_mask)}); +} + +int PosixPoller::PollImpl(std::vector &fds, int timeout_ms) const { + int ret = ::poll(user_fds_.data(), user_fds_.size(), timeout_ms); + if (ret < 0) { + return -2; + } + if (ret == 0) { + return -1; + } + for (auto &pfd : fds) { + if (pfd.revents & (pfd.events | POLLOUT)) { + return pfd.fd; + } + } + return -1; +} + +int PosixPoller::WaitOnUserWaitFds(uint64_t timeout_ns) const { + int timeout_ms = -1; + if (timeout_ns != 0) { + timeout_ms = std::max(1, static_cast(timeout_ns / 1000000ULL)); + } + int result = PollImpl(user_fds_, timeout_ms); + user_fds_.clear(); + return result; +} + +int PosixPoller::PollWithMutableFds(std::vector &fds) const { + return PollImpl(fds, 0); +} + +} // namespace toolbelt diff --git a/toolbelt/poller.h b/toolbelt/poller.h new file mode 100644 index 0000000..7363039 --- /dev/null +++ b/toolbelt/poller.h @@ -0,0 +1,278 @@ +// Copyright 2026 Mikael Persson +// All Rights Reserved +// See LICENSE file for licensing information. + +#pragma once + +#include + +#include +#include +#include + +namespace toolbelt { + +namespace toolbelt_details { + +template +inline uint64_t ChronoToNanoseconds(std::chrono::duration duration) { + using FloatingNanoseconds = std::chrono::duration; + const long double count = FloatingNanoseconds(duration).count(); + if (!(count > 0)) { + return 0; + } + const long double maximum = + static_cast(std::numeric_limits::max()); + if (count >= maximum) { + return std::numeric_limits::max(); + } + return static_cast(count); +} + +} // namespace toolbelt_details + +// This is to provide the epoll equivalent of waiting for a set +// of pollfds +struct WaitFd { + WaitFd(int f, uint32_t e) : fd(f), events(e) {} + int fd; + uint32_t events; +}; + +// This is a Poller. It's an abstract interface to a poll/wait/yield +// mechanism, such as a vanilla POSIX implementation or coroutines. +class Poller { +public: + Poller() = default; + Poller(const Poller&) = delete; + Poller(Poller&&) = delete; + Poller& operator=(const Poller&) = delete; + Poller& operator=(Poller&&) = delete; + virtual ~Poller() = default; + + // Yield cpu time (to another thread, process, coroutine, etc.). + virtual void Yield() const = 0; + + // For all Poll functions, there is no timeout because those are immediate + // polls that just check current readiness status without blocking. + // Returns -1 for no fd ready, fd if one is ready. + // Returns -2 for an error during poll. + + // Poll a set of file descriptors with a single common event mask. + int Poll(const std::vector &fds, short event_mask = POLLIN) const { + std::vector pfds; + pfds.reserve(fds.size() + 1); + for (auto &fd : fds) { + pfds.push_back({.fd = fd, .events = short(event_mask), .revents = 0}); + } + return PollWithMutableFds(pfds); + } + + // Poll a set of file descriptors with their own event masks. + // Note that the pollfd's are immutable, therefore, this function may copy + // the vector for a typical POSIX poll call that fills in `revents`, and + // upon return, the `revents` are not set. Use the mutable version below. + int Poll(const std::vector &fds) const { + std::vector pfds = fds; + return PollWithMutableFds(pfds); + } + + // Poll a set of file descriptors with their own event masks. + // Upon return, the `revents` of the ready FDs will be set. + // Note that additional FDs might be appended to this set of pollfds for + // internal purposes. + int Poll(std::vector &fds) const { + return PollWithMutableFds(fds); + } + + // For all Wait functions, the timeout is optional and if greater than zero + // specifies a nanosecond timeout. If the timeout occurs before the fd (or + // one of the fds) becomes ready, Wait will return -1. If an fd is ready, Wait + // will return the fd that terminated the wait. + // If poll returned an error, Wait will return -2. + + // Wait for a file descriptor to become ready. Returns the fd if it + // was triggered or -1 for timeout. + int Wait(int fd, uint32_t event_mask = POLLIN, uint64_t timeout_ns = 0) const { + AddToUserWaitFds(fd, event_mask); + return WaitOnUserWaitFds(timeout_ns); + } + + // Wait for a set of fds, all with the same event mask. + int Wait(const std::vector &fds, uint32_t event_mask = POLLIN, + uint64_t timeout_ns = 0) const { + for (auto &fd : fds) { + AddToUserWaitFds(fd, event_mask); + } + return WaitOnUserWaitFds(timeout_ns); + } + + // Wait for a WaitFd. Returns the fd if it was triggered or -1 for timeout. + int Wait(WaitFd fd, uint64_t timeout_ns = 0) const { + AddToUserWaitFds(fd.fd, fd.events); + return WaitOnUserWaitFds(timeout_ns); + } + + // Wait for a set of WaitFds. Each needs to specify an fd and an event. + // Returns the fd that was triggered, or -1 for a timeout. + int Wait(const std::vector &fds, uint64_t timeout_ns = 0) const { + for (auto &fd : fds) { + AddToUserWaitFds(fd.fd, fd.events); + } + return WaitOnUserWaitFds(timeout_ns); + } + + // Wait for a pollfd. Returns the fd if it was triggered or -1 for timeout. + int Wait(struct pollfd fd, uint64_t timeout_ns = 0) const { + AddToUserWaitFds(fd.fd, fd.events); + return WaitOnUserWaitFds(timeout_ns); + } + + // Wait for a set of pollfds. Each needs to specify an fd and an event. + // Returns the fd that was triggered, or -1 for a timeout. + int Wait(const std::vector &fds, + uint64_t timeout_ns = 0) const { + for (auto &fd : fds) { + AddToUserWaitFds(fd.fd, fd.events); + } + return WaitOnUserWaitFds(timeout_ns); + } + + // For all PollAndWait functions, they combine an immediate poll to check for + // readiness and if not, enter a wait (timed-out poll). This can be more efficient + // in some implementation. If the timeout occurs before the fd (or + // one of the fds) becomes ready, Wait will return -1. If an fd is ready, Wait + // will return the fd that terminated the wait. + // If poll returned an error, Wait will return -2. + + // Poll first and if the fd is not ready, wait for it. + int PollAndWait(int fd, uint32_t event_mask = POLLIN, + uint64_t timeout_ns = 0) const { + int n = Poll({fd}, event_mask); + if (n != -1) { + return n; + } + return Wait(fd, event_mask, timeout_ns); + } + + // Wait for a set of fds, all with the same event mask. + int PollAndWait(const std::vector &fds, uint32_t event_mask = POLLIN, + uint64_t timeout_ns = 0) const { + int n = Poll(fds, event_mask); + if (n != -1) { + return n; + } + return Wait(fds, event_mask, timeout_ns); + } + + int PollAndWait(WaitFd fd, uint64_t timeout_ns = 0) const { + int n = Poll({(struct pollfd){.fd = fd.fd, .events = short(fd.events)}}); + if (n != -1) { + return fd.fd; + } + return Wait(fd, timeout_ns); + } + + int PollAndWait(const std::vector &fds, + uint64_t timeout_ns = 0) const { + std::vector pfds; + pfds.reserve(fds.size()); + for (auto &fd : fds) { + pfds.push_back({.fd = fd.fd, .events = short(fd.events), .revents = 0}); + } + int n = Poll(pfds); + if (n != -1) { + return n; + } + for (auto &fd : fds) { + AddToUserWaitFds(fd.fd, fd.events); + } + return WaitOnUserWaitFds(timeout_ns); + } + + // Wait for a pollfd. Returns the fd if it was triggered or -1 for timeout. + int PollAndWait(struct pollfd fd, uint64_t timeout_ns = 0) const { + int n = Poll({fd}); + if (n != -1) { + return fd.fd; + } + return Wait(fd, timeout_ns); + } + + // Wait for a set of pollfds. Each needs to specify an fd and an event. + // Returns the fd that was triggered, or -1 for a timeout. + int PollAndWait(const std::vector &fds, + uint64_t timeout_ns = 0) const { + int n = Poll(fds); + if (n != -1) { + return n; + } + return Wait(fds, timeout_ns); + } + + // Templated waits with chrono timeouts. + template + int Wait(const T &fd, uint32_t events, + std::chrono::duration duration) const { + return Wait( + fd, events, toolbelt_details::ChronoToNanoseconds(duration)); + } + + template + int Wait(const T &fd, std::chrono::duration duration) const { + return Wait( + fd, POLLIN, toolbelt_details::ChronoToNanoseconds(duration)); + } + + template + int PollAndWait(const T &fd, uint32_t events, + std::chrono::duration duration) const { + return PollAndWait( + fd, events, toolbelt_details::ChronoToNanoseconds(duration)); + } + + template + int PollAndWait(const T &fd, + std::chrono::duration duration) const { + return PollAndWait( + fd, POLLIN, toolbelt_details::ChronoToNanoseconds(duration)); + } + + // Sleeping functions. + virtual void Nanosleep(uint64_t ns) const = 0; + void Millisleep(time_t msecs) const { + Nanosleep(static_cast(msecs) * 1000000LL); + } + void Sleep(time_t secs) const { + Nanosleep(static_cast(secs) * 1000000000LL); + } + + template + void Sleep(std::chrono::duration duration) const { + Nanosleep(toolbelt_details::ChronoToNanoseconds(duration)); + } + +protected: + virtual void AddToUserWaitFds(int fd, uint32_t event_mask) const = 0; + virtual int WaitOnUserWaitFds(uint64_t timeout_ns) const = 0; + virtual int PollWithMutableFds(std::vector &fds) const = 0; +}; + +class PosixPoller : public Poller { +public: + explicit PosixPoller(uint64_t yield_sleep_ns = 0); + + void Yield() const override; + void Nanosleep(uint64_t ns) const override; +protected: + void AddToUserWaitFds(int fd, uint32_t event_mask) const override; + int WaitOnUserWaitFds(uint64_t timeout_ns) const override; + int PollWithMutableFds(std::vector &fds) const override; +private: + uint64_t yield_sleep_ns_ = 0; + mutable std::vector user_fds_; + + int PollImpl(std::vector &fds, int timeout_ms) const; +}; + +} // namespace toolbelt diff --git a/toolbelt/sockets.cc b/toolbelt/sockets.cc index 965a0af..d93bb49 100644 --- a/toolbelt/sockets.cc +++ b/toolbelt/sockets.cc @@ -2,7 +2,7 @@ // All Rights Reserved // See LICENSE file for licensing information. -#include "sockets.h" +#include "toolbelt/sockets.h" #include #include @@ -20,7 +20,7 @@ #include #include "absl/strings/str_format.h" -#include "hexdump.h" +#include "toolbelt/poller.h" namespace toolbelt { @@ -157,7 +157,7 @@ std::string VirtualAddress::ToString() const { return absl::StrFormat("%d:%d", addr_.svm_cid, addr_.svm_port); } -static ssize_t ReceiveFully(const co::Coroutine *c, int fd, size_t length, +static ssize_t ReceiveFully(const Poller *c, int fd, size_t length, char *buffer, size_t buflen) { int offset = 0; size_t remaining = length; @@ -193,7 +193,7 @@ static ssize_t ReceiveFully(const co::Coroutine *c, int fd, size_t length, return length; } -static ssize_t SendFully(const co::Coroutine *c, int fd, const char *buffer, +static ssize_t SendFully(const Poller *c, int fd, const char *buffer, size_t length, bool blocking) { size_t remaining = length; size_t offset = 0; @@ -242,7 +242,7 @@ static ssize_t SendFully(const co::Coroutine *c, int fd, const char *buffer, } absl::StatusOr Socket::Receive(char *buffer, size_t buflen, - const co::Coroutine *c) { + const Poller *c) { if (!Connected()) { return absl::InternalError("Socket is not connected"); } @@ -256,7 +256,7 @@ absl::StatusOr Socket::Receive(char *buffer, size_t buflen, } absl::StatusOr Socket::Send(const char *buffer, size_t length, - const co::Coroutine *c) { + const Poller *c) { if (!Connected()) { return absl::InternalError("Socket is not connected"); } @@ -270,7 +270,7 @@ absl::StatusOr Socket::Send(const char *buffer, size_t length, } absl::StatusOr Socket::ReceiveMessage(char *buffer, size_t buflen, - const co::Coroutine *c) { + const Poller *c) { if (!Connected()) { return absl::InternalError("Socket is not connected"); } @@ -303,7 +303,7 @@ absl::StatusOr Socket::ReceiveMessage(char *buffer, size_t buflen, } absl::StatusOr> -Socket::ReceiveVariableLengthMessage(const co::Coroutine *c) { +Socket::ReceiveVariableLengthMessage(const Poller *c) { if (!Connected()) { return absl::InternalError("Socket is not connected"); } @@ -338,7 +338,7 @@ Socket::ReceiveVariableLengthMessage(const co::Coroutine *c) { } absl::StatusOr Socket::SendMessage(char *buffer, size_t length, - const co::Coroutine *c) { + const Poller *c) { if (!Connected()) { return absl::InternalError("Socket is not connected"); } @@ -406,7 +406,7 @@ absl::Status UnixSocket::Bind(const std::string &pathname, bool listen) { return absl::OkStatus(); } -absl::StatusOr UnixSocket::Accept(const co::Coroutine *c) const { +absl::StatusOr UnixSocket::Accept(const Poller *c) const { if (!fd_.Valid()) { return absl::InternalError("UnixSocket is not valid"); } @@ -457,7 +457,7 @@ absl::Status UnixSocket::Connect(const std::string &pathname) { } absl::Status UnixSocket::SendFds(const std::vector &fds, - const co::Coroutine *c) { + const Poller *c) { if (!Connected()) { return absl::InternalError("Socket is not connected"); } @@ -522,7 +522,7 @@ absl::Status UnixSocket::SendFds(const std::vector &fds, } absl::Status UnixSocket::ReceiveFds(std::vector &fds, - const co::Coroutine *c) { + const Poller *c) { if (!Connected()) { return absl::InternalError("Socket is not connected"); } @@ -734,7 +734,7 @@ absl::Status TCPSocket::Bind(const InetAddress &addr, bool listen) { return absl::OkStatus(); } -absl::StatusOr TCPSocket::Accept(const co::Coroutine *c) const { +absl::StatusOr TCPSocket::Accept(const Poller *c) const { if (!fd_.Valid()) { return absl::InternalError("Socket is not valid"); } @@ -883,7 +883,7 @@ absl::Status UDPSocket::SetMulticastLoop() { } absl::Status UDPSocket::SendTo(const InetAddress &addr, const void *buffer, - size_t length, const co::Coroutine *c) { + size_t length, const Poller *c) { if (c != nullptr) { int fd = c->Wait(fd_.Fd(), POLLOUT); if (fd != fd_.Fd()) { @@ -902,7 +902,7 @@ absl::Status UDPSocket::SendTo(const InetAddress &addr, const void *buffer, } absl::StatusOr UDPSocket::Receive(void *buffer, size_t buflen, - const co::Coroutine *c) { + const Poller *c) { if (c != nullptr) { int fd = c->Wait(fd_.Fd(), POLLIN); if (fd != fd_.Fd()) { @@ -918,7 +918,7 @@ absl::StatusOr UDPSocket::Receive(void *buffer, size_t buflen, } absl::StatusOr UDPSocket::ReceiveFrom(InetAddress &sender, void *buffer, size_t buflen, - const co::Coroutine *c) { + const Poller *c) { if (c != nullptr) { int fd = c->Wait(fd_.Fd(), POLLIN); if (fd != fd_.Fd()) { @@ -978,7 +978,7 @@ absl::Status VirtualStreamSocket::Bind(const VirtualAddress &addr, } absl::StatusOr -VirtualStreamSocket::Accept(const co::Coroutine *c) const { +VirtualStreamSocket::Accept(const Poller *c) const { if (!fd_.Valid()) { return absl::InternalError("Socket is not valid"); } diff --git a/toolbelt/sockets.h b/toolbelt/sockets.h index a159894..ca4da83 100644 --- a/toolbelt/sockets.h +++ b/toolbelt/sockets.h @@ -6,8 +6,8 @@ #define __TOOLBELT_SOCKETS_H #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "co/coroutine.h" -#include "fd.h" +#include "toolbelt/poller.h" +#include "toolbelt/fd.h" #include #include #include @@ -354,17 +354,17 @@ class Socket { // Send and receive raw buffers. absl::StatusOr Receive(char *buffer, size_t buflen, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); absl::StatusOr Send(const char *buffer, size_t length, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); // Send and receive length-delimited message. The length is a 4-byte // network byte order (big endian) int as the first 4 bytes and // contains the length of the message. absl::StatusOr ReceiveMessage(char *buffer, size_t buflen, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); absl::StatusOr> - ReceiveVariableLengthMessage(const co::Coroutine *c = nullptr); + ReceiveVariableLengthMessage(const Poller *c = nullptr); // For SendMessage, the buffer pointer must be 4 bytes beyond // the actual buffer start, which must be length+4 bytes @@ -372,7 +372,7 @@ class Socket { // at buffer-4. This is to allow us to do a single send // to the socket rather than splitting it into 2. absl::StatusOr SendMessage(char *buffer, size_t length, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); absl::Status SetNonBlocking() { if (absl::Status s = fd_.SetNonBlocking(); !s.ok()) { @@ -405,12 +405,12 @@ class UnixSocket : public Socket { absl::Status Bind(const std::string &pathname, bool listen); absl::Status Connect(const std::string &pathname); - absl::StatusOr Accept(const co::Coroutine *c = nullptr) const; + absl::StatusOr Accept(const Poller *c = nullptr) const; absl::Status SendFds(const std::vector &fds, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); absl::Status ReceiveFds(std::vector &fds, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); std::string BoundAddress() const { return bound_address_; } absl::StatusOr GetPeerName() const; @@ -455,12 +455,12 @@ class UDPSocket : public NetworkSocket { // NOTE: Read and Write may or may not work on UDP sockets. Use SendTo and // Receive for datagrams. absl::Status SendTo(const InetAddress &addr, const void *buffer, - size_t length, const co::Coroutine *c = nullptr); + size_t length, const Poller *c = nullptr); absl::StatusOr Receive(void *buffer, size_t buflen, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); absl::StatusOr ReceiveFrom(InetAddress &sender, void *buffer, size_t buflen, - const co::Coroutine *c = nullptr); + const Poller *c = nullptr); absl::Status SetBroadcast(); absl::Status SetMulticastLoop(); }; @@ -474,7 +474,7 @@ class TCPSocket : public NetworkSocket { absl::Status Bind(const InetAddress &addr, bool listen); - absl::StatusOr Accept(const co::Coroutine *c = nullptr) const; + absl::StatusOr Accept(const Poller *c = nullptr) const; absl::StatusOr LocalAddress(int port) const; @@ -491,7 +491,7 @@ class VirtualStreamSocket : public Socket { absl::Status Bind(const VirtualAddress &addr, bool listen); - absl::StatusOr Accept(const co::Coroutine *c = nullptr) const; + absl::StatusOr Accept(const Poller *c = nullptr) const; absl::StatusOr LocalAddress(uint32_t port) const; const VirtualAddress &BoundAddress() const { return bound_address_; } @@ -552,7 +552,7 @@ class StreamSocket { return absl::Status(absl::StatusCode::kInternal, "Invalid socket address"); } - absl::StatusOr Accept(const co::Coroutine *c = nullptr) const { + absl::StatusOr Accept(const Poller *c = nullptr) const { return std::visit( EyeOfNewt{ [&](const TCPSocket &s) mutable -> absl::StatusOr { @@ -618,7 +618,7 @@ class StreamSocket { // Send and receive raw buffers. absl::StatusOr Receive(char *buffer, size_t buflen, - const co::Coroutine *c = nullptr) { + const Poller *c = nullptr) { return std::visit( EyeOfNewt{[&](TCPSocket &s) { return s.Receive(buffer, buflen, c); }, [&](VirtualStreamSocket &s) { @@ -629,7 +629,7 @@ class StreamSocket { } absl::StatusOr Send(const char *buffer, size_t length, - const co::Coroutine *c = nullptr) { + const Poller *c = nullptr) { return std::visit( EyeOfNewt{ [&](TCPSocket &s) { return s.Send(buffer, length, c); }, @@ -642,7 +642,7 @@ class StreamSocket { // network byte order (big endian) int as the first 4 bytes and // contains the length of the message. absl::StatusOr ReceiveMessage(char *buffer, size_t buflen, - const co::Coroutine *c = nullptr) { + const Poller *c = nullptr) { return std::visit( EyeOfNewt{ [&](TCPSocket &s) { return s.ReceiveMessage(buffer, buflen, c); }, @@ -654,7 +654,7 @@ class StreamSocket { } absl::StatusOr> - ReceiveVariableLengthMessage(const co::Coroutine *c = nullptr) { + ReceiveVariableLengthMessage(const Poller *c = nullptr) { return std::visit( EyeOfNewt{ [&](TCPSocket &s) { return s.ReceiveVariableLengthMessage(c); }, @@ -671,7 +671,7 @@ class StreamSocket { // at buffer-4. This is to allow us to do a single send // to the socket rather than splitting it into 2. absl::StatusOr SendMessage(char *buffer, size_t length, - const co::Coroutine *c = nullptr) { + const Poller *c = nullptr) { return std::visit( EyeOfNewt{ [&](TCPSocket &s) { return s.SendMessage(buffer, length, c); }, diff --git a/toolbelt/sockets_test.cc b/toolbelt/sockets_test.cc index f766c8c..4cffd28 100644 --- a/toolbelt/sockets_test.cc +++ b/toolbelt/sockets_test.cc @@ -7,6 +7,8 @@ #include #include "absl/status/status_matchers.h" #include "toolbelt/hexdump.h" +#include "co/coroutine.h" +#include "co/coroutine_scheduler.h" #define VAR(a) a##__COUNTER__ #define EVAL_AND_ASSERT_OK(expr) EVAL_AND_ASSERT_OK2(VAR(r_), expr) @@ -93,7 +95,7 @@ TEST(SocketsTest, UnixSocket) { std::cerr << status << std::endl; ASSERT_TRUE(status.ok()); - co::Coroutine incoming(scheduler, [&listener](co::Coroutine* c) { + co::ScheduledCoroutine incoming(scheduler, [&listener](co::Coroutine* c) { absl::StatusOr s = listener.Accept(c); ASSERT_TRUE(s.ok()); auto socket = s.value(); @@ -109,10 +111,10 @@ TEST(SocketsTest, UnixSocket) { absl::Status s2 = socket.ReceiveFds(fds, c); ASSERT_TRUE(s2.ok()); - ASSERT_EQ(3, fds.size()); + ASSERT_EQ(std::size_t{3}, fds.size()); }); - co::Coroutine outgoing(scheduler, [&socket_name](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(scheduler, [&socket_name](co::Coroutine* c) { toolbelt::UnixSocket socket; absl::Status s = socket.Connect(socket_name); ASSERT_TRUE(s.ok()); @@ -151,7 +153,7 @@ TEST(SocketsTest, UnixSocketZeroFds) { absl::Status status = listener.Bind(socket_name, true); ASSERT_TRUE(status.ok()); - co::Coroutine incoming(scheduler, [&listener](co::Coroutine* c) { + co::ScheduledCoroutine incoming(scheduler, [&listener](co::Coroutine* c) { absl::StatusOr s = listener.Accept(c); ASSERT_TRUE(s.ok()); auto socket = s.value(); @@ -162,7 +164,7 @@ TEST(SocketsTest, UnixSocketZeroFds) { ASSERT_TRUE(fds.empty()); }); - co::Coroutine outgoing(scheduler, [&socket_name](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(scheduler, [&socket_name](co::Coroutine* c) { toolbelt::UnixSocket socket; absl::Status s = socket.Connect(socket_name); ASSERT_TRUE(s.ok()); @@ -190,7 +192,7 @@ TEST(SocketsTest, UnixSocketShortFdCountRead) { absl::Status status = listener.Bind(socket_name, true); ASSERT_TRUE(status.ok()); - co::Coroutine incoming(scheduler, [&listener](co::Coroutine* c) { + co::ScheduledCoroutine incoming(scheduler, [&listener](co::Coroutine* c) { absl::StatusOr s = listener.Accept(c); ASSERT_TRUE(s.ok()); auto socket = s.value(); @@ -198,10 +200,10 @@ TEST(SocketsTest, UnixSocketShortFdCountRead) { std::vector fds; absl::Status s2 = socket.ReceiveFds(fds, c); ASSERT_TRUE(s2.ok()); - ASSERT_EQ(1, fds.size()); + ASSERT_EQ(std::size_t{1}, fds.size()); }); - co::Coroutine outgoing(scheduler, [&socket_name](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(scheduler, [&socket_name](co::Coroutine* c) { toolbelt::UnixSocket socket; absl::Status s = socket.Connect(socket_name); ASSERT_TRUE(s.ok()); @@ -256,7 +258,7 @@ TEST(SocketsTest, TCPSocket) { absl::Status status = listener.Bind(addr, true); ASSERT_TRUE(status.ok()); - co::Coroutine incoming(scheduler, [&listener](co::Coroutine* c) { + co::ScheduledCoroutine incoming(scheduler, [&listener](co::Coroutine* c) { absl::StatusOr s = listener.Accept(c); ASSERT_TRUE(s.ok()); auto socket = s.value(); @@ -264,11 +266,11 @@ TEST(SocketsTest, TCPSocket) { absl::StatusOr> b = socket.ReceiveVariableLengthMessage(c); ASSERT_TRUE(b.ok()); auto buf = b.value(); - ASSERT_EQ(12, buf.size()); // "hello world\0" + ASSERT_EQ(std::size_t{12}, buf.size()); // "hello world\0" ASSERT_EQ("hello world", std::string(buf.data(), 11)); }); - co::Coroutine outgoing(scheduler, [&addr](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(scheduler, [&addr](co::Coroutine* c) { toolbelt::TCPSocket socket; absl::Status s = socket.Connect(addr); ASSERT_TRUE(s.ok()); @@ -295,7 +297,7 @@ TEST(SocketsTest, BigTCPSocketNonblocking) { ASSERT_TRUE(status.ok()); constexpr size_t kBufferSize = 10 * 1024 * 1024; - co::Coroutine incoming(scheduler, [&listener, kBufferSize](co::Coroutine* c) { + co::ScheduledCoroutine incoming(scheduler, [&listener, kBufferSize](co::Coroutine* c) { absl::StatusOr s = listener.Accept(c); ASSERT_TRUE(s.ok()); auto socket = s.value(); @@ -310,11 +312,11 @@ TEST(SocketsTest, BigTCPSocketNonblocking) { std::cerr << "Mismatch at " << i << ": " << buf[i] << " != " << 'a' + (i % 26) << "\n"; } - ASSERT_EQ('a' + ((i + 4) % 26), buf[i]); + ASSERT_EQ(static_cast('a' + ((i + 4) % 26)), buf[i]); } }); - co::Coroutine outgoing(scheduler, [&addr](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(scheduler, [&addr](co::Coroutine* c) { toolbelt::TCPSocket socket; absl::Status s = socket.Connect(addr); ASSERT_TRUE(s.ok()); @@ -326,7 +328,7 @@ TEST(SocketsTest, BigTCPSocketNonblocking) { absl::StatusOr nsent = socket.SendMessage(buffer.data() + 4, buffer.size() - 4, c); ASSERT_TRUE(nsent.ok()); - ASSERT_EQ(buffer.size(), nsent.value()); + ASSERT_EQ(buffer.size(), static_cast(nsent.value())); }); scheduler.Run(); @@ -343,7 +345,7 @@ TEST(SocketsTest, BigTCPSocketBlocking) { ASSERT_TRUE(status.ok()); constexpr size_t kBufferSize = 10 * 1024 * 1024; - co::Coroutine incoming( + co::ScheduledCoroutine incoming( sendScheduler, [&listener, kBufferSize](co::Coroutine* c) { absl::StatusOr s = listener.Accept(c); ASSERT_TRUE(s.ok()); @@ -358,11 +360,11 @@ TEST(SocketsTest, BigTCPSocketBlocking) { std::cerr << "Mismatch at " << i << ": " << buf[i] << " != " << 'a' + (i % 26) << "\n"; } - ASSERT_EQ('a' + ((i + 4) % 26), buf[i]); + ASSERT_EQ(static_cast('a' + ((i + 4) % 26)), buf[i]); } }); - co::Coroutine outgoing(ReceiveScheduler, [&addr](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(ReceiveScheduler, [&addr](co::Coroutine* c) { toolbelt::TCPSocket socket; absl::Status s = socket.Connect(addr); ASSERT_TRUE(s.ok()); @@ -373,7 +375,7 @@ TEST(SocketsTest, BigTCPSocketBlocking) { absl::StatusOr nsent = socket.SendMessage(buffer.data() + 4, buffer.size() - 4, c); ASSERT_TRUE(nsent.ok()); - ASSERT_EQ(buffer.size(), nsent.value()); + ASSERT_EQ(buffer.size(), static_cast(nsent.value())); }); std::thread sender([&sendScheduler]() { sendScheduler.Run(); }); @@ -393,7 +395,7 @@ TEST(SocketsTest, TCPSocketInterrupt) { absl::Status status = listener.Bind(addr, true); ASSERT_TRUE(status.ok()); - co::Coroutine incoming( + co::ScheduledCoroutine incoming( scheduler, [&listener](co::Coroutine* c) { absl::StatusOr s = listener.Accept(c); @@ -401,7 +403,7 @@ TEST(SocketsTest, TCPSocketInterrupt) { }, co::CoroutineOptions{.name = "foo", .interrupt_fd = scheduler.GetInterruptFd()}); - co::Coroutine interrupt(scheduler, [](co::Coroutine* c) { + co::ScheduledCoroutine interrupt(scheduler, [](co::Coroutine* c) { c->Yield(); c->Scheduler().TriggerInterrupt(); }); @@ -420,7 +422,7 @@ TEST(SocketsTest, TCPSocket2) { absl::Status status = listener.Bind(addr, true); ASSERT_TRUE(status.ok()); - co::Coroutine incoming(scheduler, [&listener](co::Coroutine* c) { + co::ScheduledCoroutine incoming(scheduler, [&listener](co::Coroutine* c) { absl::StatusOr s = listener.Accept(c); ASSERT_TRUE(s.ok()); auto socket = s.value(); @@ -434,7 +436,7 @@ TEST(SocketsTest, TCPSocket2) { std::vector fds; }); - co::Coroutine outgoing(scheduler, [&addr](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(scheduler, [&addr](co::Coroutine* c) { toolbelt::TCPSocket socket; absl::Status s = socket.Connect(addr); ASSERT_TRUE(s.ok()); @@ -461,7 +463,7 @@ TEST(SocketsTest, TCPSocket3) { ASSERT_TRUE(status.ok()); toolbelt::InetAddress baddr = listener.BoundAddress(); - co::Coroutine incoming(scheduler, [&listener](co::Coroutine* c) { + co::ScheduledCoroutine incoming(scheduler, [&listener](co::Coroutine* c) { absl::StatusOr s = listener.Accept(c); ASSERT_TRUE(s.ok()); auto socket = s.value(); @@ -475,7 +477,7 @@ TEST(SocketsTest, TCPSocket3) { std::vector fds; }); - co::Coroutine outgoing(scheduler, [&baddr](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(scheduler, [&baddr](co::Coroutine* c) { toolbelt::TCPSocket socket; absl::Status s = socket.Connect(baddr); ASSERT_TRUE(s.ok()); @@ -518,7 +520,7 @@ TEST(SocketsTest, UDPSocket) { co::CoroutineScheduler scheduler; - co::Coroutine incoming(scheduler, [&Receiver](co::Coroutine* c) { + co::ScheduledCoroutine incoming(scheduler, [&Receiver](co::Coroutine* c) { toolbelt::UDPSocket socket; absl::Status s1 = socket.Bind(Receiver); ASSERT_TRUE(s1.ok()); @@ -531,7 +533,7 @@ TEST(SocketsTest, UDPSocket) { ASSERT_EQ("hello world", std::string(buffer, n - 1)); }); - co::Coroutine outgoing(scheduler, [&sender, &Receiver](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(scheduler, [&sender, &Receiver](co::Coroutine* c) { toolbelt::UDPSocket socket; absl::Status s1 = socket.Bind(sender); ASSERT_TRUE(s1.ok()); @@ -554,7 +556,7 @@ TEST(SocketsTest, UDPSocket2) { co::CoroutineScheduler scheduler; - co::Coroutine incoming(scheduler, [&receiver, &sender](co::Coroutine* c) { + co::ScheduledCoroutine incoming(scheduler, [&receiver, &sender](co::Coroutine* c) { toolbelt::UDPSocket socket; absl::Status s1 = socket.Bind(receiver); ASSERT_TRUE(s1.ok()); @@ -569,7 +571,7 @@ TEST(SocketsTest, UDPSocket2) { ASSERT_EQ(sender, from); }); - co::Coroutine outgoing(scheduler, [&sender, &receiver](co::Coroutine* c) { + co::ScheduledCoroutine outgoing(scheduler, [&sender, &receiver](co::Coroutine* c) { toolbelt::UDPSocket socket; absl::Status s1 = socket.Bind(sender); ASSERT_TRUE(s1.ok()); @@ -609,7 +611,7 @@ TEST(SocketsTest, UDPSocket_SendAndReceiveUnicast) { ASSERT_TRUE(sender.SendTo(sendto_address, TEST_DATA.data(), TEST_DATA.size()).ok()); std::vector Receive_buffer(TEST_DATA.size()); - ASSERT_EQ(*Receiver.Receive(Receive_buffer.data(), Receive_buffer.size()), TEST_DATA.size()); + ASSERT_EQ(static_cast(*Receiver.Receive(Receive_buffer.data(), Receive_buffer.size())), TEST_DATA.size()); ASSERT_EQ(std::string_view(Receive_buffer.data(), Receive_buffer.size()), TEST_DATA); } @@ -632,7 +634,7 @@ TEST(SocketsTest, UDPSocket_SendAndReceiveBroadcast) { ASSERT_TRUE(sender.SendTo(sendto_address, TEST_DATA.data(), TEST_DATA.size()).ok()); std::vector Receive_buffer(TEST_DATA.size()); - ASSERT_EQ(*Receiver.Receive(Receive_buffer.data(), Receive_buffer.size()), TEST_DATA.size()); + ASSERT_EQ(static_cast(*Receiver.Receive(Receive_buffer.data(), Receive_buffer.size())), TEST_DATA.size()); ASSERT_EQ(std::string_view(Receive_buffer.data(), Receive_buffer.size()), TEST_DATA); } @@ -663,7 +665,7 @@ TEST(SocketsTest, UDPSocket_SendAndReceiveMulticast) { while (absl::Now() < timeout) { auto status_or_len = Receiver.Receive(Receive_buffer.data(), Receive_buffer.size()); if (status_or_len.ok()) { - ASSERT_EQ(*status_or_len, TEST_DATA.size()); + ASSERT_EQ(static_cast(*status_or_len), TEST_DATA.size()); ASSERT_EQ(std::string_view(Receive_buffer.data(), Receive_buffer.size()), TEST_DATA); break; }