From owner-freebsd-hackers Tue Jul 9 14:47:20 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id OAA10336 for hackers-outgoing; Tue, 9 Jul 1996 14:47:20 -0700 (PDT) Received: from phaeton.artisoft.com (phaeton.Artisoft.COM [198.17.250.211]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id OAA10329 for ; Tue, 9 Jul 1996 14:47:16 -0700 (PDT) Received: (from terry@localhost) by phaeton.artisoft.com (8.6.11/8.6.9) id OAA25120; Tue, 9 Jul 1996 14:42:22 -0700 From: Terry Lambert Message-Id: <199607092142.OAA25120@phaeton.artisoft.com> Subject: Re: handling SIGCHLD with multiple children To: brandon@tombstone.sunrem.com (Brandon Gillespie) Date: Tue, 9 Jul 1996 14:42:22 -0700 (MST) Cc: freebsd-hackers@FreeBSD.org In-Reply-To: from "Brandon Gillespie" at Jul 9, 96 12:26:35 pm X-Mailer: ELM [version 2.4 PL24] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-hackers@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk > Is there _ANY_ way of finding what child sent a SIGCHLD signal to the > parent process? I have a situation where a parent may have multiple > children processing different tasks, and the parent is waiting for one > child to complete a specific task, which it cares about, but it does not > care about the other children. Because of this in most instances when > SIGCHLD is received it simply resets it and continues working, except for > now I need to handle things differently when a specific child sends > SIGCHLD. Is there any ANY way to figure out where it came from? Signals are persistent conditions, not events. A signal handler will block deliver of on signal behind. It is therefore not a good idea to call wait in the SIGCHLD handler itself, since it introduces apotential race condition in disposing the signal. The correct method would be to program in terms of an event loop; I don't know the architecture of the parent process, but if it is an event loop, then you can do the following: 1) Establish a SIGCHLD signal handler; if a SIGCHLD signal is received, then a volatile variable should be set to indicate one or more children need to be reaped. 2) Arrange the main loop as follows: a) check the volatile flag; dispatch to inband handler function if set b) set SIGCHLD to interrupt system calls c) call the main loop hang-pending-event call (usually select or other system call) d) on handler return, reset interrupt on SIGCHLD do only the hang is interruptable. d) check hang-pending-event return value for interrupt e) if interrupted, go to top of main loop 3) Create an inband handler function for SIGCHLD; this function will: a) call wait(2) with WNOHANG option b) on -1, processing is complete (no more PID's to return) c) use the return value to hash-index a list of child processes that are outstanding (return value is PID). d) set a flag (does not need to be volatile) to indicate that anyone waiting for this process to complete may now proceed. This approach was used successfully in a "X port monitor" to allow management of logins on up to 32 terminals (highest tested amount; highest theoretical amount was 256 becase of FD_SETSIZE) using a single process (instead of running one xdm per X terminal -- a huge memory waster on a Sun machine). This approach was also successfully used for a pipe-based linkage system, similar to that employed by Khoros, to similar effect for a tools-based image processing "drag-and-drop" workbench. Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers.