| 78 | public: |
| 79 | explicit InactivityCop(Ptr<ProxyMutex> &m) : Continuation(m.get()) { SET_HANDLER(&InactivityCop::check_inactivity); } |
| 80 | int |
| 81 | check_inactivity(int event, Event *e) |
| 82 | { |
| 83 | (void)event; |
| 84 | ink_hrtime now = ink_get_hrtime(); |
| 85 | NetHandler &nh = *get_NetHandler(this_ethread()); |
| 86 | |
| 87 | Dbg(dbg_ctl_inactivity_cop_check, "Checking inactivity on Thread-ID #%d", this_ethread()->id); |
| 88 | // The rest NetEvents in cop_list which are not triggered between InactivityCop runs. |
| 89 | // Use pop() to catch any closes caused by callbacks. |
| 90 | while (NetEvent *ne = nh.cop_list.pop()) { |
| 91 | // If we cannot get the lock don't stop just keep cleaning |
| 92 | MUTEX_TRY_LOCK(lock, ne->get_mutex(), this_ethread()); |
| 93 | if (!lock.is_locked()) { |
| 94 | Metrics::Counter::increment(net_rsb.inactivity_cop_lock_acquire_failure); |
| 95 | continue; |
| 96 | } |
| 97 | |
| 98 | if (ne->closed) { |
| 99 | nh.free_netevent(ne); |
| 100 | continue; |
| 101 | } |
| 102 | |
| 103 | if (ne->default_inactivity_timeout_in == -1) { |
| 104 | // If no context-specific default inactivity timeout has been set by an |
| 105 | // override plugin, then use the global default. |
| 106 | Dbg(dbg_ctl_inactivity_cop, |
| 107 | "vc: %p setting the global default inactivity timeout of %d, next_inactivity_timeout_at: %" PRId64, ne, |
| 108 | nh.config.default_inactivity_timeout, ne->next_inactivity_timeout_at); |
| 109 | ne->set_default_inactivity_timeout(HRTIME_SECONDS(nh.config.default_inactivity_timeout)); |
| 110 | } |
| 111 | |
| 112 | // set a default inactivity timeout if one is not set |
| 113 | // The event `EVENT_INACTIVITY_TIMEOUT` only be triggered if a read |
| 114 | // or write I/O operation was set by `do_io_read()` or `do_io_write()`. |
| 115 | if (ne->next_inactivity_timeout_at == 0 && ne->default_inactivity_timeout_in > 0 && (ne->read.enabled || ne->write.enabled)) { |
| 116 | Dbg(dbg_ctl_inactivity_cop, "vc: %p inactivity timeout not set, setting a default of %d", ne, |
| 117 | nh.config.default_inactivity_timeout); |
| 118 | ne->use_default_inactivity_timeout = true; |
| 119 | ne->next_inactivity_timeout_at = ink_get_hrtime() + ne->default_inactivity_timeout_in; |
| 120 | ne->inactivity_timeout_in = 0; |
| 121 | Metrics::Counter::increment(net_rsb.default_inactivity_timeout_applied); |
| 122 | } |
| 123 | |
| 124 | if (ne->next_inactivity_timeout_at && ne->next_inactivity_timeout_at < now) { |
| 125 | if (ne->is_default_inactivity_timeout()) { |
| 126 | // track the connections that timed out due to default inactivity |
| 127 | Dbg(dbg_ctl_inactivity_cop, "vc: %p timed out due to default inactivity timeout", ne); |
| 128 | Metrics::Counter::increment(net_rsb.default_inactivity_timeout_count); |
| 129 | } |
| 130 | if (nh.keep_alive_queue.in(ne)) { |
| 131 | // only stat if the connection is in keep-alive, there can be other inactivity timeouts |
| 132 | ink_hrtime diff = (now - (ne->next_inactivity_timeout_at - ne->inactivity_timeout_in)) / HRTIME_SECOND; |
| 133 | Metrics::Counter::increment(net_rsb.keep_alive_queue_timeout_total, diff); |
| 134 | Metrics::Counter::increment(net_rsb.keep_alive_queue_timeout_count); |
| 135 | } |
| 136 | Dbg(dbg_ctl_inactivity_cop_verbose, "ne: %p now: %" PRId64 " timeout at: %" PRId64 " timeout in: %" PRId64, ne, |
| 137 | ink_hrtime_to_sec(now), ne->next_inactivity_timeout_at, ne->inactivity_timeout_in); |
nothing calls this directly
no test coverage detected