Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions vlib/picoev/picoev.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module picoev

import net
import os
import pico_http_parser
import time

Expand Down Expand Up @@ -307,6 +308,15 @@ fn default_error_callback(_data voidptr, _req pico_http_parser.Request, mut res

// new creates a `Picoev` struct and initializes the main loop.
pub fn new(config Config) !&Picoev {
// A server must not die on a peer RST: any write to a connection the client
// already reset delivers SIGPIPE, whose default action terminates the process
// SILENTLY (no panic, no crash report). Long-held fds (SSE) make this routine
// rather than rare — a subscriber that disconnects between pushes turns the
// next push into a process kill. Ignore it process-wide once a server event
// loop exists; write()/send() then report EPIPE and the caller drops the fd.
$if !windows {
os.signal_ignore(.pipe)
}
listening_socket_fd := listen(config) or {
elog('Error during listen: ${err}')
return err
Expand Down
10 changes: 10 additions & 0 deletions vlib/picoev/socket_util.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ fn setup_sock(fd int) ! {
if C.setsockopt(fd, C.IPPROTO_TCP, C.TCP_NODELAY, &flag, sizeof(int)) < 0 {
return error('setup_sock.setup_sock failed')
}
$if freebsd || macos {
// Accepted sockets do not inherit SO_NOSIGPIPE from the listener on the
// BSDs; without it a write() after a peer RST raises SIGPIPE instead of
// returning EPIPE. Belt to the process-wide signal_ignore braces in new()
// — either alone suffices, together they survive callers that re-arm
// SIGPIPE handlers.
if C.setsockopt(fd, C.SOL_SOCKET, C.SO_NOSIGPIPE, &flag, sizeof(int)) < 0 {
return error('setup_sock: SO_NOSIGPIPE failed')
}
}
$if freebsd {
if C.fcntl(fd, C.F_SETFL, C.SOCK_NONBLOCK) != 0 {
return error('fcntl failed')
Expand Down
Loading