9 Replies
      Latest reply on Apr 13, 2020 4:12 AM by galad87
      ManuelCSolis Level 1 Level 1 (0 points)

        My application handles multiple connections through the USB ports as serial devices that use termios, the application needs to send and receive a large amount of data for each open connection, but in very rare cases the process that handles the data received through a specific USB port crashes, collapsing the application and affecting the other open connections. To minimize the damage, I intend to use NSXPCConnection instances. My question to this forum is: How many similar instances of NSXPCConnection can be opened for the same application?

        • Re: NSXPCConnection multiple instances.
          eskimo Apple Staff Apple Staff (13,905 points)

          How many similar instances of NSXPCConnection can be opened for the same application?

          That depends on what you mean by “similar”.  Looking at your big picture goal I suspect that you’re trying to use an XPC Service to run your serial connections, as discussed in the Creating XPC Services section of the Daemons and Services Programming Guide.  Is that right?

          If so, be aware that the public XPC Service mechanism does not support multiple instances.  That is, if an app has XPC Services nested within the app, an instance of that app can only instantiate a single instance of each of those services.  So, for example, if you have an XPC Service that runs a serial connection, you must either:

          • Restrict yourself to one serial connection

          • Run multiple serial connections in the same service

          Clearly both of these are suboptimal.  Specifically, the second option means that, while your app is isolated from a crash in your service, a crash for serial connection A will also cause serial connections B and C to fail.

          IMPORTANT If you’d like us to support multiple instances of a single service in the future, I encourage you to file an enhancement request describing your requirements.  Please post your bug number, just for the record.

          It is possible to work around this.  One easy workaround would be to have multiple services that all run the same code.  It’s unlikely that a Mac would have more than, say, 10 serial ports attached at once, so this won’t get too far out of control.  Also, you can use a framework to share code between the services, so the disk space impact won’t be prohibitive.

          The alternative is less easy, namely, you have a single service that acts as a broker and launches child processes to run each serial connection.  This breaks down as follows:

          1. The app connects to the main service and asks it to start a new serial connection.

          2. The service launches a child process (using NSTask or any other posix_spawn wrapper).

          3. That child ‘checks in’ with the main service.

          4. The child creates an anonymous XPC listener (+[NSXPCListener anonymousListener]), gets an endpoint for that listener (endpoint) and passes that endpoint to the service.

          5. The service then passes that endpoint back to the app.

          6. The app can then connect to the child directly (-[NSXPCConnection initWithListenerEndpoint:).

          Now, if the broker service goes down then that will take all of the connections with it, but that should be relatively robust because it’s not actually doing any work with the serial port.

          Getting this to work reliably will involve a bunch of complex code, but I don’t see any unsurmountable obstacles.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: NSXPCConnection multiple instances.
              ManuelCSolis Level 1 Level 1 (0 points)

              Thanks again eskimo... This is the Suggestion track number in bug reporter: 35659284.

              I will do my best to implement your suggestion, I will comment on the results.

               

              Thanks a lot.

               

              Manuel C.

              • Re: NSXPCConnection multiple instances.
                jalkut Level 1 Level 1 (0 points)

                Hi Quinn - thanks for outlining the solution here. I'm thinking about taking a crack at something similar. Specifically I want to be able to run AppleScript on multiple processes, one process per script. I'm a little scared off by "Getting this to work reliably will involve a bunch of complex code" ... any tips for what I should be looking out for? Thanks!

                 

                Daniel

                • Re: NSXPCConnection multiple instances.
                  lupinglade Level 1 Level 1 (0 points)

                  Hi eskimo,

                   

                  I am trying to build this solution you suggested, but am a bit unclear as to what you mean by:

                   

                  1. That child ‘checks in’ with the main service.
                  2. The child creates an anonymous XPC listener (+[NSXPCListener anonymousListener]), gets an endpoint for that listener (endpoint) and passes that endpoint to the service.

                   

                  Is this by letting the launched endpoint task connect to the broker task via NSXPCConnection(serviceName:)?

                   

                  It does not seem to be able to connect to the broker XPC service, I think because its a child task and doesn't have permission to talk to it? Because of this, I can't pass the endpoint back to the main application.

                   

                  Any idea what might be wrong?

                   

                  The error I am getting back in the endpoint task is:

                  Received error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.xxx.yyy.broker was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.xxx.yyy.broker was invalidated.}

                   

                  The broker is running when this error occurs and the main application can connect to it just fine (and launches it automatically).

                    • Re: NSXPCConnection multiple instances.
                      eskimo Apple Staff Apple Staff (13,905 points)

                      It does not seem to be able to connect to the broker XPC service, I think because its a child task and doesn't have permission to talk to it?

                      Quite possibly.  Alas, I must admit to have not actually tested this, and I just don’t have time to do that here on DevForums.  If you open a DTS tech support incident, that’ll give me a chance to dig into it properly.

                      Oh, one thing before you do that: Try doing the connect back with -initWithMachServiceName:options:.

                      Share and Enjoy

                      Quinn “The Eskimo!”
                      Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                      let myEmail = "eskimo" + "1" + "@apple.com"

                        • Re: NSXPCConnection multiple instances.
                          eskimo Apple Staff Apple Staff (13,905 points)

                          Quite possibly.

                          OK, I had a chance to look into this in depth last week.  Unfortunately the news is not great.  The strategy I outlined in my 20 Nov 2017 post works for launchd daemons and agents but it does not work for XPC Services.  The problem here is that that the XPC Service’s name is only registered in the app’s context.  It is not registered in the XPC Service’s context, so a child process launched by the XPC Service can’t connect to it.

                          The enhancement request that ManuelCSolis filed about this back on 21 Nov 2017 (r. 35659284) is still open and we’re using it to track the requirement for a supported way to implement multiple instances.  If you have a product that would benefit from this, it wouldn’t hurt to file your own enhancement request describing its specific requirements.

                          In the meantime, if you need to do this you should get in touch with DTS.  While there’s no general solution to this problem, in some cases their may be a special-case solution that meets your needs.

                          Share and Enjoy

                          Quinn “The Eskimo!”
                          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                          let myEmail = "eskimo" + "1" + "@apple.com"

                            • Re: NSXPCConnection multiple instances.
                              galad87 Level 2 Level 2 (50 points)

                              I hit the same issue in HandBrake (a sandboxed video transcoding app). Fortunately I need at most a few xpc istances, so I packed 4 separate xpc services (~ 80 KB each, linked to a framework to avoid duplicating most of the binary).

                              I'll fill an enhancement request too.