Re: Acquiring an NSConnection otherwise than by registered name?
Re: Acquiring an NSConnection otherwise than by registered name?
- Subject: Re: Acquiring an NSConnection otherwise than by registered name?
- From: Ken Thomases <email@hidden>
- Date: Tue, 28 Sep 2010 03:11:37 -0500
On Sep 28, 2010, at 2:29 AM, Oleg Krupnov wrote:
> Thanks Ken,
You're welcome. I'm glad to help.
> 1. What happens when I call -connectionForProxy on the client proxy
> object? Is a new connection created? Or the root vended object's
> connection can be reused? In the latter case if I remove that
> connection from the main run loop and call -runInNewThread, would the
> root object's operation be broken?
The server creates one NSConnection instance and registers it under a name. This connection doesn't actually send data to any client. It listens for connections from clients and, when one connects, creates a new NSConnection instance to conduct the communication with that client. The new NSConnection is a child of the original one. (If you've ever worked with BSD sockets, this should be familiar. The server creates one socket file descriptor with the socket() call, calls bind() and listen() on it, and then accept()s new file descriptors as connections are made.)
The -connectionForProxy method returns the existing connection being used to convey messages to the proxy to its distant "real" object. This will be different from the NSConnection object the server originally created and registered. It will be one of the child connections.
> 2. I tried to launch two client threads simultaneously and pass
> different objects to the check-in method, and I see that the
> connection returned from -connectionForProxy is the same for the both
> threads. Is it a problem? Won't the two threads somehow interfere?
I believe you are being bitten by what I wrote about here:
> On Tue, Sep 28, 2010 at 9:12 AM, Ken Thomases <email@hidden> wrote:
>
>> For a multi-threaded client which wants to have several connections to the same server, you may have to jump through a couple of hoops. NSConnection is pretty eager about reusing its instances if they match a new request. You may need to create the connection somewhat manually by creating the ports and then explicitly using +connectionWithReceivePort:sendPort: or -initWithReceivePort:sendPort:.
Two threads within one process may very well get the same connection to the server. The simple methods for getting the connection (or ignoring the connection and just getting the root proxy) just ask by name. NSConnection will realize it already has a connection for that name and reuse it. So, you probably shouldn't use:
+connectionWithRegisteredName:host:
+connectionWithRegisteredName:host:usingNameServer:
+rootProxyForConnectionWithRegisteredName:host:
+rootProxyForConnectionWithRegisteredName:host:usingNameServer:
Instead, you should create two ports of the appropriate type. If you're using Mach ports for communication, then you want NSMachPorts. If you're using sockets for communication, then NSSocketPorts.
You should get the send port from the appropriate port name server. For example, [[NSMachBootstrapServer sharedInstance] portForName:@"foo"] or [[NSSocketPortNameServer sharedInstance] portForName:@"foo" host:@"server.example.com"]. This send port is still likely to be shared by the threads.
So, you should create a separate receive port for each thread. That's the part which ensures that each thread has a separate NSConnection (both on the client side and the server side). For example [NSMachPort port] or [NSSocketPort port].
Then, you should create the connection to the server from those two ports, using one of:
+connectionWithReceivePort:sendPort:
-initWithReceivePort:sendPort:
Read the documentation for the latter of those to learn about NSConnection object re-use/sharing. Those docs suggest you may be able to get away without creating a unique receive port manually. If you pass nil, it should create one for you. Test to make sure the connection objects your client threads are getting are unique from one another.
Then call -rootProxy on the created connection object to get the server's vended object.
Cheers,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden