diff --git a/src/ice_transport.cpp b/src/ice_transport.cpp
index d0e9afbd7f6de3752e1358b757c0d884e67de178..80b08360cc79e582b5bc59a83174f089d201bb73 100644
--- a/src/ice_transport.cpp
+++ b/src/ice_transport.cpp
@@ -770,62 +770,56 @@ IceTransportFactory::~IceTransportFactory()
     pj_caching_pool_destroy(&cp_);
 }
 
-int
-IceTransportFactory::processThread()
+static void
+handleIOEvents(pj_ice_strans_cfg& cfg, unsigned max_msec)
 {
-    register_thread();
-    while (!thread_quit_flag_) {
-        handleEvents(500, NULL);
-    }
+    // By tests, never seen more than two events per 500ms
+    static constexpr auto MAX_NET_EVENTS = 2;
 
-    return 0;
-}
-
-int
-IceTransportFactory::handleEvents(unsigned max_msec, unsigned *p_count)
-{
-    enum { MAX_NET_EVENTS = 1 };
     pj_time_val max_timeout = {0, 0};
     pj_time_val timeout = {0, 0};
-    unsigned count = 0, net_event_count = 0;
-    int c;
+    unsigned net_event_count = 0;
 
     max_timeout.msec = max_msec;
 
     timeout.sec = timeout.msec = 0;
-    c = pj_timer_heap_poll(ice_cfg_.stun_cfg.timer_heap, &timeout);
-    if (c > 0)
-        count += c;
-
-    pj_assert(timeout.sec >= 0 && timeout.msec >= 0);
-    if (timeout.msec >= 1000) timeout.msec = 999;
+    pj_timer_heap_poll(cfg.stun_cfg.timer_heap, &timeout);
 
+    // timeout limitation
+    if (timeout.msec >= 1000)
+        timeout.msec = 999;
     if (PJ_TIME_VAL_GT(timeout, max_timeout))
         timeout = max_timeout;
 
     do {
-        c = pj_ioqueue_poll(ice_cfg_.stun_cfg.ioqueue, &timeout);
-        if (c < 0) {
-            pj_status_t err = pj_get_netos_error();
+        auto n_events = pj_ioqueue_poll(cfg.stun_cfg.ioqueue, &timeout);
+
+        // timeout
+        if (not n_events)
+            return;
+
+        // error
+        if (n_events < 0) {
+            RING_ERR("IceIOQueue: error %d", pj_get_netos_error());
             std::this_thread::sleep_for(std::chrono::milliseconds(PJ_TIME_VAL_MSEC(timeout)));
-            if (p_count)
-                *p_count = count;
-            return err;
-        } else if (c == 0) {
-            break;
-        } else {
-            net_event_count += c;
-            timeout.sec = timeout.msec = 0;
+            return;
         }
-    } while (c > 0 && net_event_count < MAX_NET_EVENTS);
-
-    count += net_event_count;
-    if (p_count)
-        *p_count = count;
 
-    return PJ_SUCCESS;
+        net_event_count += n_events;
+        timeout.sec = timeout.msec = 0;
+    } while (net_event_count < MAX_NET_EVENTS);
 }
 
+int
+IceTransportFactory::processThread()
+{
+    register_thread();
+    while (!thread_quit_flag_) {
+        handleIOEvents(ice_cfg_, 500); // limit polling to 500ms
+    }
+
+    return 0;
+}
 
 std::shared_ptr<IceTransport>
 IceTransportFactory::createTransport(const char* name,
diff --git a/src/ice_transport.h b/src/ice_transport.h
index 04ab579456bdda60c7bf9586c6e697d2a579feb2..3be26fecbb4ae4dffa1793aeb152c46d212d32cd 100644
--- a/src/ice_transport.h
+++ b/src/ice_transport.h
@@ -271,8 +271,6 @@ class IceTransportFactory {
         pj_pool_factory* getPoolFactory() { return &cp_.factory; }
 
     private:
-        int handleEvents(unsigned max_msec, unsigned *p_count);
-
         pj_caching_pool cp_;
         std::unique_ptr<pj_pool_t, decltype(pj_pool_release)&> pool_;
         std::thread thread_;