Tcl Source Code

View Ticket
Login
Ticket UUID: 7aa8fd34c4e8ed00e73e06aef189fae1b092d1c4
Title: epoll notifier spins and never reports writable after EPOLLERR
Type: Bug Created on: 2026-10-16 21:46:10
Submitter: serhiy.storchaka Assigned to: jan.nijtmans
Subsystem: 01. Notifier Severity: Minor
Priority: 5 Medium Last modified: 2026-10-30 09:40:46
Status: Closed Closed by: jan.nijtmans
Resolution: Fixed Closed on: 2026-10-30 09:40:46
Version: 9.0.5, 9.1.0
Description:

On Linux (epoll notifier, 8.7 and later), a writable handler on a pipe whose reader has exited never fires: EPOLLERR is translated only to TCL_EXCEPTION, and the level-triggered event wakes epoll_wait() again at once, so the process spins at 100% CPU. A background flush to such a pipe never ends, and [close] reports no error although the data was lost.

set f [open |[list [info nameofexecutable] exit.tcl] w]   ;# child exits at once
fconfigure $f -blocking 0
puts -nonewline $f [string repeat x 300000]
catch {flush $f}
chan event $f writable {set w writable}
after 3000 {set w timeout}
vwait w   ;# 8.6: writable at once, close gives "broken pipe"; 9.x: timeout, close gives no error

select() reports such a descriptor as writable. The code is from [858569fb04].

User Comments:
serhiy.storchaka added on 2026-10-16 21:49:57:

Proposed fix in branch epoll-error-writable: report EPOLLERR as readable and writable, like select() does. Test io-78.1.


jan.nijtmans added on 2026-10-30 09:40:46:

Fixed in [6d788a0eb3|trunk], and core-9-0-branch

Many thanks!