Eric Seidel e0fd75b5ab Make absolute and sort all Sky headers
This caused us to lose our gn check certification. :(

Turns out gn check was just ignoring all the header
paths it didn't understand and so gn check passing
for sky wasn't meaning much.  I tried to straighten
out some of the mess in this CL, but its going to take
several more rounds of massaging before gn check
passes again.  On the bright side (almost) all of
our headers are absolute now.  Turns out my script
(attached to the bug) didn't notice ../ includes
but I'll fix that in the next patch.

R=abarth@chromium.org
BUG=435361

Review URL: https://codereview.chromium.org/746023002
2014-11-20 17:42:05 -08:00

359 lines
12 KiB
C++

/*
Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
Copyright (C) 2001 Dirk Mueller <mueller@kde.org>
Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef Resource_h
#define Resource_h
#include "sky/engine/core/fetch/ResourceLoaderOptions.h"
#include "sky/engine/platform/Timer.h"
#include "sky/engine/platform/network/ResourceError.h"
#include "sky/engine/platform/network/ResourceLoadPriority.h"
#include "sky/engine/platform/network/ResourceRequest.h"
#include "sky/engine/platform/network/ResourceResponse.h"
#include "sky/engine/wtf/HashCountedSet.h"
#include "sky/engine/wtf/HashSet.h"
#include "sky/engine/wtf/OwnPtr.h"
#include "sky/engine/wtf/text/WTFString.h"
// FIXME(crbug.com/352043): This is temporarily enabled even on RELEASE to diagnose a wild crash.
#define ENABLE_RESOURCE_IS_DELETED_CHECK
namespace blink {
struct FetchInitiatorInfo;
class MemoryCache;
class ResourceClient;
class ResourcePtrBase;
class ResourceFetcher;
class InspectorResource;
class ResourceLoader;
class SharedBuffer;
// A resource that is held in the cache. Classes who want to use this object should derive
// from ResourceClient, to get the function calls in case the requested data has arrived.
// This class also does the actual communication with the loader to obtain the resource from the network.
class Resource {
WTF_MAKE_NONCOPYABLE(Resource); WTF_MAKE_FAST_ALLOCATED;
friend class InspectorResource;
public:
enum Type {
MainResource,
Image,
Font,
Raw,
LinkPrefetch,
LinkSubresource,
ImportResource,
Media // Audio or video file requested by a HTML5 media element
};
enum Status {
Unknown, // let cache decide what to do with it
Pending, // only partially loaded
Cached, // regular case
LoadError,
DecodeError
};
Resource(const ResourceRequest&, Type);
#if ENABLE(OILPAN)
virtual ~Resource();
#else
protected:
// Only deleteIfPossible should delete this.
virtual ~Resource();
public:
#endif
virtual void dispose();
static unsigned instanceCount() { return s_instanceCount; }
virtual void load(ResourceFetcher*, const ResourceLoaderOptions&);
virtual void setEncoding(const String&) { }
virtual String encoding() const { return String(); }
virtual void appendData(const char*, int);
virtual void error(Resource::Status);
void setNeedsSynchronousCacheHit(bool needsSynchronousCacheHit) { m_needsSynchronousCacheHit = needsSynchronousCacheHit; }
void setResourceError(const ResourceError& error) { m_error = error; }
const ResourceError& resourceError() const { return m_error; }
void setIdentifier(unsigned long identifier) { m_identifier = identifier; }
unsigned long identifier() const { return m_identifier; }
virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return false; }
ResourceRequest& mutableResourceRequest() { return m_resourceRequest; }
const ResourceRequest& resourceRequest() const { return m_resourceRequest; }
const KURL& url() const { return m_resourceRequest.url();}
Type type() const { return static_cast<Type>(m_type); }
const ResourceLoaderOptions& options() const { return m_options; }
void setOptions(const ResourceLoaderOptions& options) { m_options = options; }
void didChangePriority(ResourceLoadPriority, int intraPriorityValue);
void addClient(ResourceClient*);
void removeClient(ResourceClient*);
bool hasClients() const { return !m_clients.isEmpty() || !m_clientsAwaitingCallback.isEmpty(); }
bool deleteIfPossible();
virtual void didAddClient(ResourceClient*);
virtual void didRemoveClient(ResourceClient*) { }
virtual void allClientsRemoved();
unsigned count() const { return m_clients.size(); }
Status status() const { return static_cast<Status>(m_status); }
void setStatus(Status status) { m_status = status; }
size_t size() const { return encodedSize() + decodedSize() + overheadSize(); }
size_t encodedSize() const { return m_encodedSize; }
size_t decodedSize() const { return m_decodedSize; }
size_t overheadSize() const;
bool isLoaded() const { return !m_loading; } // FIXME. Method name is inaccurate. Loading might not have started yet.
bool isLoading() const { return m_loading; }
void setLoading(bool b) { m_loading = b; }
virtual bool stillNeedsLoad() const { return false; }
ResourceLoader* loader() const { return m_loader.get(); }
virtual bool isImage() const { return false; }
bool ignoreForRequestCount() const
{
return type() == MainResource
|| type() == LinkPrefetch
|| type() == LinkSubresource
|| type() == Media
|| type() == Raw;
}
// Computes the status of an object after loading.
// Updates the expire date on the cache entry file
void finish(double finishTime = 0.0);
void clearLoader();
SharedBuffer* resourceBuffer() const { return m_data.get(); }
void setResourceBuffer(PassRefPtr<SharedBuffer>);
virtual void willSendRequest(ResourceRequest&, const ResourceResponse&);
virtual void updateRequest(const ResourceRequest&) { }
virtual void responseReceived(const ResourceResponse&);
void setResponse(const ResourceResponse& response) { m_response = response; }
const ResourceResponse& response() const { return m_response; }
bool hasOneHandle() const;
bool canDelete() const;
// List of acceptable MIME types separated by ",".
// A MIME type may contain a wildcard, e.g. "text/*".
AtomicString accept() const { return m_accept; }
void setAccept(const AtomicString& accept) { m_accept = accept; }
bool wasCanceled() const { return m_error.isCancellation(); }
bool errorOccurred() const { return m_status == LoadError || m_status == DecodeError; }
bool loadFailedOrCanceled() { return !m_error.isNull(); }
DataBufferingPolicy dataBufferingPolicy() const { return m_options.dataBufferingPolicy; }
void setDataBufferingPolicy(DataBufferingPolicy);
void registerHandle(ResourcePtrBase* h);
void unregisterHandle(ResourcePtrBase* h);
bool mustRevalidateDueToCacheHeaders();
bool canUseCacheValidator();
bool isCacheValidator() const { return m_resourceToRevalidate; }
Resource* resourceToRevalidate() const { return m_resourceToRevalidate; }
void setResourceToRevalidate(Resource*);
bool hasCacheControlNoStoreHeader();
bool isPurgeable() const;
bool wasPurged() const;
bool lock();
virtual void didSendData(unsigned long long /* bytesSent */, unsigned long long /* totalBytesToBeSent */) { }
virtual void didDownloadData(int) { }
double loadFinishTime() const { return m_loadFinishTime; }
virtual bool canReuse(const ResourceRequest&) const { return true; }
// Used by the MemoryCache to reduce the memory consumption of the entry.
void prune();
static const char* resourceTypeToString(Type, const FetchInitiatorInfo&);
#ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
void assertAlive() const { RELEASE_ASSERT(!m_deleted); }
#else
void assertAlive() const { }
#endif
protected:
virtual void checkNotify();
virtual void finishOnePart();
// Normal resource pointers will silently switch what Resource* they reference when we
// successfully revalidated the resource. We need a way to guarantee that the Resource
// that received the 304 response survives long enough to switch everything over to the
// revalidatedresource. The normal mechanisms for keeping a Resource alive externally
// (ResourcePtrs and ResourceClients registering themselves) don't work in this case, so
// have a separate internal protector).
class InternalResourcePtr {
public:
explicit InternalResourcePtr(Resource* resource)
: m_resource(resource)
{
m_resource->incrementProtectorCount();
}
~InternalResourcePtr()
{
m_resource->decrementProtectorCount();
m_resource->deleteIfPossible();
}
private:
Resource* m_resource;
};
void incrementProtectorCount() { m_protectorCount++; }
void decrementProtectorCount() { m_protectorCount--; }
void setEncodedSize(size_t);
void setDecodedSize(size_t);
void didAccessDecodedData();
virtual void switchClientsToRevalidatedResource();
void clearResourceToRevalidate();
void updateResponseAfterRevalidation(const ResourceResponse& validatingResponse);
void finishPendingClients();
HashCountedSet<ResourceClient*> m_clients;
HashCountedSet<ResourceClient*> m_clientsAwaitingCallback;
class ResourceCallback {
public:
static ResourceCallback* callbackHandler();
void schedule(Resource*);
void cancel(Resource*);
bool isScheduled(Resource*) const;
private:
ResourceCallback();
void timerFired(Timer<ResourceCallback>*);
Timer<ResourceCallback> m_callbackTimer;
HashSet<Resource*> m_resourcesWithPendingClients;
};
bool hasClient(ResourceClient* client) { return m_clients.contains(client) || m_clientsAwaitingCallback.contains(client); }
virtual bool isSafeToUnlock() const { return false; }
virtual void destroyDecodedDataIfPossible() { }
ResourceRequest m_resourceRequest;
AtomicString m_accept;
RefPtr<ResourceLoader> m_loader;
ResourceLoaderOptions m_options;
ResourceResponse m_response;
double m_responseTimestamp;
RefPtr<SharedBuffer> m_data;
Timer<Resource> m_cancelTimer;
private:
bool addClientToSet(ResourceClient*);
void cancelTimerFired(Timer<Resource>*);
void revalidationSucceeded(const ResourceResponse&);
void revalidationFailed();
bool unlock();
bool hasRightHandleCountApartFromCache(unsigned targetCount) const;
void failBeforeStarting();
String m_fragmentIdentifierForRequest;
ResourceError m_error;
double m_loadFinishTime;
unsigned long m_identifier;
size_t m_encodedSize;
size_t m_decodedSize;
unsigned m_handleCount;
unsigned m_protectorCount;
unsigned m_requestedFromNetworkingLayer : 1;
unsigned m_loading : 1;
unsigned m_switchingClientsToRevalidatedResource : 1;
unsigned m_type : 4; // Type
unsigned m_status : 3; // Status
unsigned m_wasPurged : 1;
unsigned m_needsSynchronousCacheHit : 1;
#ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
bool m_deleted;
#endif
// If this field is non-null we are using the resource as a proxy for checking whether an existing resource is still up to date
// using HTTP If-Modified-Since/If-None-Match headers. If the response is 304 all clients of this resource are moved
// to to be clients of m_resourceToRevalidate and the resource is deleted. If not, the field is zeroed and this
// resources becomes normal resource load.
RawPtr<Resource> m_resourceToRevalidate;
// If this field is non-null, the resource has a proxy for checking whether it is still up to date (see m_resourceToRevalidate).
RawPtr<Resource> m_proxyResource;
// These handles will need to be updated to point to the m_resourceToRevalidate in case we get 304 response.
HashSet<ResourcePtrBase*> m_handlesToRevalidate;
static unsigned s_instanceCount;
};
#if !LOG_DISABLED
// Intended to be used in LOG statements.
const char* ResourceTypeName(Resource::Type);
#endif
#define DEFINE_RESOURCE_TYPE_CASTS(typeName) \
DEFINE_TYPE_CASTS(typeName##Resource, Resource, resource, resource->type() == Resource::typeName, resource.type() == Resource::typeName); \
inline typeName##Resource* to##typeName##Resource(const ResourcePtr<Resource>& ptr) { return to##typeName##Resource(ptr.get()); }
}
#endif