[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Some questions about libports and notification of ports

From: Thomas Bushnell BSG
Subject: Re: Some questions about libports and notification of ports
Date: Thu, 21 Aug 2008 07:26:53 -0700

On Thu, 2008-08-21 at 11:26 +0200, zhengda wrote:
> In eth-filter, I define a structure
> struct proxy_info
> {
>   /* For receiving packets from pfinet. */
>   struct port_info *pfinet_pi;
>   hurd_ihash_locp_t p_pfinetpi_hashloc;
>   /* For receiving packets from the network interface. */
>   struct port_info *device_pi;
>   hurd_ihash_locp_t p_devicepi_hashloc;
>   /* For delivering packet to pfinet. */
>   mach_port_t deliver_port;
>   hurd_ihash_locp_t p_deliverport_hashloc;
>   /* The port to the network interface. */
>   mach_port_t device_port;
> };
> Because I cannot put two port_info objects in one structure, I put their 
> pointers in the structure.

Ah, there's the mistake.  First, "struct proxy" is fine; no need for
"info".  You have a situation very much like a pipe, except that you are
doing network packet stuff on each port instead of read/write on each

So take a look at what pflocal does for a hint.

You want something like

struct proxy_user
  struct port_info pi;
  struct proxy *px;

struct proxy
  int refs;
  struct mutex lock;

  a queue;
  other stuff maybe;

> The result is that I cannot find the proxy_info structure with 
> ports_lookup_port(). I define some hash tables for it and do exactly as 
> what ports_lookup_port() does. That's why I need to get the name of the 
> port.

Here you are totally violating the abstraction of libports.  Instead,
you want a single structure for each outstanding port--just like
libports wants--and then that structure points to the common structure
for what they share.

The whole point of libports is to *eliminate* the need for that.  Simply
turn your pointers around and have them point the other way (as I sketch
above) and your life will be much easier.

> ports_destroy_right decrease the reference count for the port only when 
> the port has the send right (PORT_HAS_SENDRIGHTS flag). When the port 
> gets the send right, its reference count is always increased by 1. so as 
> long as the functions in libports are used correctly, 
> ports_destroy_right() cannot destroy the port_info structure.
> As I understand, in order to destroy a port created by 
> ports_create_port(), we have to call ports_destroy_right() and 
> ports_port_deref().

Notice that Hurd servers basically never think "oh, I want to destroy a
port."  That's a very unusual thing.  You don't keep track of that; this
is exactly what libports is for.

Your interpretation of ports_destroy_right is wrong.  It does always
destroy the port, completely.

The mach_port_mod_refs is what destroys the port.  Note that *all* the
outstanding send rights, however many there may be, occupy only *one*
reference in PI->refcnt.  So when we do a ports_destroy_right, first we
blow away the receive right, which causes the kernel to nuke all the
outstanding send rights and turn them into MACH_PORT_NULL.  Then we
account for their loss by doing a ports_port_deref, if there were any
send rights.  (Notice that the no-senders notification we have
outstanding is going to be cancelled when we nuke the receive right.)

The only reason that ports_port_deref might not immediately eliminate
the port is because there are likely *other* references to the port,
perhaps in some other thread.  We can't actually free the structure
until they are done with it.  But trule, ports_destroy_right does blow
the whole thing away.

> >> For the second case, if notify is null, how can we receive the 
> >> notification? The same question for the dead-name notification (the 
> >> argument notify is also allowed to be null).
> >>     
> >
> > You can't.  The result is that you are cancelling the notification if
> > one is outstanding.
> >   
> The mach manual doesn't tell that:(, or I understand it in a wrong way.

What was your understanding of it?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]