[comp.os.mach] problem with ports and reference counting

dennisg@kgw2.Xetron.COM (Dennis Glatting) (03/27/91)

We have developed large communications system utilizing the 
NeXT computer.  The NeXTs are used as Base Stations in a 
redundant setup.  Most of the code utilized the Mach IPC
calls such as msg_rpc() rather than NeXT's Speaker/Listener
objects.  That code is written in C with some Objective-C
code composing core objects.

The system has 20 tasks running continuously (13 are unique.  the
copies interface with different devices).  All of these tasks
have ports checked in with the name server.  All are 
multi-threaded.

My question has to do with ports and reference counting.  For
each task there is an interface library.  These routines obtain
the task's port from the name server and perform a transaction.
Since we're multi-threaded, we do perform multiple transactions
with the same task from different threads within another 
task.

I two threads independently look up a tasks name then (I assume)
if one thread deallocates the port then the other thread
will have problems.  For example, in a msg_rpc().  The first
thread is completing a transaction (the other task sent a
reply) but hasn't run yet.  The second thread then looks up the
task's port.  The first thread comes back and deallocates the port.
The second thread now runs and attempts to send a message.  

Therefore, we can't deallocate the port abruptly.  My feeling
is that the task's will reach an equilibrium where multiple
netname_lookup()s won't consume more kernel resources.

Has anyone solved this problem before?  Some sort of reference
counting method?

-- 
 ..!uunet!kgw2!dennisg  | Dennis P. Glatting
 dennisg@Xetron.COM     | X2NeXT developer
                        | NeXT/C++/Objective-C wienie

Richard.Draves@cs.cmu.edu (03/29/91)

> Excerpts from netnews.comp.os.mach: 26-Mar-91 problem with ports and
> refe.. Dennis Glatting@kgw2.Xet (1683)

> My question has to do with ports and reference counting.  For
> each task there is an interface library.  These routines obtain
> the task's port from the name server and perform a transaction.
> Since we're multi-threaded, we do perform multiple transactions
> with the same task from different threads within another 
> task.

> I two threads independently look up a tasks name then (I assume)
> if one thread deallocates the port then the other thread
> will have problems.  For example, in a msg_rpc().  The first
> thread is completing a transaction (the other task sent a
> reply) but hasn't run yet.  The second thread then looks up the
> task's port.  The first thread comes back and deallocates the port.
> The second thread now runs and attempts to send a message.  

> Therefore, we can't deallocate the port abruptly.  My feeling
> is that the task's will reach an equilibrium where multiple
> netname_lookup()s won't consume more kernel resources.

This problem can't be solved satisfactorily in user space.  If one
thread can do a deallocate at the same time another thread is receiving
a message, the receive might happen first and then a port right in the
received message can be inadvertently deallocated.  Mach 2.5 programs
generally don't bother to deallocate ports, or at least not send rights,
so this isn't a problem.  Mach 3.0's IPC interface has reference
counting support to let user tasks overcome these types of races.

Rich