Subject: bug#79201: 30.1.90; set-process-thread can permanently break fd_callback_info slots

From: Eli Zaretskii <[email-masked]>
Date: Fri, 15 Aug 2025 14:52:04 +0300

> From: Spencer Baugh <[email-masked]>
> Cc: [email-masked],  [email-masked],  [email-masked],
>    [email-masked]
> Date: Thu, 14 Aug 2025 12:21:15 -0400
> 
> The cause is that recompute_max_desc runs when a file descriptor is
> deleted, and reduces max_desc.  But when it does so, that means
> clear_waiting_thread_info will not get the chance to clear the
> waiting_thread field in fd_callback_info slots above the new max_desc.

Makes sense, thanks.

> My initial thought was that recompute_max_desc should zero the
> fd_callback_info[fd] entry when it reduces max_desc.  But it turns out
> to be equivalent, and simpler, to zero fd_callback_info[desc] completely
> instead of just setting flags to 0 right before we call
> recompute_max_desc.
> 
> I do this in the attached patch, which fixes the bug.

Thanks, the patch seems OK with a minor comment:

> --- a/src/process.c
> +++ b/src/process.c
> @@ -574,8 +574,7 @@ delete_write_fd (int fd)
>    fd_callback_info[fd].flags &= ~(FOR_WRITE | NON_BLOCKING_CONNECT_FD);
>    if (fd_callback_info[fd].flags == 0)
>      {
> -      fd_callback_info[fd].func = 0;
> -      fd_callback_info[fd].data = 0;
> +      fd_callback_info[fd] = (struct fd_callback_data) {};

Please just clear the .thread and .waiting_thread members.  This way,
the code is easier to read, and it is also easier to find all the
places which assign something to these members.