1 // Copyright 2023 gRPC authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GRPC_SRC_CORE_LIB_PROMISE_DETAIL_JOIN_STATE_H 16 #define GRPC_SRC_CORE_LIB_PROMISE_DETAIL_JOIN_STATE_H 17 18 // This file is generated by tools/codegen/core/gen_join.py 19 20 #include <grpc/support/port_platform.h> 21 22 #include <tuple> 23 #include <type_traits> 24 #include <utility> 25 26 #include "absl/log/check.h" 27 #include "absl/log/log.h" 28 #include "src/core/lib/debug/trace.h" 29 #include "src/core/lib/promise/detail/promise_like.h" 30 #include "src/core/lib/promise/poll.h" 31 #include "src/core/util/bitset.h" 32 #include "src/core/util/construct_destruct.h" 33 34 namespace grpc_core { 35 namespace promise_detail { 36 template <class Traits, typename... Ps> 37 struct JoinState; 38 39 template <class Traits, typename P0, typename P1> 40 struct JoinState<Traits, P0, P1> { 41 template <typename T> 42 using UnwrappedType = decltype(Traits::Unwrapped(std::declval<T>())); 43 using Promise0 = PromiseLike<P0>; 44 using Result0 = UnwrappedType<typename Promise0::Result>; 45 union { 46 GPR_NO_UNIQUE_ADDRESS Promise0 promise0; 47 GPR_NO_UNIQUE_ADDRESS Result0 result0; 48 }; 49 using Promise1 = PromiseLike<P1>; 50 using Result1 = UnwrappedType<typename Promise1::Result>; 51 union { 52 GPR_NO_UNIQUE_ADDRESS Promise1 promise1; 53 GPR_NO_UNIQUE_ADDRESS Result1 result1; 54 }; 55 GPR_NO_UNIQUE_ADDRESS BitSet<2> ready; 56 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(P0&& p0, P1&& p1) { 57 Construct(&promise0, std::forward<P0>(p0)); 58 Construct(&promise1, std::forward<P1>(p1)); 59 } 60 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(const JoinState& other) { 61 DCHECK(other.ready.none()); 62 Construct(&promise0, other.promise0); 63 Construct(&promise1, other.promise1); 64 } 65 JoinState& operator=(const JoinState& other) = delete; 66 JoinState& operator=(JoinState&& other) = delete; 67 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(JoinState&& other) noexcept { 68 DCHECK(other.ready.none()); 69 Construct(&promise0, std::move(other.promise0)); 70 Construct(&promise1, std::move(other.promise1)); 71 } 72 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~JoinState() { 73 if (ready.is_set(0)) { 74 Destruct(&result0); 75 } else { 76 Destruct(&promise0); 77 } 78 if (ready.is_set(1)) { 79 Destruct(&result1); 80 } else { 81 Destruct(&promise1); 82 } 83 } 84 using Result = 85 typename Traits::template ResultType<std::tuple<Result0, Result1>>; 86 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Poll<Result> PollOnce() { 87 if (!ready.is_set(0)) { 88 GRPC_TRACE_VLOG(promise_primitives, 2) 89 << "join[" << this << "]: begin poll joint 1/2"; 90 auto poll = promise0(); 91 GRPC_TRACE_VLOG(promise_primitives, 2) 92 << "join[" << this << "]: end poll joint 1/2 " 93 << (poll.pending() 94 ? "pending" 95 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 96 if (auto* p = poll.value_if_ready()) { 97 if (Traits::IsOk(*p)) { 98 ready.set(0); 99 Destruct(&promise0); 100 Construct(&result0, Traits::Unwrapped(std::move(*p))); 101 } else { 102 return Traits::template EarlyReturn<Result>(std::move(*p)); 103 } 104 } 105 } else { 106 GRPC_TRACE_VLOG(promise_primitives, 2) 107 << "join[" << this << "]: joint 1/2 already ready"; 108 } 109 if (!ready.is_set(1)) { 110 GRPC_TRACE_VLOG(promise_primitives, 2) 111 << "join[" << this << "]: begin poll joint 2/2"; 112 auto poll = promise1(); 113 GRPC_TRACE_VLOG(promise_primitives, 2) 114 << "join[" << this << "]: end poll joint 2/2 " 115 << (poll.pending() 116 ? "pending" 117 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 118 if (auto* p = poll.value_if_ready()) { 119 if (Traits::IsOk(*p)) { 120 ready.set(1); 121 Destruct(&promise1); 122 Construct(&result1, Traits::Unwrapped(std::move(*p))); 123 } else { 124 return Traits::template EarlyReturn<Result>(std::move(*p)); 125 } 126 } 127 } else { 128 GRPC_TRACE_VLOG(promise_primitives, 2) 129 << "join[" << this << "]: joint 2/2 already ready"; 130 } 131 if (ready.all()) { 132 return Traits::FinalReturn(std::move(result0), std::move(result1)); 133 } 134 return Pending{}; 135 } 136 }; 137 138 template <class Traits, typename P0, typename P1, typename P2> 139 struct JoinState<Traits, P0, P1, P2> { 140 template <typename T> 141 using UnwrappedType = decltype(Traits::Unwrapped(std::declval<T>())); 142 using Promise0 = PromiseLike<P0>; 143 using Result0 = UnwrappedType<typename Promise0::Result>; 144 union { 145 GPR_NO_UNIQUE_ADDRESS Promise0 promise0; 146 GPR_NO_UNIQUE_ADDRESS Result0 result0; 147 }; 148 using Promise1 = PromiseLike<P1>; 149 using Result1 = UnwrappedType<typename Promise1::Result>; 150 union { 151 GPR_NO_UNIQUE_ADDRESS Promise1 promise1; 152 GPR_NO_UNIQUE_ADDRESS Result1 result1; 153 }; 154 using Promise2 = PromiseLike<P2>; 155 using Result2 = UnwrappedType<typename Promise2::Result>; 156 union { 157 GPR_NO_UNIQUE_ADDRESS Promise2 promise2; 158 GPR_NO_UNIQUE_ADDRESS Result2 result2; 159 }; 160 GPR_NO_UNIQUE_ADDRESS BitSet<3> ready; 161 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(P0&& p0, P1&& p1, P2&& p2) { 162 Construct(&promise0, std::forward<P0>(p0)); 163 Construct(&promise1, std::forward<P1>(p1)); 164 Construct(&promise2, std::forward<P2>(p2)); 165 } 166 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(const JoinState& other) { 167 DCHECK(other.ready.none()); 168 Construct(&promise0, other.promise0); 169 Construct(&promise1, other.promise1); 170 Construct(&promise2, other.promise2); 171 } 172 JoinState& operator=(const JoinState& other) = delete; 173 JoinState& operator=(JoinState&& other) = delete; 174 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(JoinState&& other) noexcept { 175 DCHECK(other.ready.none()); 176 Construct(&promise0, std::move(other.promise0)); 177 Construct(&promise1, std::move(other.promise1)); 178 Construct(&promise2, std::move(other.promise2)); 179 } 180 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~JoinState() { 181 if (ready.is_set(0)) { 182 Destruct(&result0); 183 } else { 184 Destruct(&promise0); 185 } 186 if (ready.is_set(1)) { 187 Destruct(&result1); 188 } else { 189 Destruct(&promise1); 190 } 191 if (ready.is_set(2)) { 192 Destruct(&result2); 193 } else { 194 Destruct(&promise2); 195 } 196 } 197 using Result = typename Traits::template ResultType< 198 std::tuple<Result0, Result1, Result2>>; 199 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Poll<Result> PollOnce() { 200 if (!ready.is_set(0)) { 201 GRPC_TRACE_VLOG(promise_primitives, 2) 202 << "join[" << this << "]: begin poll joint 1/3"; 203 auto poll = promise0(); 204 GRPC_TRACE_VLOG(promise_primitives, 2) 205 << "join[" << this << "]: end poll joint 1/3 " 206 << (poll.pending() 207 ? "pending" 208 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 209 if (auto* p = poll.value_if_ready()) { 210 if (Traits::IsOk(*p)) { 211 ready.set(0); 212 Destruct(&promise0); 213 Construct(&result0, Traits::Unwrapped(std::move(*p))); 214 } else { 215 return Traits::template EarlyReturn<Result>(std::move(*p)); 216 } 217 } 218 } else { 219 GRPC_TRACE_VLOG(promise_primitives, 2) 220 << "join[" << this << "]: joint 1/3 already ready"; 221 } 222 if (!ready.is_set(1)) { 223 GRPC_TRACE_VLOG(promise_primitives, 2) 224 << "join[" << this << "]: begin poll joint 2/3"; 225 auto poll = promise1(); 226 GRPC_TRACE_VLOG(promise_primitives, 2) 227 << "join[" << this << "]: end poll joint 2/3 " 228 << (poll.pending() 229 ? "pending" 230 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 231 if (auto* p = poll.value_if_ready()) { 232 if (Traits::IsOk(*p)) { 233 ready.set(1); 234 Destruct(&promise1); 235 Construct(&result1, Traits::Unwrapped(std::move(*p))); 236 } else { 237 return Traits::template EarlyReturn<Result>(std::move(*p)); 238 } 239 } 240 } else { 241 GRPC_TRACE_VLOG(promise_primitives, 2) 242 << "join[" << this << "]: joint 2/3 already ready"; 243 } 244 if (!ready.is_set(2)) { 245 GRPC_TRACE_VLOG(promise_primitives, 2) 246 << "join[" << this << "]: begin poll joint 3/3"; 247 auto poll = promise2(); 248 GRPC_TRACE_VLOG(promise_primitives, 2) 249 << "join[" << this << "]: end poll joint 3/3 " 250 << (poll.pending() 251 ? "pending" 252 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 253 if (auto* p = poll.value_if_ready()) { 254 if (Traits::IsOk(*p)) { 255 ready.set(2); 256 Destruct(&promise2); 257 Construct(&result2, Traits::Unwrapped(std::move(*p))); 258 } else { 259 return Traits::template EarlyReturn<Result>(std::move(*p)); 260 } 261 } 262 } else { 263 GRPC_TRACE_VLOG(promise_primitives, 2) 264 << "join[" << this << "]: joint 3/3 already ready"; 265 } 266 if (ready.all()) { 267 return Traits::FinalReturn(std::move(result0), std::move(result1), 268 std::move(result2)); 269 } 270 return Pending{}; 271 } 272 }; 273 274 template <class Traits, typename P0, typename P1, typename P2, typename P3> 275 struct JoinState<Traits, P0, P1, P2, P3> { 276 template <typename T> 277 using UnwrappedType = decltype(Traits::Unwrapped(std::declval<T>())); 278 using Promise0 = PromiseLike<P0>; 279 using Result0 = UnwrappedType<typename Promise0::Result>; 280 union { 281 GPR_NO_UNIQUE_ADDRESS Promise0 promise0; 282 GPR_NO_UNIQUE_ADDRESS Result0 result0; 283 }; 284 using Promise1 = PromiseLike<P1>; 285 using Result1 = UnwrappedType<typename Promise1::Result>; 286 union { 287 GPR_NO_UNIQUE_ADDRESS Promise1 promise1; 288 GPR_NO_UNIQUE_ADDRESS Result1 result1; 289 }; 290 using Promise2 = PromiseLike<P2>; 291 using Result2 = UnwrappedType<typename Promise2::Result>; 292 union { 293 GPR_NO_UNIQUE_ADDRESS Promise2 promise2; 294 GPR_NO_UNIQUE_ADDRESS Result2 result2; 295 }; 296 using Promise3 = PromiseLike<P3>; 297 using Result3 = UnwrappedType<typename Promise3::Result>; 298 union { 299 GPR_NO_UNIQUE_ADDRESS Promise3 promise3; 300 GPR_NO_UNIQUE_ADDRESS Result3 result3; 301 }; 302 GPR_NO_UNIQUE_ADDRESS BitSet<4> ready; 303 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(P0&& p0, P1&& p1, P2&& p2, 304 P3&& p3) { 305 Construct(&promise0, std::forward<P0>(p0)); 306 Construct(&promise1, std::forward<P1>(p1)); 307 Construct(&promise2, std::forward<P2>(p2)); 308 Construct(&promise3, std::forward<P3>(p3)); 309 } 310 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(const JoinState& other) { 311 DCHECK(other.ready.none()); 312 Construct(&promise0, other.promise0); 313 Construct(&promise1, other.promise1); 314 Construct(&promise2, other.promise2); 315 Construct(&promise3, other.promise3); 316 } 317 JoinState& operator=(const JoinState& other) = delete; 318 JoinState& operator=(JoinState&& other) = delete; 319 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(JoinState&& other) noexcept { 320 DCHECK(other.ready.none()); 321 Construct(&promise0, std::move(other.promise0)); 322 Construct(&promise1, std::move(other.promise1)); 323 Construct(&promise2, std::move(other.promise2)); 324 Construct(&promise3, std::move(other.promise3)); 325 } 326 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~JoinState() { 327 if (ready.is_set(0)) { 328 Destruct(&result0); 329 } else { 330 Destruct(&promise0); 331 } 332 if (ready.is_set(1)) { 333 Destruct(&result1); 334 } else { 335 Destruct(&promise1); 336 } 337 if (ready.is_set(2)) { 338 Destruct(&result2); 339 } else { 340 Destruct(&promise2); 341 } 342 if (ready.is_set(3)) { 343 Destruct(&result3); 344 } else { 345 Destruct(&promise3); 346 } 347 } 348 using Result = typename Traits::template ResultType< 349 std::tuple<Result0, Result1, Result2, Result3>>; 350 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Poll<Result> PollOnce() { 351 if (!ready.is_set(0)) { 352 GRPC_TRACE_VLOG(promise_primitives, 2) 353 << "join[" << this << "]: begin poll joint 1/4"; 354 auto poll = promise0(); 355 GRPC_TRACE_VLOG(promise_primitives, 2) 356 << "join[" << this << "]: end poll joint 1/4 " 357 << (poll.pending() 358 ? "pending" 359 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 360 if (auto* p = poll.value_if_ready()) { 361 if (Traits::IsOk(*p)) { 362 ready.set(0); 363 Destruct(&promise0); 364 Construct(&result0, Traits::Unwrapped(std::move(*p))); 365 } else { 366 return Traits::template EarlyReturn<Result>(std::move(*p)); 367 } 368 } 369 } else { 370 GRPC_TRACE_VLOG(promise_primitives, 2) 371 << "join[" << this << "]: joint 1/4 already ready"; 372 } 373 if (!ready.is_set(1)) { 374 GRPC_TRACE_VLOG(promise_primitives, 2) 375 << "join[" << this << "]: begin poll joint 2/4"; 376 auto poll = promise1(); 377 GRPC_TRACE_VLOG(promise_primitives, 2) 378 << "join[" << this << "]: end poll joint 2/4 " 379 << (poll.pending() 380 ? "pending" 381 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 382 if (auto* p = poll.value_if_ready()) { 383 if (Traits::IsOk(*p)) { 384 ready.set(1); 385 Destruct(&promise1); 386 Construct(&result1, Traits::Unwrapped(std::move(*p))); 387 } else { 388 return Traits::template EarlyReturn<Result>(std::move(*p)); 389 } 390 } 391 } else { 392 GRPC_TRACE_VLOG(promise_primitives, 2) 393 << "join[" << this << "]: joint 2/4 already ready"; 394 } 395 if (!ready.is_set(2)) { 396 GRPC_TRACE_VLOG(promise_primitives, 2) 397 << "join[" << this << "]: begin poll joint 3/4"; 398 auto poll = promise2(); 399 GRPC_TRACE_VLOG(promise_primitives, 2) 400 << "join[" << this << "]: end poll joint 3/4 " 401 << (poll.pending() 402 ? "pending" 403 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 404 if (auto* p = poll.value_if_ready()) { 405 if (Traits::IsOk(*p)) { 406 ready.set(2); 407 Destruct(&promise2); 408 Construct(&result2, Traits::Unwrapped(std::move(*p))); 409 } else { 410 return Traits::template EarlyReturn<Result>(std::move(*p)); 411 } 412 } 413 } else { 414 GRPC_TRACE_VLOG(promise_primitives, 2) 415 << "join[" << this << "]: joint 3/4 already ready"; 416 } 417 if (!ready.is_set(3)) { 418 GRPC_TRACE_VLOG(promise_primitives, 2) 419 << "join[" << this << "]: begin poll joint 4/4"; 420 auto poll = promise3(); 421 GRPC_TRACE_VLOG(promise_primitives, 2) 422 << "join[" << this << "]: end poll joint 4/4 " 423 << (poll.pending() 424 ? "pending" 425 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 426 if (auto* p = poll.value_if_ready()) { 427 if (Traits::IsOk(*p)) { 428 ready.set(3); 429 Destruct(&promise3); 430 Construct(&result3, Traits::Unwrapped(std::move(*p))); 431 } else { 432 return Traits::template EarlyReturn<Result>(std::move(*p)); 433 } 434 } 435 } else { 436 GRPC_TRACE_VLOG(promise_primitives, 2) 437 << "join[" << this << "]: joint 4/4 already ready"; 438 } 439 if (ready.all()) { 440 return Traits::FinalReturn(std::move(result0), std::move(result1), 441 std::move(result2), std::move(result3)); 442 } 443 return Pending{}; 444 } 445 }; 446 447 template <class Traits, typename P0, typename P1, typename P2, typename P3, 448 typename P4> 449 struct JoinState<Traits, P0, P1, P2, P3, P4> { 450 template <typename T> 451 using UnwrappedType = decltype(Traits::Unwrapped(std::declval<T>())); 452 using Promise0 = PromiseLike<P0>; 453 using Result0 = UnwrappedType<typename Promise0::Result>; 454 union { 455 GPR_NO_UNIQUE_ADDRESS Promise0 promise0; 456 GPR_NO_UNIQUE_ADDRESS Result0 result0; 457 }; 458 using Promise1 = PromiseLike<P1>; 459 using Result1 = UnwrappedType<typename Promise1::Result>; 460 union { 461 GPR_NO_UNIQUE_ADDRESS Promise1 promise1; 462 GPR_NO_UNIQUE_ADDRESS Result1 result1; 463 }; 464 using Promise2 = PromiseLike<P2>; 465 using Result2 = UnwrappedType<typename Promise2::Result>; 466 union { 467 GPR_NO_UNIQUE_ADDRESS Promise2 promise2; 468 GPR_NO_UNIQUE_ADDRESS Result2 result2; 469 }; 470 using Promise3 = PromiseLike<P3>; 471 using Result3 = UnwrappedType<typename Promise3::Result>; 472 union { 473 GPR_NO_UNIQUE_ADDRESS Promise3 promise3; 474 GPR_NO_UNIQUE_ADDRESS Result3 result3; 475 }; 476 using Promise4 = PromiseLike<P4>; 477 using Result4 = UnwrappedType<typename Promise4::Result>; 478 union { 479 GPR_NO_UNIQUE_ADDRESS Promise4 promise4; 480 GPR_NO_UNIQUE_ADDRESS Result4 result4; 481 }; 482 GPR_NO_UNIQUE_ADDRESS BitSet<5> ready; 483 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(P0&& p0, P1&& p1, P2&& p2, 484 P3&& p3, P4&& p4) { 485 Construct(&promise0, std::forward<P0>(p0)); 486 Construct(&promise1, std::forward<P1>(p1)); 487 Construct(&promise2, std::forward<P2>(p2)); 488 Construct(&promise3, std::forward<P3>(p3)); 489 Construct(&promise4, std::forward<P4>(p4)); 490 } 491 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(const JoinState& other) { 492 DCHECK(other.ready.none()); 493 Construct(&promise0, other.promise0); 494 Construct(&promise1, other.promise1); 495 Construct(&promise2, other.promise2); 496 Construct(&promise3, other.promise3); 497 Construct(&promise4, other.promise4); 498 } 499 JoinState& operator=(const JoinState& other) = delete; 500 JoinState& operator=(JoinState&& other) = delete; 501 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(JoinState&& other) noexcept { 502 DCHECK(other.ready.none()); 503 Construct(&promise0, std::move(other.promise0)); 504 Construct(&promise1, std::move(other.promise1)); 505 Construct(&promise2, std::move(other.promise2)); 506 Construct(&promise3, std::move(other.promise3)); 507 Construct(&promise4, std::move(other.promise4)); 508 } 509 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~JoinState() { 510 if (ready.is_set(0)) { 511 Destruct(&result0); 512 } else { 513 Destruct(&promise0); 514 } 515 if (ready.is_set(1)) { 516 Destruct(&result1); 517 } else { 518 Destruct(&promise1); 519 } 520 if (ready.is_set(2)) { 521 Destruct(&result2); 522 } else { 523 Destruct(&promise2); 524 } 525 if (ready.is_set(3)) { 526 Destruct(&result3); 527 } else { 528 Destruct(&promise3); 529 } 530 if (ready.is_set(4)) { 531 Destruct(&result4); 532 } else { 533 Destruct(&promise4); 534 } 535 } 536 using Result = typename Traits::template ResultType< 537 std::tuple<Result0, Result1, Result2, Result3, Result4>>; 538 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Poll<Result> PollOnce() { 539 if (!ready.is_set(0)) { 540 GRPC_TRACE_VLOG(promise_primitives, 2) 541 << "join[" << this << "]: begin poll joint 1/5"; 542 auto poll = promise0(); 543 GRPC_TRACE_VLOG(promise_primitives, 2) 544 << "join[" << this << "]: end poll joint 1/5 " 545 << (poll.pending() 546 ? "pending" 547 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 548 if (auto* p = poll.value_if_ready()) { 549 if (Traits::IsOk(*p)) { 550 ready.set(0); 551 Destruct(&promise0); 552 Construct(&result0, Traits::Unwrapped(std::move(*p))); 553 } else { 554 return Traits::template EarlyReturn<Result>(std::move(*p)); 555 } 556 } 557 } else { 558 GRPC_TRACE_VLOG(promise_primitives, 2) 559 << "join[" << this << "]: joint 1/5 already ready"; 560 } 561 if (!ready.is_set(1)) { 562 GRPC_TRACE_VLOG(promise_primitives, 2) 563 << "join[" << this << "]: begin poll joint 2/5"; 564 auto poll = promise1(); 565 GRPC_TRACE_VLOG(promise_primitives, 2) 566 << "join[" << this << "]: end poll joint 2/5 " 567 << (poll.pending() 568 ? "pending" 569 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 570 if (auto* p = poll.value_if_ready()) { 571 if (Traits::IsOk(*p)) { 572 ready.set(1); 573 Destruct(&promise1); 574 Construct(&result1, Traits::Unwrapped(std::move(*p))); 575 } else { 576 return Traits::template EarlyReturn<Result>(std::move(*p)); 577 } 578 } 579 } else { 580 GRPC_TRACE_VLOG(promise_primitives, 2) 581 << "join[" << this << "]: joint 2/5 already ready"; 582 } 583 if (!ready.is_set(2)) { 584 GRPC_TRACE_VLOG(promise_primitives, 2) 585 << "join[" << this << "]: begin poll joint 3/5"; 586 auto poll = promise2(); 587 GRPC_TRACE_VLOG(promise_primitives, 2) 588 << "join[" << this << "]: end poll joint 3/5 " 589 << (poll.pending() 590 ? "pending" 591 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 592 if (auto* p = poll.value_if_ready()) { 593 if (Traits::IsOk(*p)) { 594 ready.set(2); 595 Destruct(&promise2); 596 Construct(&result2, Traits::Unwrapped(std::move(*p))); 597 } else { 598 return Traits::template EarlyReturn<Result>(std::move(*p)); 599 } 600 } 601 } else { 602 GRPC_TRACE_VLOG(promise_primitives, 2) 603 << "join[" << this << "]: joint 3/5 already ready"; 604 } 605 if (!ready.is_set(3)) { 606 GRPC_TRACE_VLOG(promise_primitives, 2) 607 << "join[" << this << "]: begin poll joint 4/5"; 608 auto poll = promise3(); 609 GRPC_TRACE_VLOG(promise_primitives, 2) 610 << "join[" << this << "]: end poll joint 4/5 " 611 << (poll.pending() 612 ? "pending" 613 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 614 if (auto* p = poll.value_if_ready()) { 615 if (Traits::IsOk(*p)) { 616 ready.set(3); 617 Destruct(&promise3); 618 Construct(&result3, Traits::Unwrapped(std::move(*p))); 619 } else { 620 return Traits::template EarlyReturn<Result>(std::move(*p)); 621 } 622 } 623 } else { 624 GRPC_TRACE_VLOG(promise_primitives, 2) 625 << "join[" << this << "]: joint 4/5 already ready"; 626 } 627 if (!ready.is_set(4)) { 628 GRPC_TRACE_VLOG(promise_primitives, 2) 629 << "join[" << this << "]: begin poll joint 5/5"; 630 auto poll = promise4(); 631 GRPC_TRACE_VLOG(promise_primitives, 2) 632 << "join[" << this << "]: end poll joint 5/5 " 633 << (poll.pending() 634 ? "pending" 635 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 636 if (auto* p = poll.value_if_ready()) { 637 if (Traits::IsOk(*p)) { 638 ready.set(4); 639 Destruct(&promise4); 640 Construct(&result4, Traits::Unwrapped(std::move(*p))); 641 } else { 642 return Traits::template EarlyReturn<Result>(std::move(*p)); 643 } 644 } 645 } else { 646 GRPC_TRACE_VLOG(promise_primitives, 2) 647 << "join[" << this << "]: joint 5/5 already ready"; 648 } 649 if (ready.all()) { 650 return Traits::FinalReturn(std::move(result0), std::move(result1), 651 std::move(result2), std::move(result3), 652 std::move(result4)); 653 } 654 return Pending{}; 655 } 656 }; 657 658 template <class Traits, typename P0, typename P1, typename P2, typename P3, 659 typename P4, typename P5> 660 struct JoinState<Traits, P0, P1, P2, P3, P4, P5> { 661 template <typename T> 662 using UnwrappedType = decltype(Traits::Unwrapped(std::declval<T>())); 663 using Promise0 = PromiseLike<P0>; 664 using Result0 = UnwrappedType<typename Promise0::Result>; 665 union { 666 GPR_NO_UNIQUE_ADDRESS Promise0 promise0; 667 GPR_NO_UNIQUE_ADDRESS Result0 result0; 668 }; 669 using Promise1 = PromiseLike<P1>; 670 using Result1 = UnwrappedType<typename Promise1::Result>; 671 union { 672 GPR_NO_UNIQUE_ADDRESS Promise1 promise1; 673 GPR_NO_UNIQUE_ADDRESS Result1 result1; 674 }; 675 using Promise2 = PromiseLike<P2>; 676 using Result2 = UnwrappedType<typename Promise2::Result>; 677 union { 678 GPR_NO_UNIQUE_ADDRESS Promise2 promise2; 679 GPR_NO_UNIQUE_ADDRESS Result2 result2; 680 }; 681 using Promise3 = PromiseLike<P3>; 682 using Result3 = UnwrappedType<typename Promise3::Result>; 683 union { 684 GPR_NO_UNIQUE_ADDRESS Promise3 promise3; 685 GPR_NO_UNIQUE_ADDRESS Result3 result3; 686 }; 687 using Promise4 = PromiseLike<P4>; 688 using Result4 = UnwrappedType<typename Promise4::Result>; 689 union { 690 GPR_NO_UNIQUE_ADDRESS Promise4 promise4; 691 GPR_NO_UNIQUE_ADDRESS Result4 result4; 692 }; 693 using Promise5 = PromiseLike<P5>; 694 using Result5 = UnwrappedType<typename Promise5::Result>; 695 union { 696 GPR_NO_UNIQUE_ADDRESS Promise5 promise5; 697 GPR_NO_UNIQUE_ADDRESS Result5 result5; 698 }; 699 GPR_NO_UNIQUE_ADDRESS BitSet<6> ready; 700 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(P0&& p0, P1&& p1, P2&& p2, 701 P3&& p3, P4&& p4, P5&& p5) { 702 Construct(&promise0, std::forward<P0>(p0)); 703 Construct(&promise1, std::forward<P1>(p1)); 704 Construct(&promise2, std::forward<P2>(p2)); 705 Construct(&promise3, std::forward<P3>(p3)); 706 Construct(&promise4, std::forward<P4>(p4)); 707 Construct(&promise5, std::forward<P5>(p5)); 708 } 709 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(const JoinState& other) { 710 DCHECK(other.ready.none()); 711 Construct(&promise0, other.promise0); 712 Construct(&promise1, other.promise1); 713 Construct(&promise2, other.promise2); 714 Construct(&promise3, other.promise3); 715 Construct(&promise4, other.promise4); 716 Construct(&promise5, other.promise5); 717 } 718 JoinState& operator=(const JoinState& other) = delete; 719 JoinState& operator=(JoinState&& other) = delete; 720 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(JoinState&& other) noexcept { 721 DCHECK(other.ready.none()); 722 Construct(&promise0, std::move(other.promise0)); 723 Construct(&promise1, std::move(other.promise1)); 724 Construct(&promise2, std::move(other.promise2)); 725 Construct(&promise3, std::move(other.promise3)); 726 Construct(&promise4, std::move(other.promise4)); 727 Construct(&promise5, std::move(other.promise5)); 728 } 729 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~JoinState() { 730 if (ready.is_set(0)) { 731 Destruct(&result0); 732 } else { 733 Destruct(&promise0); 734 } 735 if (ready.is_set(1)) { 736 Destruct(&result1); 737 } else { 738 Destruct(&promise1); 739 } 740 if (ready.is_set(2)) { 741 Destruct(&result2); 742 } else { 743 Destruct(&promise2); 744 } 745 if (ready.is_set(3)) { 746 Destruct(&result3); 747 } else { 748 Destruct(&promise3); 749 } 750 if (ready.is_set(4)) { 751 Destruct(&result4); 752 } else { 753 Destruct(&promise4); 754 } 755 if (ready.is_set(5)) { 756 Destruct(&result5); 757 } else { 758 Destruct(&promise5); 759 } 760 } 761 using Result = typename Traits::template ResultType< 762 std::tuple<Result0, Result1, Result2, Result3, Result4, Result5>>; 763 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Poll<Result> PollOnce() { 764 if (!ready.is_set(0)) { 765 GRPC_TRACE_VLOG(promise_primitives, 2) 766 << "join[" << this << "]: begin poll joint 1/6"; 767 auto poll = promise0(); 768 GRPC_TRACE_VLOG(promise_primitives, 2) 769 << "join[" << this << "]: end poll joint 1/6 " 770 << (poll.pending() 771 ? "pending" 772 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 773 if (auto* p = poll.value_if_ready()) { 774 if (Traits::IsOk(*p)) { 775 ready.set(0); 776 Destruct(&promise0); 777 Construct(&result0, Traits::Unwrapped(std::move(*p))); 778 } else { 779 return Traits::template EarlyReturn<Result>(std::move(*p)); 780 } 781 } 782 } else { 783 GRPC_TRACE_VLOG(promise_primitives, 2) 784 << "join[" << this << "]: joint 1/6 already ready"; 785 } 786 if (!ready.is_set(1)) { 787 GRPC_TRACE_VLOG(promise_primitives, 2) 788 << "join[" << this << "]: begin poll joint 2/6"; 789 auto poll = promise1(); 790 GRPC_TRACE_VLOG(promise_primitives, 2) 791 << "join[" << this << "]: end poll joint 2/6 " 792 << (poll.pending() 793 ? "pending" 794 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 795 if (auto* p = poll.value_if_ready()) { 796 if (Traits::IsOk(*p)) { 797 ready.set(1); 798 Destruct(&promise1); 799 Construct(&result1, Traits::Unwrapped(std::move(*p))); 800 } else { 801 return Traits::template EarlyReturn<Result>(std::move(*p)); 802 } 803 } 804 } else { 805 GRPC_TRACE_VLOG(promise_primitives, 2) 806 << "join[" << this << "]: joint 2/6 already ready"; 807 } 808 if (!ready.is_set(2)) { 809 GRPC_TRACE_VLOG(promise_primitives, 2) 810 << "join[" << this << "]: begin poll joint 3/6"; 811 auto poll = promise2(); 812 GRPC_TRACE_VLOG(promise_primitives, 2) 813 << "join[" << this << "]: end poll joint 3/6 " 814 << (poll.pending() 815 ? "pending" 816 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 817 if (auto* p = poll.value_if_ready()) { 818 if (Traits::IsOk(*p)) { 819 ready.set(2); 820 Destruct(&promise2); 821 Construct(&result2, Traits::Unwrapped(std::move(*p))); 822 } else { 823 return Traits::template EarlyReturn<Result>(std::move(*p)); 824 } 825 } 826 } else { 827 GRPC_TRACE_VLOG(promise_primitives, 2) 828 << "join[" << this << "]: joint 3/6 already ready"; 829 } 830 if (!ready.is_set(3)) { 831 GRPC_TRACE_VLOG(promise_primitives, 2) 832 << "join[" << this << "]: begin poll joint 4/6"; 833 auto poll = promise3(); 834 GRPC_TRACE_VLOG(promise_primitives, 2) 835 << "join[" << this << "]: end poll joint 4/6 " 836 << (poll.pending() 837 ? "pending" 838 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 839 if (auto* p = poll.value_if_ready()) { 840 if (Traits::IsOk(*p)) { 841 ready.set(3); 842 Destruct(&promise3); 843 Construct(&result3, Traits::Unwrapped(std::move(*p))); 844 } else { 845 return Traits::template EarlyReturn<Result>(std::move(*p)); 846 } 847 } 848 } else { 849 GRPC_TRACE_VLOG(promise_primitives, 2) 850 << "join[" << this << "]: joint 4/6 already ready"; 851 } 852 if (!ready.is_set(4)) { 853 GRPC_TRACE_VLOG(promise_primitives, 2) 854 << "join[" << this << "]: begin poll joint 5/6"; 855 auto poll = promise4(); 856 GRPC_TRACE_VLOG(promise_primitives, 2) 857 << "join[" << this << "]: end poll joint 5/6 " 858 << (poll.pending() 859 ? "pending" 860 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 861 if (auto* p = poll.value_if_ready()) { 862 if (Traits::IsOk(*p)) { 863 ready.set(4); 864 Destruct(&promise4); 865 Construct(&result4, Traits::Unwrapped(std::move(*p))); 866 } else { 867 return Traits::template EarlyReturn<Result>(std::move(*p)); 868 } 869 } 870 } else { 871 GRPC_TRACE_VLOG(promise_primitives, 2) 872 << "join[" << this << "]: joint 5/6 already ready"; 873 } 874 if (!ready.is_set(5)) { 875 GRPC_TRACE_VLOG(promise_primitives, 2) 876 << "join[" << this << "]: begin poll joint 6/6"; 877 auto poll = promise5(); 878 GRPC_TRACE_VLOG(promise_primitives, 2) 879 << "join[" << this << "]: end poll joint 6/6 " 880 << (poll.pending() 881 ? "pending" 882 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 883 if (auto* p = poll.value_if_ready()) { 884 if (Traits::IsOk(*p)) { 885 ready.set(5); 886 Destruct(&promise5); 887 Construct(&result5, Traits::Unwrapped(std::move(*p))); 888 } else { 889 return Traits::template EarlyReturn<Result>(std::move(*p)); 890 } 891 } 892 } else { 893 GRPC_TRACE_VLOG(promise_primitives, 2) 894 << "join[" << this << "]: joint 6/6 already ready"; 895 } 896 if (ready.all()) { 897 return Traits::FinalReturn(std::move(result0), std::move(result1), 898 std::move(result2), std::move(result3), 899 std::move(result4), std::move(result5)); 900 } 901 return Pending{}; 902 } 903 }; 904 905 template <class Traits, typename P0, typename P1, typename P2, typename P3, 906 typename P4, typename P5, typename P6> 907 struct JoinState<Traits, P0, P1, P2, P3, P4, P5, P6> { 908 template <typename T> 909 using UnwrappedType = decltype(Traits::Unwrapped(std::declval<T>())); 910 using Promise0 = PromiseLike<P0>; 911 using Result0 = UnwrappedType<typename Promise0::Result>; 912 union { 913 GPR_NO_UNIQUE_ADDRESS Promise0 promise0; 914 GPR_NO_UNIQUE_ADDRESS Result0 result0; 915 }; 916 using Promise1 = PromiseLike<P1>; 917 using Result1 = UnwrappedType<typename Promise1::Result>; 918 union { 919 GPR_NO_UNIQUE_ADDRESS Promise1 promise1; 920 GPR_NO_UNIQUE_ADDRESS Result1 result1; 921 }; 922 using Promise2 = PromiseLike<P2>; 923 using Result2 = UnwrappedType<typename Promise2::Result>; 924 union { 925 GPR_NO_UNIQUE_ADDRESS Promise2 promise2; 926 GPR_NO_UNIQUE_ADDRESS Result2 result2; 927 }; 928 using Promise3 = PromiseLike<P3>; 929 using Result3 = UnwrappedType<typename Promise3::Result>; 930 union { 931 GPR_NO_UNIQUE_ADDRESS Promise3 promise3; 932 GPR_NO_UNIQUE_ADDRESS Result3 result3; 933 }; 934 using Promise4 = PromiseLike<P4>; 935 using Result4 = UnwrappedType<typename Promise4::Result>; 936 union { 937 GPR_NO_UNIQUE_ADDRESS Promise4 promise4; 938 GPR_NO_UNIQUE_ADDRESS Result4 result4; 939 }; 940 using Promise5 = PromiseLike<P5>; 941 using Result5 = UnwrappedType<typename Promise5::Result>; 942 union { 943 GPR_NO_UNIQUE_ADDRESS Promise5 promise5; 944 GPR_NO_UNIQUE_ADDRESS Result5 result5; 945 }; 946 using Promise6 = PromiseLike<P6>; 947 using Result6 = UnwrappedType<typename Promise6::Result>; 948 union { 949 GPR_NO_UNIQUE_ADDRESS Promise6 promise6; 950 GPR_NO_UNIQUE_ADDRESS Result6 result6; 951 }; 952 GPR_NO_UNIQUE_ADDRESS BitSet<7> ready; 953 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(P0&& p0, P1&& p1, P2&& p2, 954 P3&& p3, P4&& p4, P5&& p5, 955 P6&& p6) { 956 Construct(&promise0, std::forward<P0>(p0)); 957 Construct(&promise1, std::forward<P1>(p1)); 958 Construct(&promise2, std::forward<P2>(p2)); 959 Construct(&promise3, std::forward<P3>(p3)); 960 Construct(&promise4, std::forward<P4>(p4)); 961 Construct(&promise5, std::forward<P5>(p5)); 962 Construct(&promise6, std::forward<P6>(p6)); 963 } 964 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(const JoinState& other) { 965 DCHECK(other.ready.none()); 966 Construct(&promise0, other.promise0); 967 Construct(&promise1, other.promise1); 968 Construct(&promise2, other.promise2); 969 Construct(&promise3, other.promise3); 970 Construct(&promise4, other.promise4); 971 Construct(&promise5, other.promise5); 972 Construct(&promise6, other.promise6); 973 } 974 JoinState& operator=(const JoinState& other) = delete; 975 JoinState& operator=(JoinState&& other) = delete; 976 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(JoinState&& other) noexcept { 977 DCHECK(other.ready.none()); 978 Construct(&promise0, std::move(other.promise0)); 979 Construct(&promise1, std::move(other.promise1)); 980 Construct(&promise2, std::move(other.promise2)); 981 Construct(&promise3, std::move(other.promise3)); 982 Construct(&promise4, std::move(other.promise4)); 983 Construct(&promise5, std::move(other.promise5)); 984 Construct(&promise6, std::move(other.promise6)); 985 } 986 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~JoinState() { 987 if (ready.is_set(0)) { 988 Destruct(&result0); 989 } else { 990 Destruct(&promise0); 991 } 992 if (ready.is_set(1)) { 993 Destruct(&result1); 994 } else { 995 Destruct(&promise1); 996 } 997 if (ready.is_set(2)) { 998 Destruct(&result2); 999 } else { 1000 Destruct(&promise2); 1001 } 1002 if (ready.is_set(3)) { 1003 Destruct(&result3); 1004 } else { 1005 Destruct(&promise3); 1006 } 1007 if (ready.is_set(4)) { 1008 Destruct(&result4); 1009 } else { 1010 Destruct(&promise4); 1011 } 1012 if (ready.is_set(5)) { 1013 Destruct(&result5); 1014 } else { 1015 Destruct(&promise5); 1016 } 1017 if (ready.is_set(6)) { 1018 Destruct(&result6); 1019 } else { 1020 Destruct(&promise6); 1021 } 1022 } 1023 using Result = typename Traits::template ResultType<std::tuple< 1024 Result0, Result1, Result2, Result3, Result4, Result5, Result6>>; 1025 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Poll<Result> PollOnce() { 1026 if (!ready.is_set(0)) { 1027 GRPC_TRACE_VLOG(promise_primitives, 2) 1028 << "join[" << this << "]: begin poll joint 1/7"; 1029 auto poll = promise0(); 1030 GRPC_TRACE_VLOG(promise_primitives, 2) 1031 << "join[" << this << "]: end poll joint 1/7 " 1032 << (poll.pending() 1033 ? "pending" 1034 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1035 if (auto* p = poll.value_if_ready()) { 1036 if (Traits::IsOk(*p)) { 1037 ready.set(0); 1038 Destruct(&promise0); 1039 Construct(&result0, Traits::Unwrapped(std::move(*p))); 1040 } else { 1041 return Traits::template EarlyReturn<Result>(std::move(*p)); 1042 } 1043 } 1044 } else { 1045 GRPC_TRACE_VLOG(promise_primitives, 2) 1046 << "join[" << this << "]: joint 1/7 already ready"; 1047 } 1048 if (!ready.is_set(1)) { 1049 GRPC_TRACE_VLOG(promise_primitives, 2) 1050 << "join[" << this << "]: begin poll joint 2/7"; 1051 auto poll = promise1(); 1052 GRPC_TRACE_VLOG(promise_primitives, 2) 1053 << "join[" << this << "]: end poll joint 2/7 " 1054 << (poll.pending() 1055 ? "pending" 1056 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1057 if (auto* p = poll.value_if_ready()) { 1058 if (Traits::IsOk(*p)) { 1059 ready.set(1); 1060 Destruct(&promise1); 1061 Construct(&result1, Traits::Unwrapped(std::move(*p))); 1062 } else { 1063 return Traits::template EarlyReturn<Result>(std::move(*p)); 1064 } 1065 } 1066 } else { 1067 GRPC_TRACE_VLOG(promise_primitives, 2) 1068 << "join[" << this << "]: joint 2/7 already ready"; 1069 } 1070 if (!ready.is_set(2)) { 1071 GRPC_TRACE_VLOG(promise_primitives, 2) 1072 << "join[" << this << "]: begin poll joint 3/7"; 1073 auto poll = promise2(); 1074 GRPC_TRACE_VLOG(promise_primitives, 2) 1075 << "join[" << this << "]: end poll joint 3/7 " 1076 << (poll.pending() 1077 ? "pending" 1078 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1079 if (auto* p = poll.value_if_ready()) { 1080 if (Traits::IsOk(*p)) { 1081 ready.set(2); 1082 Destruct(&promise2); 1083 Construct(&result2, Traits::Unwrapped(std::move(*p))); 1084 } else { 1085 return Traits::template EarlyReturn<Result>(std::move(*p)); 1086 } 1087 } 1088 } else { 1089 GRPC_TRACE_VLOG(promise_primitives, 2) 1090 << "join[" << this << "]: joint 3/7 already ready"; 1091 } 1092 if (!ready.is_set(3)) { 1093 GRPC_TRACE_VLOG(promise_primitives, 2) 1094 << "join[" << this << "]: begin poll joint 4/7"; 1095 auto poll = promise3(); 1096 GRPC_TRACE_VLOG(promise_primitives, 2) 1097 << "join[" << this << "]: end poll joint 4/7 " 1098 << (poll.pending() 1099 ? "pending" 1100 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1101 if (auto* p = poll.value_if_ready()) { 1102 if (Traits::IsOk(*p)) { 1103 ready.set(3); 1104 Destruct(&promise3); 1105 Construct(&result3, Traits::Unwrapped(std::move(*p))); 1106 } else { 1107 return Traits::template EarlyReturn<Result>(std::move(*p)); 1108 } 1109 } 1110 } else { 1111 GRPC_TRACE_VLOG(promise_primitives, 2) 1112 << "join[" << this << "]: joint 4/7 already ready"; 1113 } 1114 if (!ready.is_set(4)) { 1115 GRPC_TRACE_VLOG(promise_primitives, 2) 1116 << "join[" << this << "]: begin poll joint 5/7"; 1117 auto poll = promise4(); 1118 GRPC_TRACE_VLOG(promise_primitives, 2) 1119 << "join[" << this << "]: end poll joint 5/7 " 1120 << (poll.pending() 1121 ? "pending" 1122 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1123 if (auto* p = poll.value_if_ready()) { 1124 if (Traits::IsOk(*p)) { 1125 ready.set(4); 1126 Destruct(&promise4); 1127 Construct(&result4, Traits::Unwrapped(std::move(*p))); 1128 } else { 1129 return Traits::template EarlyReturn<Result>(std::move(*p)); 1130 } 1131 } 1132 } else { 1133 GRPC_TRACE_VLOG(promise_primitives, 2) 1134 << "join[" << this << "]: joint 5/7 already ready"; 1135 } 1136 if (!ready.is_set(5)) { 1137 GRPC_TRACE_VLOG(promise_primitives, 2) 1138 << "join[" << this << "]: begin poll joint 6/7"; 1139 auto poll = promise5(); 1140 GRPC_TRACE_VLOG(promise_primitives, 2) 1141 << "join[" << this << "]: end poll joint 6/7 " 1142 << (poll.pending() 1143 ? "pending" 1144 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1145 if (auto* p = poll.value_if_ready()) { 1146 if (Traits::IsOk(*p)) { 1147 ready.set(5); 1148 Destruct(&promise5); 1149 Construct(&result5, Traits::Unwrapped(std::move(*p))); 1150 } else { 1151 return Traits::template EarlyReturn<Result>(std::move(*p)); 1152 } 1153 } 1154 } else { 1155 GRPC_TRACE_VLOG(promise_primitives, 2) 1156 << "join[" << this << "]: joint 6/7 already ready"; 1157 } 1158 if (!ready.is_set(6)) { 1159 GRPC_TRACE_VLOG(promise_primitives, 2) 1160 << "join[" << this << "]: begin poll joint 7/7"; 1161 auto poll = promise6(); 1162 GRPC_TRACE_VLOG(promise_primitives, 2) 1163 << "join[" << this << "]: end poll joint 7/7 " 1164 << (poll.pending() 1165 ? "pending" 1166 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1167 if (auto* p = poll.value_if_ready()) { 1168 if (Traits::IsOk(*p)) { 1169 ready.set(6); 1170 Destruct(&promise6); 1171 Construct(&result6, Traits::Unwrapped(std::move(*p))); 1172 } else { 1173 return Traits::template EarlyReturn<Result>(std::move(*p)); 1174 } 1175 } 1176 } else { 1177 GRPC_TRACE_VLOG(promise_primitives, 2) 1178 << "join[" << this << "]: joint 7/7 already ready"; 1179 } 1180 if (ready.all()) { 1181 return Traits::FinalReturn(std::move(result0), std::move(result1), 1182 std::move(result2), std::move(result3), 1183 std::move(result4), std::move(result5), 1184 std::move(result6)); 1185 } 1186 return Pending{}; 1187 } 1188 }; 1189 1190 template <class Traits, typename P0, typename P1, typename P2, typename P3, 1191 typename P4, typename P5, typename P6, typename P7> 1192 struct JoinState<Traits, P0, P1, P2, P3, P4, P5, P6, P7> { 1193 template <typename T> 1194 using UnwrappedType = decltype(Traits::Unwrapped(std::declval<T>())); 1195 using Promise0 = PromiseLike<P0>; 1196 using Result0 = UnwrappedType<typename Promise0::Result>; 1197 union { 1198 GPR_NO_UNIQUE_ADDRESS Promise0 promise0; 1199 GPR_NO_UNIQUE_ADDRESS Result0 result0; 1200 }; 1201 using Promise1 = PromiseLike<P1>; 1202 using Result1 = UnwrappedType<typename Promise1::Result>; 1203 union { 1204 GPR_NO_UNIQUE_ADDRESS Promise1 promise1; 1205 GPR_NO_UNIQUE_ADDRESS Result1 result1; 1206 }; 1207 using Promise2 = PromiseLike<P2>; 1208 using Result2 = UnwrappedType<typename Promise2::Result>; 1209 union { 1210 GPR_NO_UNIQUE_ADDRESS Promise2 promise2; 1211 GPR_NO_UNIQUE_ADDRESS Result2 result2; 1212 }; 1213 using Promise3 = PromiseLike<P3>; 1214 using Result3 = UnwrappedType<typename Promise3::Result>; 1215 union { 1216 GPR_NO_UNIQUE_ADDRESS Promise3 promise3; 1217 GPR_NO_UNIQUE_ADDRESS Result3 result3; 1218 }; 1219 using Promise4 = PromiseLike<P4>; 1220 using Result4 = UnwrappedType<typename Promise4::Result>; 1221 union { 1222 GPR_NO_UNIQUE_ADDRESS Promise4 promise4; 1223 GPR_NO_UNIQUE_ADDRESS Result4 result4; 1224 }; 1225 using Promise5 = PromiseLike<P5>; 1226 using Result5 = UnwrappedType<typename Promise5::Result>; 1227 union { 1228 GPR_NO_UNIQUE_ADDRESS Promise5 promise5; 1229 GPR_NO_UNIQUE_ADDRESS Result5 result5; 1230 }; 1231 using Promise6 = PromiseLike<P6>; 1232 using Result6 = UnwrappedType<typename Promise6::Result>; 1233 union { 1234 GPR_NO_UNIQUE_ADDRESS Promise6 promise6; 1235 GPR_NO_UNIQUE_ADDRESS Result6 result6; 1236 }; 1237 using Promise7 = PromiseLike<P7>; 1238 using Result7 = UnwrappedType<typename Promise7::Result>; 1239 union { 1240 GPR_NO_UNIQUE_ADDRESS Promise7 promise7; 1241 GPR_NO_UNIQUE_ADDRESS Result7 result7; 1242 }; 1243 GPR_NO_UNIQUE_ADDRESS BitSet<8> ready; 1244 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(P0&& p0, P1&& p1, P2&& p2, 1245 P3&& p3, P4&& p4, P5&& p5, 1246 P6&& p6, P7&& p7) { 1247 Construct(&promise0, std::forward<P0>(p0)); 1248 Construct(&promise1, std::forward<P1>(p1)); 1249 Construct(&promise2, std::forward<P2>(p2)); 1250 Construct(&promise3, std::forward<P3>(p3)); 1251 Construct(&promise4, std::forward<P4>(p4)); 1252 Construct(&promise5, std::forward<P5>(p5)); 1253 Construct(&promise6, std::forward<P6>(p6)); 1254 Construct(&promise7, std::forward<P7>(p7)); 1255 } 1256 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(const JoinState& other) { 1257 DCHECK(other.ready.none()); 1258 Construct(&promise0, other.promise0); 1259 Construct(&promise1, other.promise1); 1260 Construct(&promise2, other.promise2); 1261 Construct(&promise3, other.promise3); 1262 Construct(&promise4, other.promise4); 1263 Construct(&promise5, other.promise5); 1264 Construct(&promise6, other.promise6); 1265 Construct(&promise7, other.promise7); 1266 } 1267 JoinState& operator=(const JoinState& other) = delete; 1268 JoinState& operator=(JoinState&& other) = delete; 1269 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(JoinState&& other) noexcept { 1270 DCHECK(other.ready.none()); 1271 Construct(&promise0, std::move(other.promise0)); 1272 Construct(&promise1, std::move(other.promise1)); 1273 Construct(&promise2, std::move(other.promise2)); 1274 Construct(&promise3, std::move(other.promise3)); 1275 Construct(&promise4, std::move(other.promise4)); 1276 Construct(&promise5, std::move(other.promise5)); 1277 Construct(&promise6, std::move(other.promise6)); 1278 Construct(&promise7, std::move(other.promise7)); 1279 } 1280 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~JoinState() { 1281 if (ready.is_set(0)) { 1282 Destruct(&result0); 1283 } else { 1284 Destruct(&promise0); 1285 } 1286 if (ready.is_set(1)) { 1287 Destruct(&result1); 1288 } else { 1289 Destruct(&promise1); 1290 } 1291 if (ready.is_set(2)) { 1292 Destruct(&result2); 1293 } else { 1294 Destruct(&promise2); 1295 } 1296 if (ready.is_set(3)) { 1297 Destruct(&result3); 1298 } else { 1299 Destruct(&promise3); 1300 } 1301 if (ready.is_set(4)) { 1302 Destruct(&result4); 1303 } else { 1304 Destruct(&promise4); 1305 } 1306 if (ready.is_set(5)) { 1307 Destruct(&result5); 1308 } else { 1309 Destruct(&promise5); 1310 } 1311 if (ready.is_set(6)) { 1312 Destruct(&result6); 1313 } else { 1314 Destruct(&promise6); 1315 } 1316 if (ready.is_set(7)) { 1317 Destruct(&result7); 1318 } else { 1319 Destruct(&promise7); 1320 } 1321 } 1322 using Result = typename Traits::template ResultType<std::tuple< 1323 Result0, Result1, Result2, Result3, Result4, Result5, Result6, Result7>>; 1324 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Poll<Result> PollOnce() { 1325 if (!ready.is_set(0)) { 1326 GRPC_TRACE_VLOG(promise_primitives, 2) 1327 << "join[" << this << "]: begin poll joint 1/8"; 1328 auto poll = promise0(); 1329 GRPC_TRACE_VLOG(promise_primitives, 2) 1330 << "join[" << this << "]: end poll joint 1/8 " 1331 << (poll.pending() 1332 ? "pending" 1333 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1334 if (auto* p = poll.value_if_ready()) { 1335 if (Traits::IsOk(*p)) { 1336 ready.set(0); 1337 Destruct(&promise0); 1338 Construct(&result0, Traits::Unwrapped(std::move(*p))); 1339 } else { 1340 return Traits::template EarlyReturn<Result>(std::move(*p)); 1341 } 1342 } 1343 } else { 1344 GRPC_TRACE_VLOG(promise_primitives, 2) 1345 << "join[" << this << "]: joint 1/8 already ready"; 1346 } 1347 if (!ready.is_set(1)) { 1348 GRPC_TRACE_VLOG(promise_primitives, 2) 1349 << "join[" << this << "]: begin poll joint 2/8"; 1350 auto poll = promise1(); 1351 GRPC_TRACE_VLOG(promise_primitives, 2) 1352 << "join[" << this << "]: end poll joint 2/8 " 1353 << (poll.pending() 1354 ? "pending" 1355 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1356 if (auto* p = poll.value_if_ready()) { 1357 if (Traits::IsOk(*p)) { 1358 ready.set(1); 1359 Destruct(&promise1); 1360 Construct(&result1, Traits::Unwrapped(std::move(*p))); 1361 } else { 1362 return Traits::template EarlyReturn<Result>(std::move(*p)); 1363 } 1364 } 1365 } else { 1366 GRPC_TRACE_VLOG(promise_primitives, 2) 1367 << "join[" << this << "]: joint 2/8 already ready"; 1368 } 1369 if (!ready.is_set(2)) { 1370 GRPC_TRACE_VLOG(promise_primitives, 2) 1371 << "join[" << this << "]: begin poll joint 3/8"; 1372 auto poll = promise2(); 1373 GRPC_TRACE_VLOG(promise_primitives, 2) 1374 << "join[" << this << "]: end poll joint 3/8 " 1375 << (poll.pending() 1376 ? "pending" 1377 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1378 if (auto* p = poll.value_if_ready()) { 1379 if (Traits::IsOk(*p)) { 1380 ready.set(2); 1381 Destruct(&promise2); 1382 Construct(&result2, Traits::Unwrapped(std::move(*p))); 1383 } else { 1384 return Traits::template EarlyReturn<Result>(std::move(*p)); 1385 } 1386 } 1387 } else { 1388 GRPC_TRACE_VLOG(promise_primitives, 2) 1389 << "join[" << this << "]: joint 3/8 already ready"; 1390 } 1391 if (!ready.is_set(3)) { 1392 GRPC_TRACE_VLOG(promise_primitives, 2) 1393 << "join[" << this << "]: begin poll joint 4/8"; 1394 auto poll = promise3(); 1395 GRPC_TRACE_VLOG(promise_primitives, 2) 1396 << "join[" << this << "]: end poll joint 4/8 " 1397 << (poll.pending() 1398 ? "pending" 1399 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1400 if (auto* p = poll.value_if_ready()) { 1401 if (Traits::IsOk(*p)) { 1402 ready.set(3); 1403 Destruct(&promise3); 1404 Construct(&result3, Traits::Unwrapped(std::move(*p))); 1405 } else { 1406 return Traits::template EarlyReturn<Result>(std::move(*p)); 1407 } 1408 } 1409 } else { 1410 GRPC_TRACE_VLOG(promise_primitives, 2) 1411 << "join[" << this << "]: joint 4/8 already ready"; 1412 } 1413 if (!ready.is_set(4)) { 1414 GRPC_TRACE_VLOG(promise_primitives, 2) 1415 << "join[" << this << "]: begin poll joint 5/8"; 1416 auto poll = promise4(); 1417 GRPC_TRACE_VLOG(promise_primitives, 2) 1418 << "join[" << this << "]: end poll joint 5/8 " 1419 << (poll.pending() 1420 ? "pending" 1421 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1422 if (auto* p = poll.value_if_ready()) { 1423 if (Traits::IsOk(*p)) { 1424 ready.set(4); 1425 Destruct(&promise4); 1426 Construct(&result4, Traits::Unwrapped(std::move(*p))); 1427 } else { 1428 return Traits::template EarlyReturn<Result>(std::move(*p)); 1429 } 1430 } 1431 } else { 1432 GRPC_TRACE_VLOG(promise_primitives, 2) 1433 << "join[" << this << "]: joint 5/8 already ready"; 1434 } 1435 if (!ready.is_set(5)) { 1436 GRPC_TRACE_VLOG(promise_primitives, 2) 1437 << "join[" << this << "]: begin poll joint 6/8"; 1438 auto poll = promise5(); 1439 GRPC_TRACE_VLOG(promise_primitives, 2) 1440 << "join[" << this << "]: end poll joint 6/8 " 1441 << (poll.pending() 1442 ? "pending" 1443 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1444 if (auto* p = poll.value_if_ready()) { 1445 if (Traits::IsOk(*p)) { 1446 ready.set(5); 1447 Destruct(&promise5); 1448 Construct(&result5, Traits::Unwrapped(std::move(*p))); 1449 } else { 1450 return Traits::template EarlyReturn<Result>(std::move(*p)); 1451 } 1452 } 1453 } else { 1454 GRPC_TRACE_VLOG(promise_primitives, 2) 1455 << "join[" << this << "]: joint 6/8 already ready"; 1456 } 1457 if (!ready.is_set(6)) { 1458 GRPC_TRACE_VLOG(promise_primitives, 2) 1459 << "join[" << this << "]: begin poll joint 7/8"; 1460 auto poll = promise6(); 1461 GRPC_TRACE_VLOG(promise_primitives, 2) 1462 << "join[" << this << "]: end poll joint 7/8 " 1463 << (poll.pending() 1464 ? "pending" 1465 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1466 if (auto* p = poll.value_if_ready()) { 1467 if (Traits::IsOk(*p)) { 1468 ready.set(6); 1469 Destruct(&promise6); 1470 Construct(&result6, Traits::Unwrapped(std::move(*p))); 1471 } else { 1472 return Traits::template EarlyReturn<Result>(std::move(*p)); 1473 } 1474 } 1475 } else { 1476 GRPC_TRACE_VLOG(promise_primitives, 2) 1477 << "join[" << this << "]: joint 7/8 already ready"; 1478 } 1479 if (!ready.is_set(7)) { 1480 GRPC_TRACE_VLOG(promise_primitives, 2) 1481 << "join[" << this << "]: begin poll joint 8/8"; 1482 auto poll = promise7(); 1483 GRPC_TRACE_VLOG(promise_primitives, 2) 1484 << "join[" << this << "]: end poll joint 8/8 " 1485 << (poll.pending() 1486 ? "pending" 1487 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1488 if (auto* p = poll.value_if_ready()) { 1489 if (Traits::IsOk(*p)) { 1490 ready.set(7); 1491 Destruct(&promise7); 1492 Construct(&result7, Traits::Unwrapped(std::move(*p))); 1493 } else { 1494 return Traits::template EarlyReturn<Result>(std::move(*p)); 1495 } 1496 } 1497 } else { 1498 GRPC_TRACE_VLOG(promise_primitives, 2) 1499 << "join[" << this << "]: joint 8/8 already ready"; 1500 } 1501 if (ready.all()) { 1502 return Traits::FinalReturn(std::move(result0), std::move(result1), 1503 std::move(result2), std::move(result3), 1504 std::move(result4), std::move(result5), 1505 std::move(result6), std::move(result7)); 1506 } 1507 return Pending{}; 1508 } 1509 }; 1510 1511 template <class Traits, typename P0, typename P1, typename P2, typename P3, 1512 typename P4, typename P5, typename P6, typename P7, typename P8> 1513 struct JoinState<Traits, P0, P1, P2, P3, P4, P5, P6, P7, P8> { 1514 template <typename T> 1515 using UnwrappedType = decltype(Traits::Unwrapped(std::declval<T>())); 1516 using Promise0 = PromiseLike<P0>; 1517 using Result0 = UnwrappedType<typename Promise0::Result>; 1518 union { 1519 GPR_NO_UNIQUE_ADDRESS Promise0 promise0; 1520 GPR_NO_UNIQUE_ADDRESS Result0 result0; 1521 }; 1522 using Promise1 = PromiseLike<P1>; 1523 using Result1 = UnwrappedType<typename Promise1::Result>; 1524 union { 1525 GPR_NO_UNIQUE_ADDRESS Promise1 promise1; 1526 GPR_NO_UNIQUE_ADDRESS Result1 result1; 1527 }; 1528 using Promise2 = PromiseLike<P2>; 1529 using Result2 = UnwrappedType<typename Promise2::Result>; 1530 union { 1531 GPR_NO_UNIQUE_ADDRESS Promise2 promise2; 1532 GPR_NO_UNIQUE_ADDRESS Result2 result2; 1533 }; 1534 using Promise3 = PromiseLike<P3>; 1535 using Result3 = UnwrappedType<typename Promise3::Result>; 1536 union { 1537 GPR_NO_UNIQUE_ADDRESS Promise3 promise3; 1538 GPR_NO_UNIQUE_ADDRESS Result3 result3; 1539 }; 1540 using Promise4 = PromiseLike<P4>; 1541 using Result4 = UnwrappedType<typename Promise4::Result>; 1542 union { 1543 GPR_NO_UNIQUE_ADDRESS Promise4 promise4; 1544 GPR_NO_UNIQUE_ADDRESS Result4 result4; 1545 }; 1546 using Promise5 = PromiseLike<P5>; 1547 using Result5 = UnwrappedType<typename Promise5::Result>; 1548 union { 1549 GPR_NO_UNIQUE_ADDRESS Promise5 promise5; 1550 GPR_NO_UNIQUE_ADDRESS Result5 result5; 1551 }; 1552 using Promise6 = PromiseLike<P6>; 1553 using Result6 = UnwrappedType<typename Promise6::Result>; 1554 union { 1555 GPR_NO_UNIQUE_ADDRESS Promise6 promise6; 1556 GPR_NO_UNIQUE_ADDRESS Result6 result6; 1557 }; 1558 using Promise7 = PromiseLike<P7>; 1559 using Result7 = UnwrappedType<typename Promise7::Result>; 1560 union { 1561 GPR_NO_UNIQUE_ADDRESS Promise7 promise7; 1562 GPR_NO_UNIQUE_ADDRESS Result7 result7; 1563 }; 1564 using Promise8 = PromiseLike<P8>; 1565 using Result8 = UnwrappedType<typename Promise8::Result>; 1566 union { 1567 GPR_NO_UNIQUE_ADDRESS Promise8 promise8; 1568 GPR_NO_UNIQUE_ADDRESS Result8 result8; 1569 }; 1570 GPR_NO_UNIQUE_ADDRESS BitSet<9> ready; 1571 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(P0&& p0, P1&& p1, P2&& p2, 1572 P3&& p3, P4&& p4, P5&& p5, 1573 P6&& p6, P7&& p7, P8&& p8) { 1574 Construct(&promise0, std::forward<P0>(p0)); 1575 Construct(&promise1, std::forward<P1>(p1)); 1576 Construct(&promise2, std::forward<P2>(p2)); 1577 Construct(&promise3, std::forward<P3>(p3)); 1578 Construct(&promise4, std::forward<P4>(p4)); 1579 Construct(&promise5, std::forward<P5>(p5)); 1580 Construct(&promise6, std::forward<P6>(p6)); 1581 Construct(&promise7, std::forward<P7>(p7)); 1582 Construct(&promise8, std::forward<P8>(p8)); 1583 } 1584 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(const JoinState& other) { 1585 DCHECK(other.ready.none()); 1586 Construct(&promise0, other.promise0); 1587 Construct(&promise1, other.promise1); 1588 Construct(&promise2, other.promise2); 1589 Construct(&promise3, other.promise3); 1590 Construct(&promise4, other.promise4); 1591 Construct(&promise5, other.promise5); 1592 Construct(&promise6, other.promise6); 1593 Construct(&promise7, other.promise7); 1594 Construct(&promise8, other.promise8); 1595 } 1596 JoinState& operator=(const JoinState& other) = delete; 1597 JoinState& operator=(JoinState&& other) = delete; 1598 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION JoinState(JoinState&& other) noexcept { 1599 DCHECK(other.ready.none()); 1600 Construct(&promise0, std::move(other.promise0)); 1601 Construct(&promise1, std::move(other.promise1)); 1602 Construct(&promise2, std::move(other.promise2)); 1603 Construct(&promise3, std::move(other.promise3)); 1604 Construct(&promise4, std::move(other.promise4)); 1605 Construct(&promise5, std::move(other.promise5)); 1606 Construct(&promise6, std::move(other.promise6)); 1607 Construct(&promise7, std::move(other.promise7)); 1608 Construct(&promise8, std::move(other.promise8)); 1609 } 1610 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~JoinState() { 1611 if (ready.is_set(0)) { 1612 Destruct(&result0); 1613 } else { 1614 Destruct(&promise0); 1615 } 1616 if (ready.is_set(1)) { 1617 Destruct(&result1); 1618 } else { 1619 Destruct(&promise1); 1620 } 1621 if (ready.is_set(2)) { 1622 Destruct(&result2); 1623 } else { 1624 Destruct(&promise2); 1625 } 1626 if (ready.is_set(3)) { 1627 Destruct(&result3); 1628 } else { 1629 Destruct(&promise3); 1630 } 1631 if (ready.is_set(4)) { 1632 Destruct(&result4); 1633 } else { 1634 Destruct(&promise4); 1635 } 1636 if (ready.is_set(5)) { 1637 Destruct(&result5); 1638 } else { 1639 Destruct(&promise5); 1640 } 1641 if (ready.is_set(6)) { 1642 Destruct(&result6); 1643 } else { 1644 Destruct(&promise6); 1645 } 1646 if (ready.is_set(7)) { 1647 Destruct(&result7); 1648 } else { 1649 Destruct(&promise7); 1650 } 1651 if (ready.is_set(8)) { 1652 Destruct(&result8); 1653 } else { 1654 Destruct(&promise8); 1655 } 1656 } 1657 using Result = typename Traits::template ResultType< 1658 std::tuple<Result0, Result1, Result2, Result3, Result4, Result5, Result6, 1659 Result7, Result8>>; 1660 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Poll<Result> PollOnce() { 1661 if (!ready.is_set(0)) { 1662 GRPC_TRACE_VLOG(promise_primitives, 2) 1663 << "join[" << this << "]: begin poll joint 1/9"; 1664 auto poll = promise0(); 1665 GRPC_TRACE_VLOG(promise_primitives, 2) 1666 << "join[" << this << "]: end poll joint 1/9 " 1667 << (poll.pending() 1668 ? "pending" 1669 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1670 if (auto* p = poll.value_if_ready()) { 1671 if (Traits::IsOk(*p)) { 1672 ready.set(0); 1673 Destruct(&promise0); 1674 Construct(&result0, Traits::Unwrapped(std::move(*p))); 1675 } else { 1676 return Traits::template EarlyReturn<Result>(std::move(*p)); 1677 } 1678 } 1679 } else { 1680 GRPC_TRACE_VLOG(promise_primitives, 2) 1681 << "join[" << this << "]: joint 1/9 already ready"; 1682 } 1683 if (!ready.is_set(1)) { 1684 GRPC_TRACE_VLOG(promise_primitives, 2) 1685 << "join[" << this << "]: begin poll joint 2/9"; 1686 auto poll = promise1(); 1687 GRPC_TRACE_VLOG(promise_primitives, 2) 1688 << "join[" << this << "]: end poll joint 2/9 " 1689 << (poll.pending() 1690 ? "pending" 1691 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1692 if (auto* p = poll.value_if_ready()) { 1693 if (Traits::IsOk(*p)) { 1694 ready.set(1); 1695 Destruct(&promise1); 1696 Construct(&result1, Traits::Unwrapped(std::move(*p))); 1697 } else { 1698 return Traits::template EarlyReturn<Result>(std::move(*p)); 1699 } 1700 } 1701 } else { 1702 GRPC_TRACE_VLOG(promise_primitives, 2) 1703 << "join[" << this << "]: joint 2/9 already ready"; 1704 } 1705 if (!ready.is_set(2)) { 1706 GRPC_TRACE_VLOG(promise_primitives, 2) 1707 << "join[" << this << "]: begin poll joint 3/9"; 1708 auto poll = promise2(); 1709 GRPC_TRACE_VLOG(promise_primitives, 2) 1710 << "join[" << this << "]: end poll joint 3/9 " 1711 << (poll.pending() 1712 ? "pending" 1713 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1714 if (auto* p = poll.value_if_ready()) { 1715 if (Traits::IsOk(*p)) { 1716 ready.set(2); 1717 Destruct(&promise2); 1718 Construct(&result2, Traits::Unwrapped(std::move(*p))); 1719 } else { 1720 return Traits::template EarlyReturn<Result>(std::move(*p)); 1721 } 1722 } 1723 } else { 1724 GRPC_TRACE_VLOG(promise_primitives, 2) 1725 << "join[" << this << "]: joint 3/9 already ready"; 1726 } 1727 if (!ready.is_set(3)) { 1728 GRPC_TRACE_VLOG(promise_primitives, 2) 1729 << "join[" << this << "]: begin poll joint 4/9"; 1730 auto poll = promise3(); 1731 GRPC_TRACE_VLOG(promise_primitives, 2) 1732 << "join[" << this << "]: end poll joint 4/9 " 1733 << (poll.pending() 1734 ? "pending" 1735 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1736 if (auto* p = poll.value_if_ready()) { 1737 if (Traits::IsOk(*p)) { 1738 ready.set(3); 1739 Destruct(&promise3); 1740 Construct(&result3, Traits::Unwrapped(std::move(*p))); 1741 } else { 1742 return Traits::template EarlyReturn<Result>(std::move(*p)); 1743 } 1744 } 1745 } else { 1746 GRPC_TRACE_VLOG(promise_primitives, 2) 1747 << "join[" << this << "]: joint 4/9 already ready"; 1748 } 1749 if (!ready.is_set(4)) { 1750 GRPC_TRACE_VLOG(promise_primitives, 2) 1751 << "join[" << this << "]: begin poll joint 5/9"; 1752 auto poll = promise4(); 1753 GRPC_TRACE_VLOG(promise_primitives, 2) 1754 << "join[" << this << "]: end poll joint 5/9 " 1755 << (poll.pending() 1756 ? "pending" 1757 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1758 if (auto* p = poll.value_if_ready()) { 1759 if (Traits::IsOk(*p)) { 1760 ready.set(4); 1761 Destruct(&promise4); 1762 Construct(&result4, Traits::Unwrapped(std::move(*p))); 1763 } else { 1764 return Traits::template EarlyReturn<Result>(std::move(*p)); 1765 } 1766 } 1767 } else { 1768 GRPC_TRACE_VLOG(promise_primitives, 2) 1769 << "join[" << this << "]: joint 5/9 already ready"; 1770 } 1771 if (!ready.is_set(5)) { 1772 GRPC_TRACE_VLOG(promise_primitives, 2) 1773 << "join[" << this << "]: begin poll joint 6/9"; 1774 auto poll = promise5(); 1775 GRPC_TRACE_VLOG(promise_primitives, 2) 1776 << "join[" << this << "]: end poll joint 6/9 " 1777 << (poll.pending() 1778 ? "pending" 1779 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1780 if (auto* p = poll.value_if_ready()) { 1781 if (Traits::IsOk(*p)) { 1782 ready.set(5); 1783 Destruct(&promise5); 1784 Construct(&result5, Traits::Unwrapped(std::move(*p))); 1785 } else { 1786 return Traits::template EarlyReturn<Result>(std::move(*p)); 1787 } 1788 } 1789 } else { 1790 GRPC_TRACE_VLOG(promise_primitives, 2) 1791 << "join[" << this << "]: joint 6/9 already ready"; 1792 } 1793 if (!ready.is_set(6)) { 1794 GRPC_TRACE_VLOG(promise_primitives, 2) 1795 << "join[" << this << "]: begin poll joint 7/9"; 1796 auto poll = promise6(); 1797 GRPC_TRACE_VLOG(promise_primitives, 2) 1798 << "join[" << this << "]: end poll joint 7/9 " 1799 << (poll.pending() 1800 ? "pending" 1801 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1802 if (auto* p = poll.value_if_ready()) { 1803 if (Traits::IsOk(*p)) { 1804 ready.set(6); 1805 Destruct(&promise6); 1806 Construct(&result6, Traits::Unwrapped(std::move(*p))); 1807 } else { 1808 return Traits::template EarlyReturn<Result>(std::move(*p)); 1809 } 1810 } 1811 } else { 1812 GRPC_TRACE_VLOG(promise_primitives, 2) 1813 << "join[" << this << "]: joint 7/9 already ready"; 1814 } 1815 if (!ready.is_set(7)) { 1816 GRPC_TRACE_VLOG(promise_primitives, 2) 1817 << "join[" << this << "]: begin poll joint 8/9"; 1818 auto poll = promise7(); 1819 GRPC_TRACE_VLOG(promise_primitives, 2) 1820 << "join[" << this << "]: end poll joint 8/9 " 1821 << (poll.pending() 1822 ? "pending" 1823 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1824 if (auto* p = poll.value_if_ready()) { 1825 if (Traits::IsOk(*p)) { 1826 ready.set(7); 1827 Destruct(&promise7); 1828 Construct(&result7, Traits::Unwrapped(std::move(*p))); 1829 } else { 1830 return Traits::template EarlyReturn<Result>(std::move(*p)); 1831 } 1832 } 1833 } else { 1834 GRPC_TRACE_VLOG(promise_primitives, 2) 1835 << "join[" << this << "]: joint 8/9 already ready"; 1836 } 1837 if (!ready.is_set(8)) { 1838 GRPC_TRACE_VLOG(promise_primitives, 2) 1839 << "join[" << this << "]: begin poll joint 9/9"; 1840 auto poll = promise8(); 1841 GRPC_TRACE_VLOG(promise_primitives, 2) 1842 << "join[" << this << "]: end poll joint 9/9 " 1843 << (poll.pending() 1844 ? "pending" 1845 : (Traits::IsOk(poll.value()) ? "ready" : "early-error")); 1846 if (auto* p = poll.value_if_ready()) { 1847 if (Traits::IsOk(*p)) { 1848 ready.set(8); 1849 Destruct(&promise8); 1850 Construct(&result8, Traits::Unwrapped(std::move(*p))); 1851 } else { 1852 return Traits::template EarlyReturn<Result>(std::move(*p)); 1853 } 1854 } 1855 } else { 1856 GRPC_TRACE_VLOG(promise_primitives, 2) 1857 << "join[" << this << "]: joint 9/9 already ready"; 1858 } 1859 if (ready.all()) { 1860 return Traits::FinalReturn( 1861 std::move(result0), std::move(result1), std::move(result2), 1862 std::move(result3), std::move(result4), std::move(result5), 1863 std::move(result6), std::move(result7), std::move(result8)); 1864 } 1865 return Pending{}; 1866 } 1867 }; 1868 1869 } // namespace promise_detail 1870 } // namespace grpc_core 1871 1872 #endif // GRPC_SRC_CORE_LIB_PROMISE_DETAIL_JOIN_STATE_H 1873