You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by cl...@apache.org on 2020/06/18 05:54:00 UTC

[qpid-proton] branch master updated: PROTON-2240: epoll proactor - fix cases where a fired timer is not rearmed as expected

This is an automated email from the ASF dual-hosted git repository.

cliffjansen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git


The following commit(s) were added to refs/heads/master by this push:
     new 4a22a0d  PROTON-2240: epoll proactor - fix cases where a fired timer is not rearmed as expected
4a22a0d is described below

commit 4a22a0dc59016fdf64dc7ed056467a52a699460e
Author: Cliff Jansen <cl...@apache.org>
AuthorDate: Wed Jun 17 22:53:07 2020 -0700

    PROTON-2240: epoll proactor - fix cases where a fired timer is not rearmed as expected
---
 c/src/proactor/epoll.c | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/c/src/proactor/epoll.c b/c/src/proactor/epoll.c
index 20376e4..0f6a606 100644
--- a/c/src/proactor/epoll.c
+++ b/c/src/proactor/epoll.c
@@ -1054,6 +1054,15 @@ static inline bool pconnection_wclosed(pconnection_t  *pc) {
   return pn_connection_driver_write_closed(&pc->driver);
 }
 
+// Call with pc context locked.
+static void pconnection_rearm_timer(pconnection_t *pc) {
+  if (!pc->timer_armed && !pc->timer.shutting_down &&
+      pc->timer.epoll_io.fd >= 0 && pc->timer.epoll_io.polling) {
+    pc->timer_armed = true;
+    rearm(pc->psocket.proactor, &pc->timer.epoll_io);
+  }
+}
+
 /* Call only from working context (no competitor for pc->current_arm or
    connection driver).  If true returned, caller must do
    pconnection_rearm().
@@ -1093,9 +1102,11 @@ static inline void pconnection_rearm(pconnection_t *pc) {
 
 /* Only call when context switch is imminent.  Sched lock is highly contested. */
 // Call with both context and sched locks.
-static bool pconnection_sched_sync(pconnection_t *pc) {
+static bool pconnection_sched_sync(pconnection_t *pc, bool *timerfd_fired) {
+  *timerfd_fired = false;
   if (pc->sched_timeout) {
-    pc->tick_pending = true;
+    *timerfd_fired = true;;
+    pc->timer_armed = false;
     pc->sched_timeout = false;
   }
   if (pc->psocket.sched_io_events) {
@@ -1135,10 +1146,14 @@ static void pconnection_done(pconnection_t *pc) {
                                 // working context while the lock is held.  Need sched_sync too to drain possible stale wake.
   pc->hog_count = 0;
   bool has_event = pconnection_has_event(pc);
+  bool timerfd_fired;
   // Do as little as possible while holding the sched lock
   lock(&p->sched_mutex);
-  pconnection_sched_sync(pc);
+  pconnection_sched_sync(pc, &timerfd_fired);
   unlock(&p->sched_mutex);
+  if (timerfd_fired)
+    if (ptimer_callback(&pc->timer) != 0)
+      pc->tick_pending = true;
 
   if (has_event || pconnection_work_pending(pc)) {
     self_wake = true;
@@ -1159,6 +1174,7 @@ static void pconnection_done(pconnection_t *pc) {
   if (self_wake)
     notify = wake(&pc->context);
 
+  pconnection_rearm_timer(pc);
   bool rearm = pconnection_rearm_check(pc);
   unlock(&pc->context.mutex);
 
@@ -1405,9 +1421,13 @@ static pn_event_batch_t *pconnection_process(pconnection_t *pc, uint32_t events,
   }
 
   // Never stop working while work remains.  hog_count exception to this rule is elsewhere.
+  bool timerfd_fired;
   lock(&pc->context.proactor->sched_mutex);
-  bool workers_free = pconnection_sched_sync(pc);
+  bool workers_free = pconnection_sched_sync(pc, &timerfd_fired);
   unlock(&pc->context.proactor->sched_mutex);
+  if (timerfd_fired)
+    if (ptimer_callback(&pc->timer) != 0)
+      pc->tick_pending = true;
 
   if (pconnection_work_pending(pc)) {
     goto retry;  // TODO: get rid of goto without adding more locking
@@ -1433,10 +1453,7 @@ static pn_event_batch_t *pconnection_process(pconnection_t *pc, uint32_t events,
     goto retry;
   }
 
-  if (!pc->timer_armed && !pc->timer.shutting_down && pc->timer.epoll_io.fd >= 0) {
-    pc->timer_armed = true;
-    rearm(pc->psocket.proactor, &pc->timer.epoll_io);
-  }
+  pconnection_rearm_timer(pc);
   bool rearm_pc = pconnection_rearm_check(pc);  // holds rearm_mutex until pconnection_rearm() below
 
   unlock(&pc->context.mutex);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org