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