Date: Mon, 28 Jun 2010 17:05:34 +0300 From: Kostik Belousov <kostikbel@gmail.com> To: John Baldwin <jhb@freebsd.org> Cc: threads@freebsd.org Subject: Re: SIGPIPE and threads Message-ID: <20100628140534.GZ13238@deviant.kiev.zoral.com.ua> In-Reply-To: <201006280833.54224.jhb@freebsd.org> References: <201006280833.54224.jhb@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--jHgdI7OefoZoiA5t Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Jun 28, 2010 at 08:33:54AM -0400, John Baldwin wrote: > Currently when a thread performs a write(2) on a disconnected socket or a= FIFO=20 > with no readers the SIGPIPE signal is posted to the entire process via=20 > psignal(). This means that the signal can be delivered to any thread in = the=20 > process. However, it seems more intuitive to me that SIGPIPE should be s= ent=20 > to the "offending" thread similar to signals sent in response to traps vi= a=20 > trapsignal(). POSIX seems to require this in that the description of the= =20 > EPIPE error return value for write(2) and fflush(3) in the Open Group's o= nline=20 > manpages both say that SIGPIPE should be sent to the current thread in=20 > addition to returning EPIPE: >=20 > http://www.opengroup.org/onlinepubs/000095399/functions/write.html >=20 > http://www.opengroup.org/onlinepubs/000095399/functions/fflush.html >=20 > I have an untested (only compiled) patch below: I think the patch is right, but, as you note, having a dedicated function that wraps automatic ksi initialization and tdsignal() call would be even better. >=20 > Index: kern/uipc_syscalls.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- kern/uipc_syscalls.c (revision 209571) > +++ kern/uipc_syscalls.c (working copy) > @@ -738,6 +738,7 @@ > struct mbuf *control; > enum uio_seg segflg; > { > + struct ksiginfo ksi; > struct file *fp; > struct uio auio; > struct iovec *iov; > @@ -793,8 +794,11 @@ > /* Generation of SIGPIPE can be controlled per socket */ > if (error =3D=3D EPIPE && !(so->so_options & SO_NOSIGPIPE) && > !(flags & MSG_NOSIGNAL)) { > + ksiginfo_init(&ksi); > + ksi.ksi_signo =3D SIGPIPE; > + ksi.ksi_code =3D SI_KERNEL; > PROC_LOCK(td->td_proc); > - psignal(td->td_proc, SIGPIPE); > + tdsignal(td->td_proc, td, SIGPIPE, &ksi); > PROC_UNLOCK(td->td_proc); > } > } > @@ -2379,6 +2383,7 @@ > { > #if (defined(INET) || defined(INET6)) && defined(SCTP) > struct sctp_sndrcvinfo sinfo, *u_sinfo =3D NULL; > + struct ksiginfo ksi; > struct socket *so; > struct file *fp =3D NULL; > int use_rcvinfo =3D 1; > @@ -2443,8 +2448,11 @@ > /* Generation of SIGPIPE can be controlled per socket. */ > if (error =3D=3D EPIPE && !(so->so_options & SO_NOSIGPIPE) && > !(uap->flags & MSG_NOSIGNAL)) { > + ksiginfo_init(&ksi); > + ksi.ksi_signo =3D SIGPIPE; > + ksi.ksi_code =3D SI_KERNEL; > PROC_LOCK(td->td_proc); > - psignal(td->td_proc, SIGPIPE); > + tdsignal(td->td_proc, td, SIGPIPE, &ksi); > PROC_UNLOCK(td->td_proc); > } > } > @@ -2483,6 +2491,7 @@ > { > #if (defined(INET) || defined(INET6)) && defined(SCTP) > struct sctp_sndrcvinfo sinfo, *u_sinfo =3D NULL; > + struct ksiginfo ksi; > struct socket *so; > struct file *fp =3D NULL; > int use_rcvinfo =3D 1; > @@ -2561,8 +2570,11 @@ > /* Generation of SIGPIPE can be controlled per socket */ > if (error =3D=3D EPIPE && !(so->so_options & SO_NOSIGPIPE) && > !(uap->flags & MSG_NOSIGNAL)) { > + ksiginfo_init(&ksi); > + ksi.ksi_signo =3D SIGPIPE; > + ksi.ksi_code =3D SI_KERNEL; > PROC_LOCK(td->td_proc); > - psignal(td->td_proc, SIGPIPE); > + tdsignal(td->td_proc, td, SIGPIPE, &ksi); > PROC_UNLOCK(td->td_proc); > } > } > Index: kern/sys_socket.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- kern/sys_socket.c (revision 209571) > +++ kern/sys_socket.c (working copy) > @@ -92,6 +92,7 @@ > int flags, struct thread *td) > { > struct socket *so =3D fp->f_data; > + struct ksiginfo ksi; > int error; > =20 > #ifdef MAC > @@ -101,8 +102,11 @@ > #endif > error =3D sosend(so, 0, uio, 0, 0, 0, uio->uio_td); > if (error =3D=3D EPIPE && (so->so_options & SO_NOSIGPIPE) =3D=3D 0) { > + ksiginfo_init(&ksi); > + ksi.ksi_signo =3D SIGPIPE; > + ksi.ksi_code =3D SI_KERNEL; > PROC_LOCK(uio->uio_td->td_proc); > - psignal(uio->uio_td->td_proc, SIGPIPE); > + tdsignal(uio->uio_td->td_proc, uio->uio_td, SIGPIPE, &ksi); > PROC_UNLOCK(uio->uio_td->td_proc); > } > return (error); > Index: kern/sys_generic.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- kern/sys_generic.c (revision 209571) > +++ kern/sys_generic.c (working copy) > @@ -509,6 +509,7 @@ > off_t offset; > int flags; > { > + struct ksiginfo ksi; > ssize_t cnt; > int error; > #ifdef KTRACE > @@ -531,8 +532,11 @@ > error =3D 0; > /* Socket layer is responsible for issuing SIGPIPE. */ > if (fp->f_type !=3D DTYPE_SOCKET && error =3D=3D EPIPE) { > + ksiginfo_init(&ksi); > + ksi.ksi_signo =3D SIGPIPE; > + ksi.ksi_code =3D SI_KERNEL; > PROC_LOCK(td->td_proc); > - psignal(td->td_proc, SIGPIPE); > + tdsignal(td->td_proc, td, SIGPIPE, &ksi); > PROC_UNLOCK(td->td_proc); > } > } >=20 > --=20 > John Baldwin --jHgdI7OefoZoiA5t Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkworC0ACgkQC3+MBN1Mb4huTACfX3Wdq2CxgCmwrqNmCbolHudz rdQAnjDBamwK3sbfOy+wcMH/tNo5Bpup =86qS -----END PGP SIGNATURE----- --jHgdI7OefoZoiA5t--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100628140534.GZ13238>