1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ios/web/webui/url_data_source_ios_impl.h"
8 #include "base/location.h"
9 #include "base/memory/ref_counted_memory.h"
10 #include "base/strings/string_util.h"
11 #include "ios/web/public/url_data_source_ios.h"
12 #include "ios/web/public/web_thread.h"
13 #include "ios/web/webui/url_data_manager_ios_backend.h"
17 URLDataSourceIOSImpl::URLDataSourceIOSImpl(const std::string
& source_name
,
18 URLDataSourceIOS
* source
)
19 : source_name_(source_name
), backend_(NULL
), source_(source
) {
22 URLDataSourceIOSImpl::~URLDataSourceIOSImpl() {
25 void URLDataSourceIOSImpl::SendResponse(int request_id
,
26 base::RefCountedMemory
* bytes
) {
27 // Take a ref-pointer on entry so byte->Release() will always get called.
28 scoped_refptr
<base::RefCountedMemory
> bytes_ptr(bytes
);
29 if (URLDataManagerIOS::IsScheduledForDeletion(this)) {
30 // We're scheduled for deletion. Servicing the request would result in
31 // this->AddRef being invoked, even though the ref count is 0 and 'this' is
32 // about to be deleted. If the AddRef were allowed through, when 'this' is
33 // released it would be deleted again.
35 // This scenario occurs with DataSources that make history requests. Such
36 // DataSources do a history query in |StartDataRequest| and the request is
37 // live until the object is deleted (history requests don't up the ref
38 // count). This means it's entirely possible for the DataSource to invoke
39 // |SendResponse| between the time when there are no more refs and the time
40 // when the object is deleted.
43 web::WebThread::PostTask(
44 web::WebThread::IO
, FROM_HERE
,
45 base::Bind(&URLDataSourceIOSImpl::SendResponseOnIOThread
, this,
46 request_id
, bytes_ptr
));
49 void URLDataSourceIOSImpl::SendResponseOnIOThread(
51 scoped_refptr
<base::RefCountedMemory
> bytes
) {
52 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::IO
);
54 backend_
->DataAvailable(request_id
, bytes
.get());