brightray/brightray — pull request #32 by aroben (2013-10-23 16:17:22+00:00)
Title: Fix a hang on quit when application cache is used

If you navigated to a page that used the HTML Application Cache, you'd see a hang on quit with a backtrace like so:

```
+ 2825 content::ContentMain(int, char const**, content::ContentMainDelegate*) (in libchromiumcontent.dylib) + 64 [0xb33190]
+ 2825 ??? (in libchromiumcontent.dylib) load address 0x1c9000 + 0x96b261 [0xb34261]
+ 2825 ??? (in libchromiumcontent.dylib) load address 0x1c9000 + 0x96a409 [0xb33409]
+ 2825 content::BrowserMain(content::MainFunctionParams const&) (in libchromiumcontent.dylib) + 200 [0x14290b8]
+ 2825 ??? (in libchromiumcontent.dylib) load address 0x1c9000 + 0x1265426 [0x142e426]
+ 2825 content::BrowserMainLoop::~BrowserMainLoop() (in libchromiumcontent.dylib) + 17 [0x14294a1]
+ 2825 content::BrowserMainLoop::~BrowserMainLoop() (in libchromiumcontent.dylib) + 357 [0x1429625]
+ 2825 brightray::BrowserMainParts::~BrowserMainParts() (in ) + 70 [0x68df6]
+ 2825 scoped_ptr >::~scoped_ptr() (in ) + 23 [0x68ff7]
+ 2825 scoped_ptr >::~scoped_ptr() (in ) + 23 [0x69297]
+ 2825 base::internal::scoped_ptr_impl >::~scoped_ptr_impl() (in ) + 23 [0x692b7]
+ 2825 base::internal::scoped_ptr_impl >::~scoped_ptr_impl() (in ) + 50 [0x692f2]
+ 2825 base::DefaultDeleter::operator()(brightray::BrowserContext*) const (in ) + 46 [0x6916e]
+ 2825 brightray::BrowserContext::~BrowserContext() (in ) + 127 [0x672bf]
+ 2825 base::SupportsUserData::~SupportsUserData() (in libchromiumcontent.dylib) + 57 [0xccc019]
+ 2825 ??? (in libchromiumcontent.dylib) load address 0x1c9000 + 0xb03230 [0xccc230]
+ 2825 ??? (in libchromiumcontent.dylib) load address 0x1c9000 + 0xb0324e [0xccc24e]
+ 2825 ??? (in libchromiumcontent.dylib) load address 0x1c9000 + 0x14c4239 [0x168d239]
+ 2825 content::StoragePartitionImpl::~StoragePartitionImpl() (in libchromiumcontent.dylib) + 17 [0x16899a1]
+ 2825 content::StoragePartitionImpl::~StoragePartitionImpl() (in libchromiumcontent.dylib) + 491 [0x1689bab]
+ 2825 content::ChromeAppCacheService::DeleteOnCorrectThread() const (in libchromiumcontent.dylib) + 66 [0x1424f32]
+ 2825 content::ChromeAppCacheService::~ChromeAppCacheService() (in libchromiumcontent.dylib) + 50 [0x1424e32]
+ 2825 appcache::AppCacheService::~AppCacheService() (in libchromiumcontent.dylib) + 301 [0x2b8ad2d]
+ 2825 ??? (in libchromiumcontent.dylib) load address 0x1c9000 + 0x29c9b81 [0x2b92b81]
+ 2825 ??? (in libchromiumcontent.dylib) load address 0x1c9000 + 0x29c9da4 [0x2b92da4]
+ 2825 appcache::AppCacheDiskCache::~AppCacheDiskCache() (in libchromiumcontent.dylib) + 17 [0x2b78c71]
+ 2825 appcache::AppCacheDiskCache::~AppCacheDiskCache() (in libchromiumcontent.dylib) + 135 [0x2b78d17]
+ 2825 disk_cache::BackendImpl::~BackendImpl() (in libchromiumcontent.dylib) + 17 [0x25979a1]
+ 2825 disk_cache::BackendImpl::~BackendImpl() (in libchromiumcontent.dylib) + 305 [0x2597af1]
+ 2825 base::WaitableEvent::Wait() (in libchromiumcontent.dylib) + 50 [0xccd942]
+ 2825 base::WaitableEvent::TimedWait(base::TimeDelta const&) (in libchromiumcontent.dylib) + 347 [0xccdb3b]
+ 2825 base::ConditionVariable::Wait() (in libchromiumcontent.dylib) + 35 [0xcccbb3]
+ 2825 pthread_cond_wait$UNIX2003 (in libsystem_c.dylib) + 71 [0x964d3089]
+ 2825 _pthread_cond_wait (in libsystem_c.dylib) + 833 [0x9644d280]
+ 2825 __psynch_cvwait (in libsystem_kernel.dylib) + 10 [0x94b8e8e2]
```

`BackendImpl` was waiting on `BrowserThread::CACHE`, but that thread had already been stopped. The solution is to destroy the BrowserContext before threads have been stopped. We now do this in `BrowserMainParts::PostMainMessageLoopRun`, which matches content_shell.