ceph/ceph — pull request #414 by dachary (2013-07-09 12:35:56+00:00)
Title: replace ObjectContext pointers with shared_ptr

The ObjectContext pointers are shared using a ref data member that
needs to be updated by the caller. This is tedious and error
prone. All pointers are replaced with shared_ptr for
automatic reference counting and the ref data member is removed.

The ReplicatedPG::object_contexts is changed to a SharedPtrRegistry.
Two new methods are added to SharedPtrRegistry : get_next() with a
value of ObjectContextRef instead of ObjectContext and empty().

The SharedPtrRegistry_ptr do not delete the ObjectContext or update the
ReplicatedPG::object_contexts at exactly the same point as
ReplicatedPG::put_object_context does. It happens when the last object
holding a shared_ptr goes out of scope, which is always later than
the call to ReplicatedPG::put_object_context.

The ObjectContext::get method is removed: its only purpose is to
increment the ref.

The ReplicatedPG::_lookup_object_context method is removed because it
is used once to retrieve an ObjectContext without incrementing ref, in
order to save a call to ReplicatedPG::put_object_context. Since the ref
data member is no longer used, the method is redundant.

The ReplicatedPG::lookup_object_context (no underscore) method is
replaced with SharedPtrRegistry::lookup.

The ReplicatedPG::put_object_context has three different purposes: a)
check mode.wake b) decrement the ref of the associated ObjectContext
given in argument c) if the ref drops to zero delete the object,
delete its entry in the ReplicatedPG::object_contexts registry and
call PG::kick. The decrementing part is no longer necessary because
the SharedPtrRegistry takes care of it. The mode.wake check is moved
to the check_wake method. The cleanup that happens on deletion is
moved to the ObjectContext destructor, using a Context object as a
callback to invoke the
ReplicatedPG::object_context_destructor_callback method.

ReplicatedPG::register_object_context is removed and the
-----
initialization
of the ObjectContext only three times with
struct C_PG_ObjectContext : public Context is a callback added to the
ObjecContext and called by the destructor. It is set by the
ReplicatedPG::register_object_context method which is called
immediately after new ObjectContext.

ReplicatedPG::put_object_contexts calls put_object_context on a list
of ObjectContexts and clears the list. It is replaced by a call to
list::clear. It also ( indirectly ) checks mode.wake because
put_object_context does. However, it is always called before or a
after a call to ReplicatedPG::put_object_context ( no s at the end )
which is replaced with check_wake, therefore the expected side effect
happens anyway.

ReplicatedPG::context_registry_on_change is a call to the
Watch::discard method of all the watchers found in
ReplicatedPG::object_contexts. It also calls
ReplicatedPG::put_object_contexts on all of them and it is replaced
with a single call to check_wake()

ReplicatedPG::_finish_mark_all_unfound_lost explicitely calls
ReplicatedPG::put_object_contexts in a loop to clear the list. It is
taken care of by shared_ptr and the list can be cleared without
iterating over all its elements. A single call to check_wake is added.

Watch::get_obc is inlined and does not rely on the ObjectContext::get
method.

http://tracker.ceph.com/issues/5510 refs #5510

Signed-off-by: Loic Dachary