
|
[interfacekit] Re: Phase 1
- From: "Ingo Weinhold" <bonefish@xxxxxxxxxxxxxxx>
- To: interfacekit@xxxxxxxxxxxxx
- Date: Sat, 06 Jul 2002 04:09:16 CEST (+0200)
> Agreed on all points. =) I think B_REG_* is a good choice.
Alright, let's use those then.
> >Are you content with the message/type constant values? Or do you
> > think
> >they should also lie within the range Be reserved, i.e. 'ABCD' for
> > type
>
> >constants and '_ABC' for message constants? As discussed, the API
> > user
> >won't get in contact with them.
>
> Hmm, hadn't thought about that. I think sticking with Be's protocol
> is
> probably best; developers already know not to step on that range,
> which
> is really my only concern here.
My point was, that it actually doesn't matter, if developers use the
same values, since the areas of use are completely disjoint. Neither
can a registrar message fall into the hands of a developer object, nor
can a developer send a message to any entity that also deals with
registrar messages (well, to the registrar itself, but doing that
requires some criminal energy anyway). So actually I don't see any
reason to pollute the three letter namespace with quite a bunch of new
messages codes. Especially because we would define them in a different
(internal) header, not in AppDefs.h.
However, I wouldn't insist on using another namespace, so if you
object, I have no problem with using Be's namespace.
> Going back over the original mail, I
> didn't actually see any constants being proposed, just their #defines
> .. maybe in an earlier mail?
I didn't suggest concrete values for the constants, just the general
pattern:
"For the message constant values I suggest four small letters starting
with 'rg', e.g. 'rgsu' for REG_SUCCESS..."
> >Yep, they are and I meant it to be a direct replacement for
> >AddApplication() only.
> >Some clarifications: The four functions should merely be equivalent
> > to
> >the current functions:
> >
> >RegisterApp() == AddApplication()
> >RegisterRunningApp() == CompleteRegistration()
> >UnregisterRunningApp() == RemoveApp()
> >UnregisterApp() == RemovePreRegApp()
> >
> >Well, actually I don't know, whether they are equivalent, because I
> >haven't completely understood the original ones.
> >Here is how I think the registration process should work. There are
> > two
>
> >levels of registration, err, actually three: unregistered,
> > registered
> >and registered-running.
>
> I have to admit I was a bit confused by this. I sat and did a lot of
> head scratching and cogitation. The central questions were:
>
> 1) If AddApplication() takes the team_id, thread_id and port_id as
> parameters, why would it later need to send those very same
> parameters
> to the roster via CompleteRegistration()?
>
> 2) Looking at RemovePreRegApp(), I saw IsAppPreRegistered().
> Assuming
> these two are related (which seems reasonable), why/how would an app
> get
> "preregistered"?
>
> I had no idea, so I went and watched a movie instead. =) When I came
> back from that, it occured to me that there are two ways an
> application
> can get launched: directly, and by BRoster::Launch(). In cases where
> the app is launched directly, BRoster::AddApplication() would get
> used,
> because all the necessary "registration" info is immediately
> available
> to the launching app. In cases where BRoster::Launch() is used,
> three
> vital pieces of information are *not* available when the roster is
> first
> made aware of the launch: the team_id, thread_id and port_id.
> Following
> this train of thought, it seems to me that when BRoster::Launch() is
> used, the app is "preregistered" with the roster, the app is run, and
> when BApplication gets to the point where it would normally register
> itself with the roster it checks to see if it's been preregistered
> (BRoster::IsAppPreRegistered()) and calls CompleteRegistration() if
> it
> has been. The app's entry in the roster would then get "moved" from
> its
> preregistered state to a fully registered state.
Yes, that sounds like a reasonable explanation. :-)
> The short version is that there isn't a two-stage registration
> process,
> but two *different* registrations processes: one for direct launches,
> one for BRoster::Launch() initiated launches.
And the latter is two-stage: AddApplication() + CompleteRegistration().
;-P
> >The BApplication constructor makes the application known to the
> > roster
> >via RegisterApp(). From that time on it appears on the roster, i.e.
> >roster-watchers receive a notification and all others can use the
> >BRoster functionality to query the app -- IsRunning() will return
> > true,
>
> >and TeamFor() and GetRunningAppInfo() will work. Registered-running
> > is
> >the level on which the application, that is its message loop, is
> > really
>
> >running. BApplication::Run() will call RegisterRunningApp() which in
> >turn will cause the roster to send the B_ARGV_RECEIVED,
> > B_REFS_RECEIVED
> >and B_READY_TO_RUN messages.
>
> In cases of direct launches, it introduces extra (and unnecessary)
> overhead to send the info necessary for those three messages to the
> roster, only so it can turn around and send them right back. Maybe
> it
> would send them for BRoster::Launch() launches, but that doesn't make
> much sense either: BRoster::Launch() could simply call load_image(),
> which takes argc and argv and probably passes them directly to the
> app.
>
> It's unclear from the docs whether BRoster calls load_image() or the
> roster itself calls it. Looking at RemovePreRegApp(), my guess is
> that
> BRoster pre-registers the app with the roster (which returns a token)
> and then attempts to launch it (via load_image()). If the launch
> fails,
> BRoster uses RemovePreRegApp() to clear the roster entry. If the
> roster
> was actually launching the app, I don't think
> BRoster::RemovePreRegApp()
> would need to exist.
Right.
> >> In particular
> >> these
> >
> >> >params:
> >> >- argc: The application's command line parameter count.
> >> >- argv: The application's command line parameters.
> >>
> >> don't make any sense when BApplication is registering itself --
> > > why
> >> would BRoster care what these are, since the app already knows?
> >
> >I think, it makes sense. Or at least it makes things easier. If the
> >roster sends B_ARGV_RECEIVED, then those arguments must get there
> >somehow. Well, you might say, that the application could as well
> > send
> >the message itself or just call ArgvReceived(). OK, then this
> > argument
> >may be more convincing: If the application is single/exclusive
> > launch
> >and called the second time, then the argvs must be sent to the
> > already
> >running instance. If the latter is on level registered, not
> > registered-
> >running, then it might be better to wait with sending the argvs
> > until
> >its message loop is running. The roster can do that, the new
> >application instance can't.
>
> That last statement isn't actually true. If an app is single/
> exclusive
> launch, it can check the roster to see if an instance is already
> running
> with BRoster::GetAppInfo(). If an instance *is* running, it can use
> the
> team_id in the app_info struct returned by GetAppInfo() to create a
> BMessenger and send along the B_ARGV_RECEIVED message itself.
While this is true, my last statement was only referring to the fact,
that the new app can't know, if the message loop of the already
"running" app is really running. With a two-stage registration, the
roster would know that and would be able to avoid sending messages to
such an application (until, if ever, the message loop is running).
However, this might not be of much relevance.
> Either
> way it's launched, the app is going to get argc and argv -- it makes
> more sense to just have the app deal with them locally than to send
> them
> over to the roster and have the roster forward them (if necessary) or
> just send them right back. These same arguments (approximately)
> apply
> to B_REFS_RECEIVED and B_READY_TO_RUN.
>
> >To summarize my point: The roster can much better deal with the argv
> >stuff, and let it do so makes the BApplication side a lot simpler.
>
> I don't think the first is necessarily true, and I don't see a
> particular advantage to pushing the work onto the roster instead of
> doing it in BApplication. In fact, we would introduce additional
> messaging overhead by doing so.
I'll try to explain my point below.
> >> >params:
> >> >- team: The application team.
> >> >- thread: The application looper thread.
> >
> >A correction: The thread argument is not needed here, but in
> >RegisterApp(). It is not the looper thread, but the application's
> > main
> >thread (which may differ). The same of course goes for the message
> >protocols.
>
> How are the threads going to differ? The docs explicitly state that
> BApplication "takes over" whatever thread it's in.
Yes, and that is exactly why the main thread (the thread that enters
main()) and the app looper thread can differ.
> >I'm not sure, if it is really necessary to have a two-level
> >registration, but it seems to me at least convenient. For sure it
> > gives
> >the roster more knowledge, that can be exploited -- e.g. avoid
> > sending
> >an application not running the message loop messages.
>
> I see what you're saying, though it would entail adding a function to
> BRoster (IsLoopRunning() or something).
Only if you want to share the roster knowledge with the applications.
> I think the odds are pretty
> slim of there being messages already waiting in the queue of an app
> that
> fails to launch, and having a few messages "disappear" once in a blue
> moon doesn't strike me as a problem. And now that I think about it,
> how
> would one actually *send* messages to an app that hasn't managed to
> successfully launch? The only mechanism I can think of is
> BRoster::Launch(), and that will clearly let the caller know if the
> launch failed -- not to mention, it's not likely to try and send
> messages to an app it couldn't launch. ;)
I'm not talking about applications failing to launch, but about the
time between the return of the BApplication constructor and the
invocation of Run() (if at all -- some programs create a BApplication
only because they want to deal with BBitmaps and don't need messaging
at all). Though it is bad practice to do a lot of things in the
constructor of the BApplication derived class, it is not too unusual
practice to do so. However you might be right objecting that it is
quite unlikely that within this period of time the message queue is
flooded.
> >> >message: REG_REGISTER_RUNNING_APP
> >> >message: REG_UNREGISTER_RUNNING_APP
> >>
> >> Unless I was horrendously mistaken earlier, these two messages
> > > should
> >> not be needed.
> >
> >If we drop the corresponding methods, then I agree. But currently I
> >still like the idea of a two-level registration.
>
> As I said before, I don't think there are two levels in the
> registration
> process -- there are two *different* registration processes. Maybe I
> should write up a coherent outline of what I think the process looks
> like ... ??
Won't be necessary. I think, I understand the process now.
Nevertheless, I believe, Be's process is more complicated than it had
to be. And my primary intention was to simplify things a bit. I will
try to clarify my point and adjust my idea according to some of your
concerns.
Why two stages?
After rethinking it, I guess, the only thing I wanted to avoid is, that
messages are sent to an application before its message loop is running,
i.e. Run() has been called. Actually the only problem that could arise,
was that the message queue -- to be precise: the port's buffer -- runs
full. I have to agree, that this is merely a theoretical problem.
Why sending the argvs to the roster for registration?
You are right, that is not necessary. The application calls
BRoster::RegisterApp() (or AddApplication(), if you like). If the
roster reports that everything went fine, the application sends
B_ARGV_RECEICED to itself. If it says, that an instance of the app is
already running, then it can as well pass a messenger targeting this
instance back, so that our application can use this to send
B_ARGV_RECEIVED without further querying.
Straight forward and certainly quite similar to the current
implementation.
BRoster::Launch()
That is where I see some potential for simplification. Why dealing with
pre-registration when the roster can gracefully handle that internally?
What I'm proposing: Send a launch request including the argvs (oh my...
he did it again ;-) to the registrar and the registrar determines,
whether the application is already running. If so, it sends a
B_ARGV_RECEIVED to it and passes a messenger to it back to the
launching application, which can in turn send (if any) B_REFS_RECEIVED
and the other messages passed to Launch(). If not, the registrar pre-
registers the application internally and launchs it, and again sends
back a messenger for the other messages to be send. The newly launched
application registers regularly. To keep the registrar responsive, the
launch is executed in a new thread.
OK, what are the costs:
1) The argvs have to be sent and
2) a temporary thread has to be spawned.
What is gained:
1) The application side registration process is simplified: It consists
of exactly one request posted via RegisterApp(), no exceptions.
2) BRoster::Launch() (xLaunchAppPrivate()) is simplified
..
Mmh, this is not convincing at all, is it?
Basically the work is moved into the registrar, what saves some
communication overhead and due to the direct access to the information
things might be a bit easier to implement there. I thought, it would be
possible to get rid of the pre-registration completely, but that does
only work, if the app is not launched in a separate thread (otherwise
it might be able to register before the launch thread reports the team
ID to the roster).
Alright, I give up here. :-)
Anyway, here is a tricky one. I just re-read the BRoster::Launch()
documentation and it goes like this:
"If a message is specified, it will be sent to the application on-
launch where it will be received and responded to before the
application is notified that it's ready to run."
I wonder how that works. After the launching application has called
load_image() it has no control over the launched app. So, if it sends
the messages passed to Launch() itself, it can't ensure, that they will
arrive before the other app starts running. The only way I can imagine
is that it somehow passes the messages to the roster, which delivers
them when the launched application completes the registration via
CompleteRegistration().
I'm afraid here is still some research to be done.
CU, Ingo
Other related posts:[interfacekit] Phase 1 [interfacekit] Re: Phase 1 [interfacekit] Re: Phase 1 [interfacekit] Re: Phase 1 [interfacekit] Re: Phase 1 [interfacekit] Re: Phase 1 [interfacekit] Re: Phase 1 [interfacekit] Re: Phase 1 [interfacekit] Re: Phase 1
|

|

|
[ Home |
Signup |
Help |
Login |
Archives |
Lists
]
All trademarks and copyrights within the FreeLists archives are owned
by their respective owners. Everything else ©2008 Avenir Technologies, LLC.
|

|
|