mirror of https://github.com/grpc/grpc.git
Merge https://github.com/grpc/grpc into requires2
commit
8e4f033317
100 changed files with 1286 additions and 528 deletions
@ -1,3 +0,0 @@ |
||||
# Top level ownership |
||||
@markdroth **/OWNERS |
||||
@a11r **/OWNERS |
@ -0,0 +1,98 @@ |
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_LIB_PROMISE_INTER_ACTIVITY_LATCH_H |
||||
#define GRPC_SRC_CORE_LIB_PROMISE_INTER_ACTIVITY_LATCH_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include <string> |
||||
|
||||
#include "absl/base/thread_annotations.h" |
||||
#include "absl/strings/str_cat.h" |
||||
|
||||
#include <grpc/support/log.h> |
||||
|
||||
#include "src/core/lib/gprpp/sync.h" |
||||
#include "src/core/lib/promise/activity.h" |
||||
#include "src/core/lib/promise/poll.h" |
||||
#include "src/core/lib/promise/trace.h" |
||||
#include "src/core/lib/promise/wait_set.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
// A latch providing true cross activity wakeups
|
||||
template <typename T> |
||||
class InterActivityLatch; |
||||
|
||||
template <> |
||||
class InterActivityLatch<void> { |
||||
public: |
||||
InterActivityLatch() = default; |
||||
InterActivityLatch(const InterActivityLatch&) = delete; |
||||
InterActivityLatch& operator=(const InterActivityLatch&) = delete; |
||||
|
||||
// Produce a promise to wait for this latch.
|
||||
auto Wait() { |
||||
return [this]() -> Poll<Empty> { |
||||
MutexLock lock(&mu_); |
||||
if (grpc_trace_promise_primitives.enabled()) { |
||||
gpr_log(GPR_INFO, "%sPollWait %s", DebugTag().c_str(), |
||||
StateString().c_str()); |
||||
} |
||||
if (is_set_) { |
||||
return Empty{}; |
||||
} else { |
||||
return waiters_.AddPending(Activity::current()->MakeNonOwningWaker()); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
// Set the latch.
|
||||
void Set() { |
||||
MutexLock lock(&mu_); |
||||
if (grpc_trace_promise_primitives.enabled()) { |
||||
gpr_log(GPR_INFO, "%sSet %s", DebugTag().c_str(), StateString().c_str()); |
||||
} |
||||
is_set_ = true; |
||||
waiters_.WakeupAsync(); |
||||
} |
||||
|
||||
bool IsSet() const ABSL_LOCKS_EXCLUDED(mu_) { |
||||
MutexLock lock(&mu_); |
||||
return is_set_; |
||||
} |
||||
|
||||
private: |
||||
std::string DebugTag() { |
||||
return absl::StrCat(Activity::current()->DebugTag(), |
||||
" INTER_ACTIVITY_LATCH[0x", |
||||
reinterpret_cast<uintptr_t>(this), "]: "); |
||||
} |
||||
|
||||
std::string StateString() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { |
||||
return absl::StrCat("is_set:", is_set_); |
||||
} |
||||
|
||||
mutable Mutex mu_; |
||||
// True if we have a value set, false otherwise.
|
||||
bool is_set_ = false; |
||||
WaitSet waiters_ ABSL_GUARDED_BY(mu_); |
||||
}; |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_PROMISE_INTER_ACTIVITY_LATCH_H
|
@ -1,7 +1,7 @@ |
||||
<!-- This file is generated --> |
||||
<Project> |
||||
<PropertyGroup> |
||||
<GrpcCsharpVersion>2.60.0-dev</GrpcCsharpVersion> |
||||
<GrpcCsharpVersion>2.61.0-dev</GrpcCsharpVersion> |
||||
<GoogleProtobufVersion>3.25.0</GoogleProtobufVersion> |
||||
</PropertyGroup> |
||||
</Project> |
||||
|
@ -0,0 +1,103 @@ |
||||
// Copyright 2023 gRPC authors.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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 "src/core/lib/promise/inter_activity_latch.h" |
||||
|
||||
#include "absl/status/status.h" |
||||
#include "gtest/gtest.h" |
||||
|
||||
#include <grpc/grpc.h> |
||||
|
||||
#include "src/core/lib/event_engine/default_event_engine.h" |
||||
#include "src/core/lib/gprpp/notification.h" |
||||
#include "src/core/lib/promise/event_engine_wakeup_scheduler.h" |
||||
#include "src/core/lib/promise/seq.h" |
||||
|
||||
using grpc_event_engine::experimental::GetDefaultEventEngine; |
||||
|
||||
namespace grpc_core { |
||||
namespace { |
||||
|
||||
TEST(InterActivityLatchTest, Works) { |
||||
InterActivityLatch<void> latch; |
||||
|
||||
// Start some waiting activities
|
||||
Notification n1; |
||||
auto a1 = MakeActivity( |
||||
[&] { |
||||
return Seq(latch.Wait(), [&](Empty) { |
||||
n1.Notify(); |
||||
return absl::OkStatus(); |
||||
}); |
||||
}, |
||||
EventEngineWakeupScheduler{GetDefaultEventEngine()}, [](absl::Status) {}); |
||||
Notification n2; |
||||
auto a2 = MakeActivity( |
||||
[&] { |
||||
return Seq(latch.Wait(), [&](Empty) { |
||||
n2.Notify(); |
||||
return absl::OkStatus(); |
||||
}); |
||||
}, |
||||
EventEngineWakeupScheduler{GetDefaultEventEngine()}, [](absl::Status) {}); |
||||
Notification n3; |
||||
auto a3 = MakeActivity( |
||||
[&] { |
||||
return Seq(latch.Wait(), [&](Empty) { |
||||
n3.Notify(); |
||||
return absl::OkStatus(); |
||||
}); |
||||
}, |
||||
EventEngineWakeupScheduler{GetDefaultEventEngine()}, [](absl::Status) {}); |
||||
|
||||
ASSERT_FALSE(n1.HasBeenNotified()); |
||||
ASSERT_FALSE(n2.HasBeenNotified()); |
||||
ASSERT_FALSE(n3.HasBeenNotified()); |
||||
|
||||
// Start a setting activity
|
||||
auto kicker = MakeActivity( |
||||
[&] { |
||||
latch.Set(); |
||||
return absl::OkStatus(); |
||||
}, |
||||
EventEngineWakeupScheduler{GetDefaultEventEngine()}, [](absl::Status) {}); |
||||
|
||||
// Start another waiting activity
|
||||
Notification n4; |
||||
auto a4 = MakeActivity( |
||||
[&] { |
||||
return Seq(latch.Wait(), [&](Empty) { |
||||
n4.Notify(); |
||||
return absl::OkStatus(); |
||||
}); |
||||
}, |
||||
EventEngineWakeupScheduler{GetDefaultEventEngine()}, [](absl::Status) {}); |
||||
|
||||
// Everything should finish
|
||||
n1.WaitForNotification(); |
||||
n2.WaitForNotification(); |
||||
n3.WaitForNotification(); |
||||
n4.WaitForNotification(); |
||||
} |
||||
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
||||
int main(int argc, char** argv) { |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
grpc_init(); // for GetDefaultEventEngine
|
||||
int r = RUN_ALL_TESTS(); |
||||
grpc_shutdown(); |
||||
return r; |
||||
} |
Loading…
Reference in new issue