Fix a bug in QuicEventLoop where ArtificiallyNotifyEvent() would sometimes not work

PiperOrigin-RevId: 463574877
diff --git a/quiche/quic/core/io/quic_poll_event_loop.cc b/quiche/quic/core/io/quic_poll_event_loop.cc
index 286dd65..aaf82e7 100644
--- a/quiche/quic/core/io/quic_poll_event_loop.cc
+++ b/quiche/quic/core/io/quic_poll_event_loop.cc
@@ -151,7 +151,7 @@
   int poll_result =
       PollWithRetries(absl::Span<pollfd>(pollfds.get(), registration_count),
                       start_time, timeout);
-  if (poll_result == 0) {
+  if (poll_result == 0 && !has_artificial_events_pending_) {
     return;
   }
 
diff --git a/quiche/quic/tools/quic_server_test.cc b/quiche/quic/tools/quic_server_test.cc
index d193fd3..444d023 100644
--- a/quiche/quic/tools/quic_server_test.cc
+++ b/quiche/quic/tools/quic_server_test.cc
@@ -55,9 +55,10 @@
 
 class TestQuicServer : public QuicServer {
  public:
-  TestQuicServer()
+  explicit TestQuicServer(QuicEventLoopFactory* event_loop_factory)
       : QuicServer(crypto_test_utils::ProofSourceForTesting(),
-                   &quic_simple_server_backend_) {}
+                   &quic_simple_server_backend_),
+        event_loop_factory_(event_loop_factory) {}
 
   ~TestQuicServer() override = default;
 
@@ -74,13 +75,19 @@
     return mock_dispatcher_;
   }
 
+  std::unique_ptr<QuicEventLoop> CreateEventLoop() override {
+    return event_loop_factory_->Create(QuicDefaultClock::Get());
+  }
+
   MockQuicSimpleDispatcher* mock_dispatcher_ = nullptr;
   QuicMemoryCacheBackend quic_simple_server_backend_;
+  QuicEventLoopFactory* event_loop_factory_;
 };
 
-class QuicServerEpollInTest : public QuicTest {
+class QuicServerEpollInTest : public QuicTestWithParam<QuicEventLoopFactory*> {
  public:
-  QuicServerEpollInTest() : server_address_(TestLoopback(), 0) {}
+  QuicServerEpollInTest()
+      : server_address_(TestLoopback(), 0), server_(GetParam()) {}
 
   void StartListening() {
     server_.CreateUDPSocketAndListen(server_address_);
@@ -99,10 +106,19 @@
   TestQuicServer server_;
 };
 
+std::string GetTestParamName(
+    ::testing::TestParamInfo<QuicEventLoopFactory*> info) {
+  return EscapeTestParamName(info.param->GetName());
+}
+
+INSTANTIATE_TEST_SUITE_P(QuicServerEpollInTests, QuicServerEpollInTest,
+                         ::testing::ValuesIn(GetAllSupportedEventLoops()),
+                         GetTestParamName);
+
 // Tests that if dispatcher has CHLOs waiting for connection creation, EPOLLIN
 // event should try to create connections for them. And set epoll mask with
 // EPOLLIN if there are still CHLOs remaining at the end of epoll event.
-TEST_F(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
+TEST_P(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
   // Given an EPOLLIN event, try to create session for buffered CHLOs. In first
   // event, dispatcher can't create session for all of CHLOs. So listener should
   // register another EPOLLIN event by itself. Even without new packet arrival,