(Putting this on scheduler-dev for visibility / archiving.)We talked a bit about exposing a variant of SingleThreadTaskRunner::GetCurrentDefault() that returns a BEST_EFFORT sequence, so that code in layers like components/ that don't have direct access to content::GetUIThreadTaskRunner() etc. can get "the right BEST_EFFORT sequence for the current context". Let's call it SingleThreadTaskRunner::GetCurrentBestEffort(), for argument.The problem is that only sequences managed by SequenceManager have multiple task queues, so in many cases there won't be a BEST_EFFORT sequence corresponding to the current default. (eg. if the current default task runner was returned by base::ThreadPool::CreateSingleThreadTaskRunner). We could return null in that case, or CHECK in the same way the GetCurrentDefault() does when called outside a single-threaded context, but I think that would be too confusing. The nuances of which threads/sequences have a BEST_EFFORT task queue are a lot harder to explain than whether the code is running on a managed sequence / thread or not.(I mean, from a content/ layer perspective it's easy to explain: there's a BEST_EFFORT task queue if you're on a named browser thread. But the whole point of exposing GetCurrentBestEffort() in base/ is to avoid depending on that content layer knowledge.)More specifically, I don't think GetCurrentBestEffort() should return null, because that wouldn't parallel GetCurrentDefault() so it would be easy to forget to null-check it. And I don't think it should CHECK because it would be really fragile for callers from components/ that are, in theory, running on an arbitrary sequence - they wouldn't know when it's safe to call.I've thought of two other approaches - what do you think of these?1. Expose SequenceManager::GetCurrent().
It returns the SequenceManager that controls the current sequence, or nullptr if there is none. Then SequenceManager can have a GetBestEffortTaskRunner() method.Code in components/ that doesn't know the current sequence will have to have a fallback if SequenceManager::GetCurrent() returns null. But I think that's less confusing than returning null from SingleThreadTaskRunner::GetCurrentBestEffort() because you wouldn't expect a SequenceManager method to have the same semantics as a SingleThreadTaskRunner method.2. Expose SingleThreadTaskRunner::GetAssociatedBestEffortSequence().
This returns a BEST_EFFORT TaskRunner that may or may not run tasks on the current sequence.
If on a SequenceManager sequence, it returns the BEST_EFFORT TaskQueue. If on a ThreadPool sequence, it returns a different ThreadPool sequence with the same traits but different priority.So the caller can always use this to post a BEST_EFFORT task, and if it also needs that task to be sequenced with the current sequence, it can check with RunsTasksInCurrentSequence(). eg. it could use the GetAssociatedBestEffortSequence() sequence if RunsTasksInCurrentSequence() returns true, or GetCurrentDefault() otherwise. Or it could post a BEST_EFFORT task to do part of the work, and BindPostTask(GetCurrentDefault(), rest_of_work) to post back to the current sequence if needed.