wait_and_drain treated every read() <= 0 as "queue drained", so a real error (bad fd, EINVAL) silently ended the drain and the monitor kept polling a broken fd. Distinguish the cases: EAGAIN ends the drain, EINTR retries, and any other error propagates. monitor_loop logs the error before exiting so a dead memory monitor is visible in the session log.