SIGN IN SIGN UP

osdc: deliver neorados completions to associated executor

while Objecter delivers librados completions directly by calling
Context::complete(), neorados completions are passed in as
boost::asio::any_completion_handler and delivered to an asio executor
via boost::asio::defer() on completion

asio handlers may have an "associated executor" so callers can customize
where these completions are delivered. for example, multithreaded
applications often use strand executors to synchronize completion
handlers and prevent data races between concurrent operations

however, applications like radosgw that depend on strands for
thread-safety did not get it due to the fact that Objecter's
Op::complete() delivered all neorados completions to the default
io_context executor

use boost::asio::get_associated_executor() to respect the handler's
executor affinity, if any. but because the Op's handler is the
type-erased any_completion_handler, its associated executor is also
type-erased as any_completion_executor. that any_completion_executor
doesn't support the blocking::never_t property required by defer/post,
so defer() was changed to dispatch() which may call the handler directly
if Objecter is already running on the requested executor. i assume this
is safe, given that librados' Context-based completions already do this

Fixes: https://tracker.ceph.com/issues/76725

Co-Authored-by: Oguzhan Ozmen <oozmen@bloomberg.net>
Signed-off-by: Casey Bodley <cbodley@redhat.com>
C
Casey Bodley committed
aabb5c70c56ed630a01c6f89d9981cdb6317ea34
Parent: cbacb23