bug-hurd
[Top][All Lists]
Advanced

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

Re: Some questions about libports and notification of ports


From: zhengda
Subject: Re: Some questions about libports and notification of ports
Date: Thu, 21 Aug 2008 11:26:33 +0200
User-agent: Thunderbird 2.0.0.16 (X11/20080707)

Thomas Bushnell BSG wrote:
On Wed, 2008-08-20 at 22:47 +0200, zhengda wrote:
I want to get the confirmation from you about the usage of ports_get_right(), ports_destroy_right() and ports_port_deref(). When I use ports_get_right() to get the receive right of the port, I should always make a send right for the port. So if we just want to get the name of the port, we should use the port_right field in port_info directly. Am I right?

The "normal" call is ports_get_send_right.  You should think of
ports_get_right as simply ports_get_send_right where you are responsible
for a MACH_MSG_TYPE_COPY_SEND invocation to come.  The only reason for
ports_get_right is to avoid the system call inside of
ports_get_send_right in the usual case.

That means that it is *not* a good idea to think of ports_get_right as
returning you the name of the receive right.  Notice that it increments
a reference count!

So the question you are asking then is "how can I get the name of the
receive right for a port if I am using libports?"  And the answer is:

1) Why do you think you need the receive right?
2) Don't.

Such an operation breaks the abstraction of the ports library.  You
should pretty much not be dereferencing *anything* inside a struct
port_info.
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. 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.
I think I have to rewrite this part of code.
ports_destroy_right() is only used to destroy the receive right and it shouldn't be able to destroy the port_info object. ports_port_deref() is the one to destroy the port_info object (of course, only when its reference count is 0), right?

Yes, but note that destroying the receive right is quickly going to
result in the reference count for the port going to zero, and the
consequent destruction of the port_info structure.  But that step will
happen later, when the last no-senders notification comes in.
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().
Another question is about the notification of no senders.
From the mach manual, I see there are two situations where no-senders notification is generated. 1. "If notify is not null, and the receive right’s make-send count is greater than or equal to the sync value, and it has no extant send rights, than an immediate no-senders notification is generated." 2. "Otherwise the notification is generated when the receive right next loses its last extant send right." For the first case, why is the notification generated only when make-send count >= the sync value? Is there any special reason for this?

Yes.  They are thinking of a case where you might want to create a port,
and schedule a no-senders notification, and *then* start creating the
send rights.  The sync value says that no-senders only counts *after*
you've created the send rights you wanted to make.

Notice that ports_get_right works in exactly this way.  If we are making
a send right for the first time, we ask for a notification, and specify
the sync value so that we don't generate an immediate notification.
ah, right.
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.

Zheng Da




reply via email to

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