/// 接收线程推进 void tcp_session::run() { if (m_notify_connected) { connect_invoke(); m_notify_connected = false; } post_recv(false); post_send(false); std::size_t bytes; while ((bytes = m_recvbuf.gcount()) > 0) { on_recv(m_recvbuf.gptr(), bytes); m_recvbuf.gbump(bytes); } try_shutdown(); if (m_both_closed.is_locked() && m_error) { on_disconnect(m_error); m_error.clear(); m_valid = false; } }
// Invoke timers static void timer_dispatch(void) { struct timespec tru = timer_repeat_until; for (;;) { // Run the next software timer uint32_t next = sched_timer_dispatch(); struct timespec nt = timespec_from_time(next); struct timespec now = timespec_read(); if (!timespec_is_before(nt, timespec_add(now, TIMER_MIN_TRY_NS))) { // Schedule next timer normally. next_wake_time = nt; return; } if (unlikely(timespec_is_before(tru, now))) { // Check if there are too many repeat timers if (unlikely(timespec_is_before(timespec_add(nt, 100000000), now))) try_shutdown("Rescheduled timer in the past"); if (sched_tasks_busy()) { timer_repeat_until = timespec_add(now, TIMER_REPEAT_NS); next_wake_time = timespec_add(now, TIMER_DEFER_REPEAT_NS); return; } timer_repeat_until = timespec_add(now, TIMER_IDLE_REPEAT_NS); } // Next timer in the past or near future - wait for it to be ready while (unlikely(timespec_is_before(now, nt))) now = timespec_read(); } }
uint16_t gpio_adc_read(struct gpio_adc g) { char buf[64]; int ret = pread(g.fd, buf, sizeof(buf)-1, 0); if (ret <= 0) { report_errno("analog read", ret); try_shutdown("Error on analog read"); return 0; } buf[ret] = '\0'; return atoi(buf); }