🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.next.programmer
Article #475

Re: signals and the appkit

#475
From: Chris Lloyd
Date: Thu, 06 Aug 1992 23:09
97 lines
3873 bytes
In article <4536@rosie.NeXT.COM> jdoenias@next.com (Josh Doenias) writes:
>In article <Bs4G4M.19M@oceania.com>  writes:
>>We are using sigvec to set a handler to catch SIGCHLD. (wait?(2) is no  
>>good as this application has other tasks to perform.)  Since the handler's  
>>stack is finite, we want to post an event to notify the application and  
>>that there is work to be done and get off the stack.  
>
[ recommendation about avoiding signals and signal handling deleted ]

Agreed.

>In your case, where you're interested in child processes completing, I  
>would recommend the following solution.
>
>1.  Create a DPSTimedEntry function that gets called at some regular  
>interval (using DPSAddTimedEntry)
>2.  In that function, use the wait3() system call.  You said that wait()  
>is no good, since it is blocking, but wait3() can be passed parameters  
>making it non-blocking.
>3.  If the wait3() call tells you a process has finished, send a message  
>to whoever cares.  You can queue the messages up or handle them  
>immediately.

ACK! Polling is Evil with a capital E.

- Give the app's task a notify port.
- setup a handler for the notify port.
- each time you fork a child, request the child's task port, this
    gives you rights to the childs task and you will get a message on
    the task notify port about the death of this port.

death_handler(msg_header_t *msg,id self)
{
/* Stolen from Josh's example .. */
    union wait status;
    int pid = wait3(&status,WNOHANG,NULL);
    
    if (pid > 0) [self processFinished:pid withStatus:&status];
}

For the curious at heart, *msg is:
struct {
  msg_header_t header;
  msg_type_t   type;
  port_t       port;
} *msg;

and port will be the port that was destroyed (in this case, the child's task
port)

Then in the object that starts up the children:

-init
{
   port_t notify;
   kern_return_t r;

   if(r=port_allocate(task_self(),&notify))
    mach_error("port_allocate",r);

   if(r=task_set_notify_port(task_self(),notify))
    mach_error("task_set_notify_port");

   DPSAddPort(notify,death_handler,MSG_SIZE_MAX,self,NX_MODALRESPTHRESHOLD);
}

Then for the trick:

A task is a port, in order to be notified of a ports death, you need to
have rights to it, since a parent process doesnt have rights to the
childs task by default (neh?), you need to do the following right after 
your fork() in order to get the rights, so that a message is sent to you
when the task , er port, right? is destroyed...

  task_t child;

  if((pid=fork())==0)
   { /* do childish things */ }

  task_by_unix_pid(task_self(),pid,&child);

dat's it.

One thing to notice here is that there is this really nasty window
between the time the fork() happens and the time you get the task port of
the child in which the child can die and you dont have rights and you
never get a notification message and the handler is never called.  If this
is a concern, the thing to do would be to fire a bogus message down your
own notify port right after the task_by_unix_pid() so that the handler
is called and the wait status is checked and in effect eliminating the window.

It would be handy to have a fork() variant which returned a task_t for
the child...

la la la,
-- 
:: Christopher Lloyd :: a74k110@titan.ucc.umass.edu :: Yrrid, Inc. ::
Technical Details
Message-ID: <1992Aug6.230949.7527@nic.umass.edu>
Path: arc1-ca.pugleaf.net!sparky!uunet!caen!nic.umass.edu!titan.ucc.umass.edu!a74k110
References: <Bs4G4M.19M@oceania.com> <4536@rosie.NeXT.COM>

Show Full Headers
Complete Article Headers
Newsgroups: comp.sys.next.programmer
Path: arc1-ca.pugleaf.net!sparky!uunet!caen!nic.umass.edu!titan.ucc.umass.edu!a74k110
From: a74k110@titan.ucc.umass.edu (Chris Lloyd)
Subject: Re: signals and the appkit
Message-ID: <1992Aug6.230949.7527@nic.umass.edu>
Sender: usenet@nic.umass.edu (USENET News System)
Nntp-Posting-Host: titan.ucc.umass.edu
Organization: University of Massachusetts, Amherst
References: <Bs4G4M.19M@oceania.com> <4536@rosie.NeXT.COM>
Date: Thu, 6 Aug 1992 23:09:49 GMT
Lines: 97