|
|
Created:
4 years, 5 months ago by anthonyvd Modified:
4 years, 5 months ago CC:
chromium-apps-reviews_chromium.org, chromium-reviews, extensions-reviews_chromium.org Base URL:
https://chromium.googlesource.com/chromium/src.git@master Target Ref:
refs/pending/heads/master Project:
chromium Visibility:
Public. |
DescriptionRequest the Identity API's Uber Token without a Channel ID
BUG=621542
Committed: https://crrev.com/b07bc57f8b5e3407bc6a60901bc2da19046ac08d
Cr-Commit-Position: refs/heads/master@{#405596}
Patch Set 1 #
Total comments: 3
Patch Set 2 : Don't use AppRequestContext. #Patch Set 3 : Move IO thread bits in a separate class #
Total comments: 2
Patch Set 4 : Only cleanup io_helper_ if it was actually created. #
Messages
Total messages: 21 (7 generated)
anthonyvd@chromium.org changed reviewers: + courage@chromium.org, nharper@chromium.org
Hi guys, can you please take a look at this change to make the Identity API's Uber Token request without a Channel ID? Thanks! https://codereview.chromium.org/2145103003/diff/1/chrome/browser/profiles/pro... File chrome/browser/profiles/profile_io_data.h (right): https://codereview.chromium.org/2145103003/diff/1/chrome/browser/profiles/pro... chrome/browser/profiles/profile_io_data.h:293: protected: This diff is pretty bad. This is making AppRequestContext public.
I assume this is a temporary measure to fix the bug quickly. The uber token should eventually be channel bound again. https://codereview.chromium.org/2145103003/diff/1/chrome/browser/profiles/pro... File chrome/browser/profiles/profile_io_data.h (right): https://codereview.chromium.org/2145103003/diff/1/chrome/browser/profiles/pro... chrome/browser/profiles/profile_io_data.h:293: protected: On 2016/07/13 18:36:08, anthonyvd wrote: > This diff is pretty bad. This is making AppRequestContext public. The reason for using the AppRequestContext was to have something to hold ownership of the URLRequestContext's pointers. I think you could use an URLRequestContext directly and have the GaiaWebAuthFlow hold ownership (or use an URLRequestContextStorage to hold ownership of the new objects).
On 2016/07/13 at 20:04:48, nharper wrote: > I assume this is a temporary measure to fix the bug quickly. The uber token should eventually be channel bound again. Yes, although I'm still not sure how to get the app's request context to make that request in. > > https://codereview.chromium.org/2145103003/diff/1/chrome/browser/profiles/pro... > File chrome/browser/profiles/profile_io_data.h (right): > > https://codereview.chromium.org/2145103003/diff/1/chrome/browser/profiles/pro... > chrome/browser/profiles/profile_io_data.h:293: protected: > On 2016/07/13 18:36:08, anthonyvd wrote: > > This diff is pretty bad. This is making AppRequestContext public. > > The reason for using the AppRequestContext was to have something to hold ownership of the URLRequestContext's pointers. I think you could use an URLRequestContext directly and have the GaiaWebAuthFlow hold ownership (or use an URLRequestContextStorage to hold ownership of the new objects).
https://codereview.chromium.org/2145103003/diff/1/chrome/browser/profiles/pro... File chrome/browser/profiles/profile_io_data.h (right): https://codereview.chromium.org/2145103003/diff/1/chrome/browser/profiles/pro... chrome/browser/profiles/profile_io_data.h:293: protected: On 2016/07/13 at 20:04:47, nharper wrote: > On 2016/07/13 18:36:08, anthonyvd wrote: > > This diff is pretty bad. This is making AppRequestContext public. > > The reason for using the AppRequestContext was to have something to hold ownership of the URLRequestContext's pointers. I think you could use an URLRequestContext directly and have the GaiaWebAuthFlow hold ownership (or use an URLRequestContextStorage to hold ownership of the new objects). I see. I initially tried to use it because it's not possible to set HttpNetworkSession on net::URLRequestContext. Turns out it's HttpTransactionFactory that ties all of this together so using AppRequestContext was irrelevant. Done.
There are a two object lifetime issues I'm concerned about in this change. I have now forgotten the full details, but the GaiaWebAuthFlow won't always complete before its deletion. In particular if the browser shuts down, an app/extension API call can be destroyed without necessarily completing. You can trace through IdentityAPI::Shutdown to see how this would go. Imagine that that shutdown path executes while: 1. StartOnIOThread is running, using that base::Unretained(this) pointer. 2. The Ubertoken fetch is running. 3. While CleanupRequestContextOnIOThread is running. I think 1&3 could cause the I/O thread to access a deallocated GaiaWebAuthFlow. I think 2 could cause the ubertoken_request_context_ to be deleted on the UI thread instead of the IO thread, because the ubertoken callbacks will never run, and so ::~GaiaWebAuthFlow will end up deleting the request context.
On 2016/07/13 at 20:43:01, courage wrote: > There are a two object lifetime issues I'm concerned about in this change. I have now forgotten the full details, but the GaiaWebAuthFlow won't always complete before its deletion. In particular if the browser shuts down, an app/extension API call can be destroyed without necessarily completing. You can trace through IdentityAPI::Shutdown to see how this would go. Thanks for the feedback, I wasn't sure about that either. > > Imagine that that shutdown path executes while: > 1. StartOnIOThread is running, using that base::Unretained(this) pointer. > 2. The Ubertoken fetch is running. > 3. While CleanupRequestContextOnIOThread is running. > > I think 1&3 could cause the I/O thread to access a deallocated GaiaWebAuthFlow. > > I think 2 could cause the ubertoken_request_context_ to be deleted on the UI thread instead of the IO thread, because the ubertoken callbacks will never run, and so ::~GaiaWebAuthFlow will end up deleting the request context. What do you think about making GaiaWebFlow a base::RefCountedThreadSafe (and not calling base::Unretained(this)) to take care of 1&3 and calling CleanupOnIOThread from ~GaiaWebAuthFlow to address 2? Is there anything obviously wrong with that approach?
> What do you think about making GaiaWebFlow a base::RefCountedThreadSafe (and not > calling base::Unretained(this)) to take care of 1&3 Would be nice if you could avoid refcounting, but it would be ok. > and calling > CleanupOnIOThread from ~GaiaWebAuthFlow to address 2? Is there anything > obviously wrong with that approach? Once you're in ~GaiaWebAuthFlow on the UI thread, you won't (or at least should not) be able to add a reference to the destructing object to pass to the IO thread. You'd probably want to move the IO-owned references onto a new object so you can separate its lifetime from GaiaWebAuthFlow. I haven't thought it through all the way, but I think once you do that life will be easier. Maybe something like class GaiaWebAuthFlow { unique_ptr<BadlyNamedGaiaWebAuthFlowIOThreadStuffClass> io_stuff_ void CleanIOStuffFromUIThread() { PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&BadlyNamedGaiaWebAuthFlowIOThreadStuffClass::Cleanup, base::Unretained(io_stuff_.release())) } } class BadlyNamedGaiaWebAuthFlowIOThreadStuffClass { ~BadlyNamedGaiaWebAuthFlowIOThreadStuffClass() { /* maybe complain if not on IO thread */ } WeakPtr<GaiaWebAuthFlow> safe_to_post_me_to_ui_thread_tasks_ // can't be dereferenced on IO, but that's ok void Cleanup() { delete this; } }
On 2016/07/13 at 21:57:53, courage wrote: > > What do you think about making GaiaWebFlow a base::RefCountedThreadSafe (and not > > calling base::Unretained(this)) to take care of 1&3 > > Would be nice if you could avoid refcounting, but it would be ok. > > > and calling > > CleanupOnIOThread from ~GaiaWebAuthFlow to address 2? Is there anything > > obviously wrong with that approach? > > Once you're in ~GaiaWebAuthFlow on the UI thread, you won't (or at least should not) be able to add a reference to the destructing object to pass to the IO thread. You'd probably want to move the IO-owned references onto a new object so you can separate its lifetime from GaiaWebAuthFlow. I haven't thought it through all the way, but I think once you do that life will be easier. > > Maybe something like > > class GaiaWebAuthFlow { > unique_ptr<BadlyNamedGaiaWebAuthFlowIOThreadStuffClass> io_stuff_ > > void CleanIOStuffFromUIThread() { > PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&BadlyNamedGaiaWebAuthFlowIOThreadStuffClass::Cleanup, base::Unretained(io_stuff_.release())) > } > } > > class BadlyNamedGaiaWebAuthFlowIOThreadStuffClass { > ~BadlyNamedGaiaWebAuthFlowIOThreadStuffClass() { /* maybe complain if not on IO thread */ } > WeakPtr<GaiaWebAuthFlow> safe_to_post_me_to_ui_thread_tasks_ // can't be dereferenced on IO, but that's ok > void Cleanup() { delete this; } > } Makes a lot of sense! I've implemented something like this. Can you please take a look? Thanks!
lgtm https://codereview.chromium.org/2145103003/diff/40001/chrome/browser/extensio... File chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc (right): https://codereview.chromium.org/2145103003/diff/40001/chrome/browser/extensio... chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc:94: content::BrowserThread::PostTask( should check to see if io_helper_ has been set before posting. current callers always call Start, but you never know.
The CQ bit was checked by anthonyvd@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
https://codereview.chromium.org/2145103003/diff/40001/chrome/browser/extensio... File chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc (right): https://codereview.chromium.org/2145103003/diff/40001/chrome/browser/extensio... chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc:94: content::BrowserThread::PostTask( On 2016/07/14 at 17:53:30, Michael Courage wrote: > should check to see if io_helper_ has been set before posting. current callers always call Start, but you never know. Done.
The CQ bit was unchecked by anthonyvd@chromium.org
The CQ bit was checked by anthonyvd@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from courage@chromium.org Link to the patchset: https://codereview.chromium.org/2145103003/#ps60001 (title: "Only cleanup io_helper_ if it was actually created.")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Message was sent while issue was closed.
Committed patchset #4 (id:60001)
Message was sent while issue was closed.
CQ bit was unchecked.
Message was sent while issue was closed.
Description was changed from ========== Request the Identity API's Uber Token without a Channel ID BUG=621542 ========== to ========== Request the Identity API's Uber Token without a Channel ID BUG=621542 Committed: https://crrev.com/b07bc57f8b5e3407bc6a60901bc2da19046ac08d Cr-Commit-Position: refs/heads/master@{#405596} ==========
Message was sent while issue was closed.
Patchset 4 (id:??) landed as https://crrev.com/b07bc57f8b5e3407bc6a60901bc2da19046ac08d Cr-Commit-Position: refs/heads/master@{#405596} |