Activation vs. factory life cycles



Hello, bouncing monkeys,

I just figured out that there is a problem when you are using
activation via GOAD and a particular type of factory.

The factory in question is the one used in Evolution's personal
calendar server (PCS).  The CalFactory creates calendar backends
(CalBackend).  A CalBackend has the storage, notification, and event
generation stuff that calendars need; it happens to be a plain GTK+
object.

Also, each CalBackend has a list of Cal CORBA interfaces, which are
ones that calendar clients talk to.  The idea is that a CalBackend is
a unique calendar, and it is exported to multiple clients via Cal
CORBA objects.  For the purposes of this discussion, all CORBA
interfaces here also implement Bonobo::Unknown.

Say multiple clients are accessing a single calendar backend via a
number of Cal objects.  When a client is done with a calendar, it
unrefs the Cal object.  When all Cal objects for a particular
CalBackend are destroyed, i.e. a backend has no more clients, then the
CalBackend is destroyed.

You do not want the factory that created the backends to run forever
after it is launched; the policy we adopted is that the factory also
goes away when all the backends are destroyed.

Clients obtain the factory with GOAD.  Then they call something like
cal_factory_load_calendar (f, "uri"); and they will be notified
asynchronously when the loading is complete via a client-side Listener
CORBA interface.

So the calendar client code is more or less like this

	(1) f = goad_server_activate_with_id ("evolution:cal_factory", GOAD_ACTIVATE_REMOTE);

	(2) cal_factory_load_calendar (f, "uri", my_listener);

However, consider the situation when the factory was already running
and you just get a CORBA reference to it in (1).  Say you are context
switched at that point and the following happens.  All other calendar
clients unref all their backends, so the factory decides to go away.
At that point (2) is scheduled and it fails horribly because the
factory no longer exists.

The problem exists because the activation process knows nothing about
the life cycle of the factory.  The life cycle of the factory is
indirectly controlled by the presence of active backends; when all the
backends go away, the factory goes away.

Assume the activation process knew about Bonobo objects.  If so, it
could atomically do a Bonobo_Unknown_ref() on the factory when it
activates it.  Thus activating an object would implicitly do a
reference count on it.  The last backend to be destroyed could unref
the factory and thus make it go away.  This would eliminate the race
condition that occurs from the point of view of the clients.

This problem will happen all over the place once we have many
singleton-type service factories and service backends in Bonobo.

This should be taken into account for OAF, as GOAD may be impossible
to change for this right now.

Comments?

  Federico



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]