8 Replies
      Latest reply on Jul 16, 2019 7:09 AM by eskimo
      Sheppy Level 1 Level 1 (0 points)

        I have a Mac Carbon project that currently exists as a monolithic application that fhas a single main window that is primarily an OpenGL view into which 2D content is being drawn. Obviously, I'm eager to get this converted into a modern 64-bit application. I would also like to transition to allowing multiple windows to be open, each running an instance of the code that the existing application is based on, so that multiple ongoing sessions can be running at the same time.

         

        My plan is to remove all the UI code from the existing application, and to eradicate all Carbon dependencies so I can convert the code to 64-bit. Then I will create a wrapper application which handles the UI: the menus, the creation and management of the session windows, and so forth. Each time a new session is created or restored from a save file, I want the wrapper app to instantiate a copy of the main program, using an IOSurface and a shared memory object to allow the wrapper and the main program to share a memory buffer which is used as a texture for Metal to draw the graphics into the session's window.

         

        The main program is more than just a "helper" in that it can't be allowed to be terminated automatically or anything like that. It needs to stay running until the wrapper is quit or the wrapper tells a given session to exit.

         

        Right now, my main concern is figuring out the right way to create and manage the session processes. It sounds like in theory converting the main session program into an XPC service would be the right approach, except for a few concerns I have due to things I've read:

         

        1. It sounds like a given XPC service can only be run once. That would not suffice for my needs, since the whole point is to spawn multiple copies of it.
        2. It sounds like XPC services are really intended for processes that live a very short time, and for which there are limits on how much control you have over how long the service is permitted to run.
        3. If XPC isn't the right choice, what is? I know I'm not the first person to think of doing things this way...

         

        The basic model is something like this:

         

        ┌──────────────────────────────────────────────────┐                    ┌───────────────────┐
        │                                                  │                    │                   │
        │                   Main Program                   │        ┌ ─ ─ ─ ─ ─>│    SessionApp     │
        │ •••••••••••••••••••••••••••••••••••••••••••••••• │                    │                   │
        │                                                  │        │           └───────────────────┘
        │ ┌───────────────────┐          ┌───────────────┐ │                                         
        │ │                   │    ┌────>│ SessionWindow │<│─ ─ ─ ─ ┘           ┌───────────────────┐
        │ │                   │    │     └───────────────┘ │                    │                   │
        │ │                   │    │                       │        ┌ ─ ─ ─ ─ ─>│    SessionApp     │
        │ │    Main Menus     │    │     ┌───────────────┐ │                    │                   │
        │ │ Window Management │────┼────>│ SessionWindow │<│─ ─ ─ ─ ┘           └───────────────────┘
        │ │                   │    │     └───────────────┘ │                                         
        │ │                   │    │                       │                    ┌───────────────────┐
        │ │                   │    │     ┌───────────────┐ │                    │                   │
        │ │                   │    └────>│ SessionWindow │<│─ ─ ─ ─ ─ ─ ─ ─ ─ ─>│    SessionApp     │
        │ └───────────────────┘          └───────────────┘ │                    │                   │
        └──────────────────────────────────────────────────┘                    └───────────────────┘
                                                             messages back and                       
                                                            forth; shared memory                     
                                                                  for each                           
                                                              SessionWindow's                        
                                                                 MTKView's                           
                                                            window-sized texture                     
                                                                   buffer                            
                                                                                                     
                                                                                                     
        

         

        Any suggestions or advice? Thanks!

        • Re: Multi-window application with each window being handled by a sub-process
          KMT Level 9 Level 9 (14,835 points)

          If you strike out here, you might want to burn a support ticket w/DTS to see if they can help.

          Also...textdog salutes your AG skills
                 !
                     O      ^__^
                         o  (oo)\_______
                            (__)\       )\/\
                                ||----w | 
                                ||     ||     
          
          
          • Re: Multi-window application with each window being handled by a sub-process
            eskimo Apple Staff Apple Staff (12,095 points)

            It sounds like a given XPC service can only be run once.

            That’s correct.  Internally, XPC Services support the notion of multiple instances, but that support is not available for third-party use.  If you think that’d be helpful in your situation, please file a bug report describing your requirements.

            I’d appreciate your posting your bug number, just for the record.

            It sounds like XPC services are really intended for processes that live a very short time …

            I don’t think that’s a valid characterisation.  For example, the XPC Services used by WebKit are very long-lived.

            If XPC isn't the right choice, what is?

            It’s a tradeoff.  To implement this with XPC you have to jump through some hoops (more on that below) but you do get one key benefit, namely that the XPC API is much easier to use than most other IPC APIs.  That’s especially important in your case, because it’s likely that you’ll want to pass an IOSurface over your IPC channel.  That’s easy to do with XPC but tricky for other IPC mechanisms [1].


            With regards your specific setup, here’s how I’d implement this:

            1. You set up an XPC Service for managing the rendezvous.

            2. The app talks to the XPC Service to get it to start a new worker.

            3. In response, the XPC Service allocates a UUID and associates that with the worker instance.

            4. It then launches the worker (using NSTask, say), passing it the UUID as an argument.

            5. The worker allocates an anonymous XPC listener.

            6. It then creates an endpoint for that.

            7. Finally, it checks in with the XPC Service, using the UUID to identify itself and passing it the endpoint.

            8. The XPC Service then responds to the app, passing it the endpoint.

            9. The app can then use that endpoint to open a connection directly to the worker’s anonymous listener.

            Share and Enjoy

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

            [1] The only other IPC mechanism that allows you to transfer an IOSurface is Mach messaging, and Mach messaging is horribly hard to get right.

              • Re: Multi-window application with each window being handled by a sub-process
                Sheppy Level 1 Level 1 (0 points)

                Yeah, that's one of the approaches that has come up. I'm trying to make sure I find the least complex and most sturdy approach before I die in and start coding.

                 

                I have filed a bug report suggesting the notion of allowing multiple instances of an XPC service (https://feedbackassistant.apple.com/feedback/6142396). In there, I explain my situation and what I'm suggesting, and point out that for people like me trying to update old 32-bit Carbon apps to modern, secure 64-bit code before Catalina ships, this would potentially save an enormous amount of time and effort.

                  • Re: Multi-window application with each window being handled by a sub-process
                    eskimo Apple Staff Apple Staff (12,095 points)

                    I've actually already put in a DTS request

                    Yeah, I thought this sounded familiar.

                    I have filed a bug report suggesting the notion of allowing multiple instances of an XPC service

                    Thanks.  My recommendation is that you plan to implement your solution on the currently shipping infrastructure.  While it’s hard to predict the future with 100% accuracy, past experience is that it’s quite unusual for us to add significant APIs between WWDC and GM.

                    Share and Enjoy

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

                      • Re: Multi-window application with each window being handled by a sub-process
                        Sheppy Level 1 Level 1 (0 points)

                        Yes, that seemed obvious enough. Hopefully in the future I can simplify my code by just using multiple XPC service instances, but for now I'll have to create a service that creates instances, basically. OK. I'll see if I can implement something along those lines. FWIW it's something that would be really nice to see a DTS sample for, since upon searching around more I see this has been a topic of discussion in the past.

                         

                        With that sorted out, the specifics of what the DTS request is about are clearer, hopefully.

                    • Re: Multi-window application with each window being handled by a sub-process
                      Zachary Girouard Level 1 Level 1 (0 points)

                      Just a clarifying question before I start ripping apart my own app:

                       

                      The XPC service you refer to in the first step, that has to be a login item/Helper/SMJobBless style service? I've tried to few simple experiments with an on-demand XPCService, but if I launch an NSTask from it the launched task cannot communicate with the XPCService. Unless there's a non-obvious trick I'm missing?