Date: Mon, 25 Sep 2000 13:28:03 -0400 (EDT) From: Bosko Milekic <bmilekic@technokratis.com> To: Alfred Perlstein <bright@wintelcom.net> Cc: arch@FreeBSD.ORG, cp@FreeBSD.ORG Subject: Re: need advice, fsetown annoyances and mpsafeness. Message-ID: <Pine.BSF.4.21.0009251314260.15801-100000@jehovah.technokratis.com> In-Reply-To: <20000924125311.Q9141@fw.wintelcom.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 24 Sep 2000, Alfred Perlstein wrote: > It's really a lot more evil than you think. Yeah, I noticed after sending the Email. > The race is in the object (socket/tty) checking the pointer and > then dereferencing it. > > A broken solution is to lock the sigio struct or provide a backreference > to the socket/tty lock, after banging my head against my desk for some time I came across this solution: This looks somewhat like what you mentionned in (2) in your earlier post. The sigio struct will only be freed by the object. I think this is a reasonable solution. > (assuming pfind/pgfind return the proc/pgrp locked) > [...] > /* > * ok this is somewhat tricky, we examine what the sigio is attached > * to, whatever it is proc/pgrp we need to use the search functions > * to ensure atomicity. If we get back ESRCH that's ok, that means > * we lost the race, just free it. > * if we get back a pointer we then need to make sure that the pgid > * hasn't been NULLed out because we lost the race between looking > * at the sigio and locking the proc/pgrp > * (most likely pid/pgid wraparound) > */ > pid = sigio->sio_pgid; > > if (pid < 0) { > struct pgrp *p; > > if ((pgrp = pgfind(pid)) != NULL) { > /* funsetown_proc would have set this to zero */ > if (sigio->sio_pgid != 0) > SLIST_REMOVE(&sigio->sio_pgrp->pg_sigiolst, sigio, > sigio, sio_pgsigio); > PGRP_UNLOCK(&sigio->sio_pgrp); > } > } else if (pid > 0) { > struct proc *p; > > if ((p = pfind(pid)) != NULL) { > /* funsetown_proc would have set this to zero */ > if (sigio->sio_pgid != 0) > SLIST_REMOVE(&sigio->sio_proc->p_sigiolst, sigio, > sigio, sio_pgsigio); > PROC_UNLOCK(&sigio->sio_proc); > } > } > > out: > crfree(sigio->sio_ucred); > FREE(sigio, M_SIGIO); > } Looks good. > /* > * NULL out a sigio struct attached to a process/pgrp > * must be called with the object (struct proc/pgrp) locked > * this is to be called from the perspective of the process/pgrp > * > * called from the proc/pgid at teardown > * proc/pgid must be locked > */ > void > funsetown_proc(sigio) > struct sigio *sigio; > { > int s; > > if (sigio == NULL) > return; > if (sigio->sio_pgid < 0) { > SLIST_REMOVE(&sigio->sio_pgrp->pg_sigiolst, sigio, > sigio, sio_pgsigio); > } else /* if ((*sigiop)->sio_pgid > 0) */ { > SLIST_REMOVE(&sigio->sio_proc->p_sigiolst, sigio, > sigio, sio_pgsigio); > } > sigio->sio_pgid = 0; > } > > /* > * Free a list of sigio structures. > * > * called from the proc/pgid at teardown > * proc/pgid must be locked > */ > void > funsetownlst(sigiolst) > struct sigiolst *sigiolst; > { > struct sigio *sigio; > > while ((sigio = SLIST_FIRST(sigiolst)) != NULL) > funsetown(sigio); > } > > > Questions? Comments? Question: You don't seem to be protecting the actual sigiolst list with a lock. What happens if you've got two different processes manipulating the list? Each one may be locked, but regardless, your list can still be trashed. > -- > -Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] > "I have the heart of a child; I keep it in a jar on my desk." Regards, Bosko Milekic bmilekic@technokratis.com To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0009251314260.15801-100000>