Re: Rép : Using dead notification with mach ports (Modifié par Stéphane Letz)
Re: Rép : Using dead notification with mach ports (Modifié par Stéphane Letz)
- Subject: Re: Rép : Using dead notification with mach ports (Modifié par Stéphane Letz)
- From: Jim Magee <email@hidden>
- Date: Mon, 13 Sep 2004 12:36:24 -0400
On Sep 13, 2004, at 12:14 PM, Stéphane Letz wrote:
You seem to have an overly complex situation here. You have a
private client->server port, a call-back port, AND a shared
semaphore.
Well after thinking a little more, maybe using only *one* port and the
shared semaphore for each client will be enough....
I mean the idea to have a "private" client->server port was to allow
the server to get a notification related to a specific client and to
cleanly destroy its internal client data structure. But if a call-back
port is needed for server->client communication anyway, *and* if this
port can be checked by the server for dead-name notification then the
"private" client->server port seems not to be needed anymore.
And *all* client->server MIG RPC can use the server global port
(allocated and registered in the global namespace)
Is this possible?
It is certainly possible. But it is trickier (again, all depending on
the protocol you have established between the client and server and
vice-versa). You need to make sure clients don't spoof each other to
the server (if you care about that at all) because of the common queue
between all clients and the server. You have deal with the problem of
"pending messages still in the main queue" from a client at the time
you receive the dead-name notification for that client (how do you know
when you receive them that they are from the dead client and not some
new client whose identifying marks look similar?).
That's a lot of stuff to keep coordinated. I assume that you would
consider having any one of these channels shut down prematurely as a
sign of a failed client/server connection. If so, you have to
request a dead-name notification on the semaphore and the callback
port, and a no-senders notification on the private client->server
port.
But if you are careful with checking error codes (and not allowing
the server to get hung up waiting for a non-responsive/dead client on
the semaphore and callback operations) you could still get away with
just the no-senders notification on the private client->server port.
For the semaphore, I guess "semaphore_signal" called on the server
side will return KERN_TERMINATED error code if the client has shut
down prematurely. Will it be enough?
Should be, as long as the client always allocates the semaphore and not
the server.
For callback ports, I hope that using a timeout will be enough.
Actually, you'll get back a difference error (invalid destination vs.
timeout), but the same recovery logic should work in either case if you
design your server state engine correctly.
Another question : notification will allow the server to know when
clients disappear abnormally. What happens in the contrary case? Can
clients be notified if the server dappear?
Sure. But this is usually trickier unless you own all the clients
yourself. You can use a dead-name notification on the client->server
private port or a no-senders notification on the server->client
callback port. Again, the no-senders approach is usually the
cleanest. Since you are likely to be using a CFRunLoop in the
client, you probably are already creating a CFMachPort in the client
to receive the callbacks from the server. Unfortunately, CFMachPort
doesn't have any built in support for no-senders notifications (like
the invalidation callback for dead-name notifications). Instead,
you'll just have to request the notification manually and then handle
the no-senders notification as part of you normal message callback
handler.
Well I am not using CFMachPort because I wanted to have the server do
RPC on the call-back port. So I actually use the MIG generator to
define RPC to be called by the server. And I use a "manually"
allocated thread to handle the MIG generated message handling routine.
Would using CFRunLoop and CFMachPort be a cleaner approach?
If you can handle it all in your helper thread, and the number of
clients needing this additional thread is small, then there is nothing
wrong with your approach. But it's normally better to not create an
additional threads in the clients if you can avoid it. If the
callbacks cannot be completely handled in the additional thread, how do
these additional threads signal the main thread? In that case, you're
going to have to reflect the callback status over to the main thread
anyway and it might have just been easier (and more efficient) to send
it there directly.
Why is the "no-senders approach" the cleanest in this case?
Because you are already waiting for messages to arrive on the callback
port in each client, no-senders notifications can be sent to those very
same ports, and you are then guaranteed they are the last messages that
are going to come on those ports. You can, for instance, send the
dead-name notifications for the server's global port to that same
callback port. But you can't be sure it will be the last message
there. If you don't target the same port, then you have to add a
second port and a portset to the client-side logic just like the
server's.
--Jim
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden