[interfacekit] App Registration

Hi,

I did some investigation and think, I understand the app registration 
and launch process a bit better now. Here it goes:

BApplication::InitData():
* check signature
* collect all the information about the application (team_id,
  BAppFileInfo,...)
* check BRoster::IsAppPreRegistered()
  - if so, create B_ARGV_RECEIVED message and add it to the message
    queue (BLooper::AddMessage()), call BRoster::CompleteRegistration()
    and return
* call BRoster::AddApplication()
  - if it fails because the app is single/exclusive launch and already
    running, create B_ARGV_RECEIVED message, send it to the already
    running instance, and exit()
* create B_ARGV_RECEIVED message and B_READY_TO_RUN and add them to
  the message queue

BRoster::xLaunchAppPrivate()
* call BRoster::AddApplication() for pre-registration
  - if the app is single/exclusive launch and already runnning, send
    B_ARGV/REFS_RECEIVED and other messages straight to it and return
* call load_image()
  - if it fails, call BRoster::RemovePreRegApp() and return
* send B_REFS_RECEIVED/other messages and B_READY_TO_RUN to the new
  application

This is pretty much, what Erik wrote, plus it answers how to ensure the 
initial messages being processed before ReadyToRun() is called.

Sounds good, but has one problem, a race condition to be precise. After 
calling load_image() the new program runs, but noone knows, how long 
(if at all) it will take until it constructs a BApplication object. 
Sending messages to it appears to be sort of a problem without a port 
hanging around at the remote site.

I first thought, this was solved by waiting for the app to be up (via a 
request to the registrar or so), but that's wrong. BRoster::Launch() 
returns immediately. My last test result was really confusing me. I had 
two applications, the first Launch()ing the second one, and then 
sending another message to it. The second one had a snooze() of several 
seconds at the very beginning of its main(), in particular before the 
BApplication constructor. That confusing fact was, that the first app 
ran only a fraction of a second, but both messages -- the one passed to 
Launch() and the one sent explicitly thereafter -- magically appeared 
in the MessageReceived() of the remote application object constructed 
seconds after the first application was already gone.

The explanation for this phenomenon is not, as one could think, that 
the first application moved in time to the point where the second 
application has just constructed its BApplication object, delivers the 
messages and moves back to the original time, but that after loading an 
application image there is already a port available. For those who, 
looking at the listport output, wondered, why app looper ports can have 
two different names, that's the answer: A port named `rAppLooperPort' 
is created while loading libbe -- certainly in initialize_before() -- 
and is taken over by the BApplication object, if it is pre-registered, 
that is launched by another application. Otherwise the port created by 
the BLooper is used as usual.

One last thing. I found the symbols __libc_argc and __libc_argv which 
seem to be what I was looking for -- the argc/argv combo passed to 
main(). Unless someone tells me that it isn't a good idea to use them 
or that there is a better way, I will go with these.

CU, Ingo



Other related posts: