After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 550278 - Engine kickstart should be more automatic
Engine kickstart should be more automatic
Status: RESOLVED FIXED
Product: ekiga
Classification: Applications
Component: Engine
unspecified
Other All
: Normal enhancement
: ---
Assigned To: Snark
Ekiga maintainers
Depends on:
Blocks:
 
 
Reported: 2008-09-01 19:06 UTC by Snark
Modified: 2009-02-17 15:04 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Snark 2008-09-01 19:06:06 UTC
* Starter objects

   A Starter object should have a single method, say "init", which
   receives &argc, &argv and an Ekiga::ServiceCore reference, and
   returns a value from a failed/partial/complete enum. Said method
   shouldn't mind being called several times.

   Example of "init" method: first, check that the needed services are
   present, and that the provided service isn't already in ; if all is
   well, use the needed services as argument to create new objects,
   and register services, then return 'true' ; if something is wrong
   (and finding the service you wanted to provide is wrong),
   return 'failed'. Notice that since argc and argv are available, it's
   possible to check if the user disabled something.

   Example of "init" method: check if the "gtk-init" service is there
   (return 'failed'), and if not, call gtk_init then register the
   "gtk-init" service and return 'complete'.

   Example of "init" method: check that all needed deps are here and a
   service isn't provided, and provide it. See that needed deps for a
   second service aren't satisfied and return 'partial' (you managed
   to provide one, so it can't be 'failed'). Next call, only  check if
   the second service can be enabled, since the first is already, and
   return 'failed' or 'complete'.

   * Firing the starters

   There is a list of Starter objects to which all Starters belong at first.

   The initialization algorithm is the following:
   (1) Take each Starter and try to "init" it:
      if 'failed' keep it there ;
      if 'partial' keep it there, but notice something good happened ;
      if 'complete' remove it and notice something good happened.
   (2) If something good happened, then get back to (1).

   * Algorithmic considerations

   Since we're looping on mostly the same list over and over again,
   the worst situation is when the most-needed dependancies are at the
   end of the list, because we could end up always getting to the end
   of the list to enable the feature -- this means a quadratic cost!

   If however they are just in the right order, then the cost is
   optimal: linear. So we really should put the built-in Starter
   objects in the right order to speed up starting time.

   Perhaps we should have a fourth value for complete failure? That
   would modify the algorithm that such an event would mean to remove
   the Starter from the loop while not noticing something good
   happened? (call it 'dead')

   Notice that the algorithm does end, since there is a strictly
   decreasing loop invariant : the number of not-yet-initialized
   services. There is a finite number of Starter objects, which want
   to initialize a finite number of services, and we loop only when we
   get a 'partial' or 'complete' initialization, ie when one of those
   services was started.

   !WARNING! This means an "init" method should really return 'failed'
   if it didn't manage to register a new service at this time, and
   not 'partial' because it registered one on the previous run! A good
   example to make it clear ; take a Starter has a "foo" and "bar"
   service to enable :
   + first "init" run: the "foo" service is enabled, but "bar"
   can't be -- return 'partial' ;
   + second "init" run: the "bar" service still can't be enabled ; we
   still had a success with "foo", but we don't care -- return
   'failed' .

   * Why so complex?

   We need such a complex system because when external plugins will
   enter the picture, we will get them in filesystem order, so we need
   a way to order them correctly and automatically.

   Another advantage of this system is that if the Ekiga::ServiceCore
   stores the Ekiga::Service in FILO order, then if we uninitialize
   the services in that order all will go well. This is something
   std::tr1::smart_ptr would have given too -- but they have a size
   cost and dynamic_cast can't be used on them.
Comment 1 Snark 2009-01-07 16:38:53 UTC
Ok, I implemented something like this and started to make use of it for some modules.

What do you think about it at this point?
Comment 2 Snark 2009-02-17 15:04:14 UTC
No complaints : it must be good enough.