From 844bf42e7ef3fc6bc6207e8a9b13e99d455703f1 Mon Sep 17 00:00:00 2001 From: lasan Date: Thu, 11 Jun 2026 12:42:59 +0530 Subject: [PATCH] Revert "removed bluetooth_classic_socket specific stream semantics. all linux sockets should use stream.h. improved stream semantics in stream.h" This reverts commit 18970db59805ee40e0f8653105e0e7a42cc09121. --- MODULE.bazel | 12 -- MODULE.bazel.lock | 183 +++++++++++++++++- internal/platform/implementation/linux/BUILD | 38 ++-- .../implementation/linux/ble_l2cap_socket.cc | 49 +++-- .../implementation/linux/ble_l2cap_socket.h | 2 - .../linux/bluetooth_classic_socket.cc | 126 ++++++++++++ .../linux/bluetooth_classic_socket.h | 41 +++- .../platform/implementation/linux/stream.cc | 147 +++----------- .../platform/implementation/linux/stream.h | 8 +- .../implementation/linux/timer_test.cc | 31 +-- sharing/linux/BUILD | 17 -- 11 files changed, 424 insertions(+), 230 deletions(-) create mode 100644 internal/platform/implementation/linux/bluetooth_classic_socket.cc diff --git a/MODULE.bazel b/MODULE.bazel index a465e98b..33450200 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -122,18 +122,6 @@ filegroup( ], ) -# Bazel Compile Commands Extractor (helly25 fork; see FORK.md for context) -# https://github.com/helly25/bazel-compile-commands-extractor -bazel_dep(name = "hedron_compile_commands", dev_dependency = True) # Bazel module name kept for backwards compat with existing consumers. -git_override( - module_name = "hedron_compile_commands", - remote = "https://github.com/helly25/bazel-compile-commands-extractor.git", - commit = "75ba4c31d3b74fa5fb57c7508220571d4e52f828", - # Replace the commit hash with the latest from - # https://github.com/helly25/bazel-compile-commands-extractor/commits/main - # (or set up Renovate; see below). -) - # Create a repo that exposes system-installed sdbus-c++ and libsystemd to Bazel. # # Important portability note: diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index a4169fee..348ddaef 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -40,8 +40,7 @@ "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.43.0/MODULE.bazel": "defa2226f06ba20550d6548c3a2ea2a7929634437a52973869c20c225450eb91", - "https://bcr.bazel.build/modules/bazel_features/1.43.0/source.json": "1c4207dc858d6de0eecef30026793616bbf420c74aac27b6bad212534a730437", + "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", @@ -54,7 +53,6 @@ "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", "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.0/MODULE.bazel": "2fb3fb53675f6adfc1ca5bfbd5cfb655ae350fba4706d924a8ec7e3ba945671c", "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", @@ -132,8 +130,7 @@ "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", "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.18/MODULE.bazel": "4460ec36adc8f722a6a2a4ac9374cb91f2acebadaa93fc37966129afb3dece87", - "https://bcr.bazel.build/modules/rules_cc/0.2.18/source.json": "abad668ff2fd63ada1ac49bf386d37e27048b89a3465a6fd968bb832b00a09d3", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", "https://bcr.bazel.build/modules/rules_cc/0.2.9/MODULE.bazel": "34263f1dca62ea664265438cef714d7db124c03e1ed55ebb4f1dc860164308d1", @@ -189,8 +186,7 @@ "https://bcr.bazel.build/modules/rules_python/1.5.1/MODULE.bazel": "acfe65880942d44a69129d4c5c3122d57baaf3edf58ae5a6bd4edea114906bf5", "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/2.0.1/MODULE.bazel": "294fbfe4dc3b24a925172e5487e1e8d3c2927cf4fba1eaddd7bad0ce50701da1", - "https://bcr.bazel.build/modules/rules_python/2.0.1/source.json": "f2bacc75d3fc496dfd3e6a5986200b10e70169aaaf4ee5f1cea573c8d347e7c4", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", "https://bcr.bazel.build/modules/rules_rust/0.68.1/MODULE.bazel": "8d3332ef4079673385eb81f8bd68b012decc04ac00c9d5a01a40eff90301732c", "https://bcr.bazel.build/modules/rules_rust/0.68.1/source.json": "3378e746f81b62457fdfd37391244fa8ff075ba85c05931ee4f3a20ac1efe963", "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", @@ -206,6 +202,7 @@ "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", "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", @@ -275,10 +272,178 @@ } } }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "iibnRYgg8LpcfmH7EAnVwYePC3jsVaJ6Id8XxUjSZps=", + "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": "I8FPZMevE2oI/peSpMBRVIN++WOtfjtJVjbPsBZQ87A=", - "usagesDigest": "KI88AZslgI1K52IZ7PfBqhuXb5hke0gUD9N73XeVqaI=", + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", "recordedInputs": [ "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", "REPO_MAPPING:rules_python+,platforms platforms" diff --git a/internal/platform/implementation/linux/BUILD b/internal/platform/implementation/linux/BUILD index ad1b127e..8ee54236 100644 --- a/internal/platform/implementation/linux/BUILD +++ b/internal/platform/implementation/linux/BUILD @@ -12,24 +12,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands") +#load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands") + load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") - -refresh_compile_commands( - name = "refresh_compile_commands_linux", - - # Specify the targets of interest. - # For example, specify a dict of targets and any flags required to build. - targets = { - ":linux": "-s --check_visibility=false --spawn_strategy=standalone --verbose_failures --cxxopt=-std=c++20 --host_cxxopt=-std=c++20 --cxxopt='-fvisibility-inlines-hidden'", - }, - # No need to add flags already in .bazelrc. They're automatically picked up. - # If you don't need flags, a list of targets is also okay, as is a single target string. - # Wildcard patterns, like //... for everything, *are* allowed here, just like a build. - # As are additional targets (+) and subtractions (-), like in bazel query https://docs.bazel.build/versions/main/query.html#expressions - # And if you're working on a header-only library, specify a test or binary target that compiles it. -) - +#refresh_compile_commands( +# name = "refresh_compile_commands", +# +# # Specify the targets of interest. +# # For example, specify a dict of targets and any flags required to build. +# targets = { +# ":linux": "-s --check_visibility=false --spawn_strategy=standalone --verbose_failures --strip=never --copt=-O0 --copt=-g --copt=-fno-omit-frame-pointer", +# "//connections:core": "-s --check_visibility=false --spawn_strategy=standalone --verbose_failures --strip=never --copt=-O0 --copt=-g --copt=-fno-omit-frame-pointer", +# "//connections/file_share:file_share": "-s --check_visibility=false --spawn_strategy=standalone --verbose_failures --strip=never --copt=-O0 --copt=-g --copt=-fno-omit-frame-pointer", +# }, +# # No need to add flags already in .bazelrc. They're automatically picked up. +# # If you don't need flags, a list of targets is also okay, as is a single target string. +# # Wildcard patterns, like //... for everything, *are* allowed here, just like a build. +# # As are additional targets (+) and subtractions (-), like in bazel query https://docs.bazel.build/versions/main/query.html#expressions +# # And if you're working on a header-only library, specify a test or binary target that compiles it. +#) licenses(["notice"]) @@ -199,6 +200,7 @@ cc_library( "ble_l2cap_socket.cc", "bluetooth_adapter.cc", "bluetooth_bluez_profile.cc", + "bluetooth_classic_socket.cc", "bluetooth_classic_device.cc", "bluetooth_classic_medium.cc", "bluetooth_classic_server_socket.cc", @@ -312,7 +314,7 @@ cc_test( # "bluetooth_adapter_test.cc", "crypto_test.cc", # "executor_test.cc", - # "file_path_test.cc", + "file_path_test.cc", # "http_loader_test.cc", # "preferences_manager_test.cc", # "preferences_repository_test.cc", diff --git a/internal/platform/implementation/linux/ble_l2cap_socket.cc b/internal/platform/implementation/linux/ble_l2cap_socket.cc index a12ad0a7..e8f26c0c 100644 --- a/internal/platform/implementation/linux/ble_l2cap_socket.cc +++ b/internal/platform/implementation/linux/ble_l2cap_socket.cc @@ -34,9 +34,7 @@ namespace nearby { namespace linux { -BleL2capInputStream::~BleL2capInputStream() { - Close(); -} +BleL2capInputStream::~BleL2capInputStream() { Close(); } ExceptionOr BleL2capInputStream::Read(std::int64_t size) { std::vector buffer(size); @@ -56,24 +54,22 @@ ExceptionOr BleL2capInputStream::Read(std::int64_t size) { } if (pfds[0].revents & POLLIN) { auto r = recv(fd_raw_->get(), buffer.data() + rcvd, size - rcvd, 0); - if (r < 0) { - return Exception{Exception::kIo}; - } + if (r < 0){ return Exception{Exception::kIo};} rcvd += r; } } + return ExceptionOr{ByteArray(std::string(buffer.begin(), buffer.end()))}; } Exception BleL2capInputStream::Close() { if (!fd_raw_->isValid()) return {Exception::kSuccess}; - fd_raw_->reset(); - return {Exception::kSuccess}; -} -BleL2capOutputStream::~BleL2capOutputStream() { - Close(); + fd_raw_ -> reset(); + return {Exception::kSuccess}; + } +BleL2capOutputStream::~BleL2capOutputStream() { Close(); } Exception BleL2capOutputStream::Write(absl::string_view data) { pollfd pfds[1]; @@ -91,9 +87,7 @@ Exception BleL2capOutputStream::Write(absl::string_view data) { } if (pfds[0].revents & POLLOUT) { auto r = send(fd_raw_->get(), data.data() + sent, data.size(), 0); - if (r < 0) { - return Exception{Exception::kIo}; - } + if (r < 0){ return Exception{Exception::kIo};} sent += r; } } @@ -102,29 +96,32 @@ Exception BleL2capOutputStream::Write(absl::string_view data) { Exception BleL2capOutputStream::Close() { if (!fd_raw_->isValid()) return {Exception::kSuccess}; - fd_raw_->reset(); - return {Exception::kSuccess}; + fd_raw_ -> reset(); + return {Exception::kSuccess}; } BleL2capSocket::BleL2capSocket(int fd, api::ble::BlePeripheral::UniqueId peripheral_id, - std::string service_id) - : fd_(std::make_shared(fd)), - input_stream_(std::make_unique(fd_)), + std::string service_id + ) + : fd_(std::make_shared(fd)), input_stream_(std::make_unique(fd_)), output_stream_(std::make_unique(fd_)), - peripheral_id_(peripheral_id) {} + peripheral_id_(peripheral_id) + {} + +BleL2capSocket::~BleL2capSocket() { Close(); } + -BleL2capSocket::~BleL2capSocket() { - Close(); -} Exception BleL2capSocket::Close() { if (!fd_->isValid()) return {Exception::kIo}; - fd_->reset(); - return {Exception::kSuccess}; + fd_ -> reset(); + return {Exception::kSuccess}; } -void BleL2capSocket::SetCloseNotifier(absl::AnyInvocable notifier) {} + +void BleL2capSocket::SetCloseNotifier(absl::AnyInvocable notifier) { +} bool BleL2capSocket::IsClosed() const { return closed_; diff --git a/internal/platform/implementation/linux/ble_l2cap_socket.h b/internal/platform/implementation/linux/ble_l2cap_socket.h index d13ba98c..cdea0bf1 100644 --- a/internal/platform/implementation/linux/ble_l2cap_socket.h +++ b/internal/platform/implementation/linux/ble_l2cap_socket.h @@ -35,8 +35,6 @@ namespace nearby { namespace linux { -// TODO: use linux stream instead of bespoke l2cap input/output stream - class BleL2capSocket; class BleL2capInputStream final : public InputStream { diff --git a/internal/platform/implementation/linux/bluetooth_classic_socket.cc b/internal/platform/implementation/linux/bluetooth_classic_socket.cc new file mode 100644 index 00000000..f1ff28f7 --- /dev/null +++ b/internal/platform/implementation/linux/bluetooth_classic_socket.cc @@ -0,0 +1,126 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include + +#include "internal/platform/byte_array.h" +#include "internal/platform/exception.h" +#include "internal/platform/implementation/linux/bluetooth_classic_socket.h" +#include "internal/platform/logging.h" + +#include +#include +#include +#include +#include + +namespace nearby { +namespace linux { + +// This method blocks until input data is available, end of file is detected, or an exception is thrown. +ExceptionOr BluetoothInputStream::Read(std::int64_t size) { + // Sanity: avoid negative / zero sizes + if (size <= 0) return ExceptionOr{ByteArray(std::string())}; + + + std::vector buffer(size); + + // fd returned from bluez assumed to be stream type always + + pollfd pfds[1]; + pfds[0].fd = fd_raw_->get(); + pfds[0].events = POLLIN; + ssize_t rcvd = 0; + + while (rcvd < size) { + int r = poll(pfds, 1, -1); + if (r < 0) { + if (errno == EINTR) { + continue; + } + return Exception{Exception::kIo}; + } + if (pfds[0].revents & POLLIN) { + while (rcvd < size) { + + auto r = recv(fd_raw_->get(), buffer.data() + rcvd, size - rcvd, 0); + if (r > 0) { + rcvd += r; + continue; + } + if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {continue;} + + LOG(ERROR) << __func__ + << ": error reading from fd: " << std::strerror(errno); + return {Exception::kIo}; + } + } + } + + + return ExceptionOr{ByteArray(std::string(buffer.begin(), buffer.end()))}; +} + +Exception BluetoothInputStream::Close() { + if (!fd_raw_->isValid()) return {Exception::kSuccess}; + fd_raw_ -> reset(); + return {Exception::kSuccess}; +} + +Exception BluetoothOutputStream::Write(absl::string_view data) { + pollfd pfds[1]; + pfds[0].fd = fd_raw_->get(); + pfds[0].events = POLLOUT; + ssize_t sent = 0; + + while (sent < data.size()) { + int r = poll(pfds, 1, -1); + if (r < 0) { + if (errno == EINTR) { + continue; + } + return Exception{Exception::kIo}; + } + if (pfds[0].revents & POLLOUT) { + while (sent < data.size()) { + auto r = send(fd_raw_->get(), data.data() + sent, data.size(), 0); + if (r > 0) { + sent += r; + continue; + } + if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {continue;} + + LOG(ERROR) << __func__ + << ": error reading from fd: " << std::strerror(errno); + return {Exception::kIo}; + } + } + } + return {Exception::kSuccess}; +} + +Exception BluetoothOutputStream::Close() { + if (!fd_raw_->isValid()) return {Exception::kSuccess}; + fd_raw_ -> reset(); + return {Exception::kSuccess}; +} + +} // namespace linux +} // namespace nearby diff --git a/internal/platform/implementation/linux/bluetooth_classic_socket.h b/internal/platform/implementation/linux/bluetooth_classic_socket.h index a1353713..b9fe89e6 100644 --- a/internal/platform/implementation/linux/bluetooth_classic_socket.h +++ b/internal/platform/implementation/linux/bluetooth_classic_socket.h @@ -27,21 +27,46 @@ #include "internal/platform/exception.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/linux/bluetooth_classic_device.h" - -#include "internal/platform/implementation/linux/stream.h" +#include "internal/platform/input_stream.h" +#include "internal/platform/output_stream.h" namespace nearby { namespace linux { +class BluetoothInputStream final : public nearby::InputStream { + public: + explicit BluetoothInputStream(std::shared_ptr fd) + : fd_raw_(std::move(fd)){} + + ExceptionOr Read(std::int64_t size) override; + Exception Close() override; + + private: + std::shared_ptr fd_raw_; +}; + +class BluetoothOutputStream : public nearby::OutputStream { + public: + explicit BluetoothOutputStream(std::shared_ptr fd) + : fd_raw_(std::move(fd)) {} + + Exception Write(absl::string_view data) override; + Exception Flush() override { return {Exception::kSuccess}; } + Exception Close() override; + + private: + mutable absl::Mutex fd_mutex_; + std::shared_ptr fd_raw_; +}; class BluetoothSocket final : public api::BluetoothSocket { public: BluetoothSocket(std::shared_ptr device, sdbus::UnixFd fd) - :fd_(fd), device_(std::move(device)), output_stream_(fd_), input_stream_(fd_) {} + :fd_(std::make_shared(fd)), device_(std::move(device)), output_stream_(fd_), input_stream_(fd_) {} - InputStream &GetInputStream() override { return input_stream_; } - OutputStream &GetOutputStream() override { return output_stream_; } + nearby::InputStream &GetInputStream() override { return input_stream_; } + nearby::OutputStream &GetOutputStream() override { return output_stream_; } Exception Close() override { input_stream_.Close(); output_stream_.Close(); @@ -51,10 +76,10 @@ class BluetoothSocket final : public api::BluetoothSocket { api::BluetoothDevice *GetRemoteDevice() override { return device_.get(); }; private: - sdbus::UnixFd fd_; + std::shared_ptr fd_; std::shared_ptr device_; - OutputStream output_stream_; - InputStream input_stream_; + BluetoothOutputStream output_stream_; + BluetoothInputStream input_stream_; }; } // namespace linux } // namespace nearby diff --git a/internal/platform/implementation/linux/stream.cc b/internal/platform/implementation/linux/stream.cc index bf25e427..6bfe13e4 100644 --- a/internal/platform/implementation/linux/stream.cc +++ b/internal/platform/implementation/linux/stream.cc @@ -12,10 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include #include -#include #include #include #include @@ -29,149 +27,52 @@ namespace nearby { namespace linux { ExceptionOr InputStream::Read(std::int64_t size) { - if (size <= 0) { - return ExceptionOr(ByteArray(std::string())); - } - - if (!fd_ || !fd_->isValid()) { - return {Exception::kIo}; - } + if (!fd_.isValid()) return {Exception::kIo}; std::string buffer; buffer.resize(size); - - while (true) { - pollfd pfd{}; - pfd.fd = fd_->get(); - pfd.events = POLLIN; - - int poll_result = poll(&pfd, 1, -1); - - if (poll_result < 0) { - if (errno == EINTR) { - continue; - } - - LOG(ERROR) << __func__ << ": poll failed: " << std::strerror(errno); - return {Exception::kIo}; - } - - if (pfd.revents & POLLNVAL || pfd.revents & POLLERR) { - LOG(ERROR) << __func__ << ": Error reading from BluetoothSocket: " - << std::strerror(errno); - return {Exception::kIo}; - } - - if (pfd.revents & (POLLIN | POLLHUP)) { - ssize_t bytes_read = - recv(fd_->get(), buffer.data(), buffer.size(), 0); - - if (bytes_read > 0) { - buffer.resize(static_cast(bytes_read)); - return ExceptionOr(ByteArray(std::move(buffer))); - } - - if (bytes_read == 0) { - // EOF / peer closed. - return ExceptionOr(ByteArray(std::string())); - } - - if (errno == EINTR) { - continue; - } - - if (errno == EAGAIN || errno == EWOULDBLOCK) { - // Non-blocking fd had no data by the time recv() ran. - // Go back to poll. - continue; - } - - LOG(ERROR) << __func__ << ": recv failed: " << std::strerror(errno); - return {Exception::kIo}; - } + ssize_t ret = recv(fd_.get(), buffer.data(), buffer.size(), MSG_WAITALL); + if (ret == 0) { + return ExceptionOr(ByteArray()); } + if (ret < 0) { + LOG(ERROR) << __func__ + << ": error reading from fd: " << std::strerror(errno); + return {Exception::kIo}; + } + buffer.resize(ret); + + return ExceptionOr(ByteArray(std::move(buffer))); } Exception InputStream::Close() { - if (!fd_->isValid()) return Exception{Exception::kIo}; + if (!fd_.isValid()) return Exception{Exception::kIo}; fd_.reset(); return {}; } Exception OutputStream::Write(absl::string_view data) { - if (!fd_ || !fd_->isValid()) { - return {Exception::kIo}; - } + if (!fd_.isValid()) return Exception{Exception::kIo}; - const int fd = fd_->get(); - size_t sent = 0; - - while (sent < data.size()) { - pollfd pfd{}; - pfd.fd = fd; - pfd.events = POLLOUT; - - int poll_result; - do { - poll_result = poll(&pfd, 1, -1); - } while (poll_result < 0 && errno == EINTR); - - if (poll_result < 0) { + size_t written = 0; + while (written < data.size()) { + ssize_t ret = write(fd_.get(), data.data(), data.size()); + if (ret < 0) { LOG(ERROR) << __func__ - << ": poll failed: " << std::strerror(errno); - return {Exception::kIo}; + << ": error writing to fd: " << std::strerror(errno); + return Exception{Exception::kIo}; } - - if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { - LOG(ERROR) << __func__ - << ": fd error/hangup during write, revents=" << pfd.revents; - return {Exception::kIo}; - } - - if (!(pfd.revents & POLLOUT)) { - continue; - } - - ssize_t n = send( - fd, - data.data() + sent, - data.size() - sent, - MSG_NOSIGNAL); - - if (n > 0) { - sent += static_cast(n); - continue; - } - - if (n == 0) { - LOG(ERROR) << __func__ << ": send returned 0"; - return {Exception::kIo}; - } - - if (errno == EINTR) { - continue; - } - - if (errno == EAGAIN || errno == EWOULDBLOCK) { - // Socket became not writable after poll said it was writable. - // Normal for non-blocking FDs. Go back to poll(). - continue; - } - - LOG(ERROR) << __func__ - << ": error writing to fd: " << std::strerror(errno); - return {Exception::kIo}; + written += ret; } - - return {Exception::kSuccess}; + return Exception{Exception::kSuccess}; } Exception OutputStream::Flush() { return Exception{Exception::kSuccess}; } Exception OutputStream::Close() { - if (!fd_->isValid()) return Exception{Exception::kIo}; + if (!fd_.isValid()) return Exception{Exception::kIo}; - auto ret = close(fd_->get()) < 0 ? Exception{Exception::kIo} + auto ret = close(fd_.get()) < 0 ? Exception{Exception::kIo} : Exception{Exception::kSuccess}; fd_.reset(); return ret; diff --git a/internal/platform/implementation/linux/stream.h b/internal/platform/implementation/linux/stream.h index b4b42f19..66d1c20c 100644 --- a/internal/platform/implementation/linux/stream.h +++ b/internal/platform/implementation/linux/stream.h @@ -26,26 +26,26 @@ namespace nearby { namespace linux { class InputStream : public nearby::InputStream { public: - explicit InputStream(sdbus::UnixFd fd) : fd_(std::make_shared(fd)){}; + explicit InputStream(sdbus::UnixFd fd) : fd_(std::move(fd)){}; ExceptionOr Read(std::int64_t size) override; Exception Close() override; private: - std::shared_ptr fd_; + sdbus::UnixFd fd_; }; class OutputStream : public nearby::OutputStream { public: - explicit OutputStream(sdbus::UnixFd fd) : fd_(std::make_shared(fd)){}; + explicit OutputStream(sdbus::UnixFd fd) : fd_(std::move(fd)){}; Exception Write(absl::string_view data) override; Exception Flush() override; Exception Close() override; private: - std::shared_ptr fd_; + sdbus::UnixFd fd_; }; } // namespace linux diff --git a/internal/platform/implementation/linux/timer_test.cc b/internal/platform/implementation/linux/timer_test.cc index 106df6e4..60308d24 100644 --- a/internal/platform/implementation/linux/timer_test.cc +++ b/internal/platform/implementation/linux/timer_test.cc @@ -14,11 +14,12 @@ #include "internal/platform/implementation/timer.h" +#include // NOLINT +// NOLINT #include +#include // NOLINT #include "gtest/gtest.h" -#include "absl/time/time.h" -#include "internal/platform/count_down_latch.h" #include "internal/platform/implementation/platform.h" namespace nearby { @@ -37,21 +38,29 @@ TEST(Timer, TestCreateTimer) { } // This test case cannot run on Google3 -TEST(Timer, TestRepeatTimer) { - CountDownLatch latch(3); +TEST(Timer, DISABLED_TestRepeatTimer) { int count = 0; + std::unique_ptr timer = nearby::api::ImplementationPlatform::CreateTimer(); ASSERT_TRUE(timer != nullptr); - EXPECT_TRUE(timer->Create(300, 300, [&]() { - ++count; - latch.CountDown(); - })); - - EXPECT_TRUE(latch.Await(absl::Seconds(2))); - EXPECT_EQ(count, 3); + EXPECT_TRUE(timer->Create(300, 300, [&]() { ++count; })); + std::this_thread::sleep_for(std::chrono::seconds(1)); EXPECT_TRUE(timer->Stop()); + EXPECT_EQ(count, 3); +} + +TEST(Timer, DISABLED_TestFireNow) { + int count = 0; + + auto timer = nearby::api::ImplementationPlatform::CreateTimer(); + + EXPECT_TRUE(timer != nullptr); + EXPECT_TRUE(timer->Create(3000, 3000, [&]() { ++count; })); + EXPECT_TRUE(timer->FireNow()); + EXPECT_TRUE(timer->Stop()); + EXPECT_EQ(count, 1); } } // namespace diff --git a/sharing/linux/BUILD b/sharing/linux/BUILD index 29f06fc4..2ea5d434 100644 --- a/sharing/linux/BUILD +++ b/sharing/linux/BUILD @@ -16,23 +16,6 @@ licenses(["notice"]) load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") load("@rules_cc//cc/private/rules_impl:cc_static_library.bzl", "cc_static_library") -load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands") - -refresh_compile_commands( - name = "refresh_compile_commands_sharing", - - # Specify the targets of interest. - # For example, specify a dict of targets and any flags required to build. - targets = { - ":nearby_sharing_api_shared": "-s --check_visibility=false --spawn_strategy=standalone --verbose_failures --cxxopt=-std=c++20 --host_cxxopt=-std=c++20 --cxxopt='-fvisibility-inlines-hidden'", - }, - # No need to add flags already in .bazelrc. They're automatically picked up. - # If you don't need flags, a list of targets is also okay, as is a single target string. - # Wildcard patterns, like //... for everything, *are* allowed here, just like a build. - # As are additional targets (+) and subtractions (-), like in bazel query https://docs.bazel.build/versions/main/query.html#expressions - # And if you're working on a header-only library, specify a test or binary target that compiles it. -) - cc_library( name = "linux_sharing_platform", srcs = ["platform/linux_sharing_platform.cc"],