亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? cache.c

?? 一個(gè)很有名的瀏覽器
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* Cache subsystem *//* $Id: cache.c,v 1.194.2.4 2005/05/02 21:14:03 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "elinks.h"#include "bfu/dialog.h"#include "cache/cache.h"#include "cache/dialogs.h"#include "config/options.h"#include "main.h"#include "protocol/protocol.h"#include "protocol/proxy.h"#include "protocol/uri.h"#include "sched/connection.h"#include "util/error.h"#include "util/memory.h"#include "util/object.h"#include "util/string.h"#include "util/types.h"/* The list of cache entries */static INIT_LIST_HEAD(cache_entries);static long cache_size;static int id_counter = 1;/* Change 0 to 1 to enable cache debugging features (redirect stderr to a file). */#if 0#define DEBUG_CACHE#endif#ifdef DEBUG_CACHE#define dump_frag(frag, count) \do { \	DBG(" [%d] f=%p offset=%li length=%li real_length=%li", \	      count, frag, frag->offset, frag->length, frag->real_length); \} while (0)#define dump_frags(entry, comment) \do { \	struct fragment *frag; \        int count = 0;	\ \	DBG("%s: url=%s, cache_size=%li", comment, entry->url, cache_size); \	foreach (frag, entry->frag) \		dump_frag(frag, ++count); \} while (0)#else#define dump_frags(entry, comment)#endif /* DEBUG_CACHE */static intis_entry_used(struct cache_entry *cached){	struct connection *conn;	foreach (conn, queue)		if (conn->cached == cached)			return 1;	return 0;}longcache_info(int type){	int i = 0;	struct cache_entry *cached;	switch (type) {		case INFO_BYTES:			return cache_size;		case INFO_FILES:			foreach (cached, cache_entries) i++;			return i;		case INFO_LOCKED:			foreach (cached, cache_entries)				i += is_object_used(cached);			return i;		case INFO_LOADING:			foreach (cached, cache_entries)				i += is_entry_used(cached);			return i;	}	return 0;}struct cache_entry *find_in_cache(struct uri *uri){	struct cache_entry *cached;	int proxy = (uri->protocol == PROTOCOL_PROXY);	foreach (cached, cache_entries) {		struct uri *c_uri;		if (!cached->valid) continue;		c_uri = proxy ? cached->proxy_uri : cached->uri;		if (!compare_uri(c_uri, uri, URI_BASE))			continue;		/* Move it on the top of the list. */		del_from_list(cached);		add_to_list(cache_entries, cached);		return cached;	}	return NULL;}struct cache_entry *get_cache_entry(struct uri *uri){	struct cache_entry *cached = find_in_cache(uri);	assertm(!uri->fragment, "Fragment in URI (%s)", struri(uri));	if (cached) return cached;	shrink_memory(0);	cached = mem_calloc(1, sizeof(*cached));	if (!cached) return NULL;	cached->uri = get_proxied_uri(uri);	if (!cached->uri) {		mem_free(cached);		return NULL;	}	cached->proxy_uri = get_proxy_uri(uri, NULL);	if (!cached->proxy_uri) {		done_uri(cached->uri);		mem_free(cached);		return NULL;	}	cached->incomplete = 1;	cached->valid = 1;	init_list(cached->frag);	cached->id = id_counter++;	object_nolock(cached, "cache_entry"); /* Debugging purpose. */	add_to_list(cache_entries, cached);	cached->box_item = add_listbox_leaf(&cache_browser, NULL, cached);	return cached;}static intcache_entry_has_expired(struct cache_entry *cached){	return cached->max_age <= time(NULL);}struct cache_entry *get_validated_cache_entry(struct uri *uri, enum cache_mode cache_mode){	struct cache_entry *cached;	/* We have to check if something should be reloaded */	if (cache_mode > CACHE_MODE_NORMAL)		return NULL;	/* We only consider complete entries */	cached = find_in_cache(uri);	if (!cached || cached->incomplete)		return NULL;	/* Check if the entry can be deleted */	/* FIXME: This does not make sense to me. Why should the usage pattern	 * of the cache entry matter? Only reason I can think of is to avoid	 * reloading when spawning a new tab which could potentially be a big	 * penalty but shouldn't that be taken care of on a higher level?	 * --jonas */	if (is_object_used(cached)) {#if 0		/* Never use expired entries. */		if (cached->expire && cache_entry_has_expired(cached))			return NULL;#endif		return cached;	}	/* A bit of a gray zone. Delete the entry if the it has the stricktest	 * cache mode and we don't want the most aggressive mode or we have to	 * remove the redirect or the entry expired. Please enlighten me.	 * --jonas */	if ((cached->cache_mode == CACHE_MODE_NEVER && cache_mode != CACHE_MODE_ALWAYS)	    || (cached->redirect && !get_opt_bool("document.cache.cache_redirects"))	    || (cached->expire && cache_entry_has_expired(cached))) {		delete_cache_entry(cached);		return NULL;	}	return cached;}intcache_entry_is_valid(struct cache_entry *cached){	struct cache_entry *valid_cached;	foreach (valid_cached, cache_entries) {		if (valid_cached == cached)			return 1;	}	return 0;}struct cache_entry *follow_cached_redirects(struct cache_entry *cached){	int redirects = 0;	while (cached) {		if (!cached->redirect) {			/* XXX: This is not quite true, but does that difference			 * matter here? */			return cached;		}		if (++redirects > MAX_REDIRECTS) break;		cached = find_in_cache(cached->redirect);	}	return NULL;}struct cache_entry *get_redirected_cache_entry(struct uri *uri){	struct cache_entry *cached = find_in_cache(uri);	return cached ? follow_cached_redirects(cached) : NULL;}static inline voidenlarge_entry(struct cache_entry *cached, int size){	cached->data_size += size;	assertm(cached->data_size >= 0,		"cache entry data_size underflow: %ld", cached->data_size);	if_assert_failed { cached->data_size = 0; }	cache_size += size;	assertm(cache_size >= 0, "cache_size underflow: %ld", cache_size);	if_assert_failed { cache_size = 0; }}#define CACHE_PAD(x) (((x) | 0x3fff) + 1)/* One byte is reserved for data in struct fragment. */#define FRAGSIZE(x) (sizeof(struct fragment) + (x) - 1)/* We store the fragments themselves in a private vault, safely separated from * the rest of memory structures. If we lived in the main libc memory pool, we * would trigger annoying pathological behaviour like artificially enlarging * the memory pool to 50M, then securing it with some stupid cookie record at * the top and then no matter how you flush the cache the data segment is still * 50M big. * * Cool, but we don't want that, so fragments (where the big data is stored) * live in their little mmap()ed worlds. There is some overhead, but if we * assume single fragment per cache entry and page size (mmap() allocation * granularity) 4096, for a squad of ten 1kb documents this amounts 30kb. * That's not *that* horrible when you realize that the freshmeat front page * takes 300kb in memory and we usually do not deal with documents so small * that max. 4kb overhead would be visible there. * * The alternative would be of course to manage an entire custom memory pool, * but that is feasible only when we are able to resize it efficiently. We * aren't, except on Linux. * * Of course for all this to really completely prevent the pathological cases, * we need to stuff the rendered documents in too, because they seem to amount * the major memory bursts. */static struct fragment *frag_alloc(size_t size){	struct fragment *f = mem_mmap_alloc(FRAGSIZE(size));	if (!f) return NULL;	memset(f, 0, FRAGSIZE(size));	return f;}static struct fragment *frag_realloc(struct fragment *f, size_t size){	return mem_mmap_realloc(f, FRAGSIZE(f->real_length), FRAGSIZE(size));}static voidfrag_free(struct fragment *f){	mem_mmap_free(f, FRAGSIZE(f->real_length));}/* Contatenate overlapping fragments. */static voidremove_overlaps(struct cache_entry *cached, struct fragment *f, int *trunc){	int f_end_offset = f->offset + f->length;	/* Iterate thru all fragments we still overlap to. */	while (list_has_next(cached->frag, f)		&& f_end_offset > f->next->offset) {		struct fragment *nf;		int end_offset = f->next->offset + f->next->length;		if (f_end_offset < end_offset) {			/* We end before end of the following fragment, though.			 * So try to append overlapping part of that fragment			 * to us. */			nf = frag_realloc(f, end_offset - f->offset);			if (nf) {				nf->prev->next = nf;				nf->next->prev = nf;				f = nf;				if (memcmp(f->data + f->next->offset - f->offset,					   f->next->data,					   f->offset + f->length - f->next->offset))					*trunc = 1;				memcpy(f->data + f->length,				       f->next->data + f_end_offset - f->next->offset,				       end_offset - f_end_offset);				enlarge_entry(cached, end_offset - f_end_offset);				f->length = f->real_length = end_offset - f->offset;			}		} else {			/* We will just discard this, it's complete subset of			 * our new fragment. */			if (memcmp(f->data + f->next->offset - f->offset,				   f->next->data,				   f->next->length))				*trunc = 1;		}		/* Remove the fragment, it influences our new one! */		nf = f->next;		enlarge_entry(cached, -nf->length);		del_from_list(nf);		frag_free(nf);	}}/* Note that this function is maybe overcommented, but I'm certainly not * unhappy from that. */intadd_fragment(struct cache_entry *cached, int offset,	     unsigned char *data, int length){	struct fragment *f, *nf;	int trunc = 0;	int end_offset;	if (!length) return 0;	end_offset = offset + length;	if (cached->length < end_offset)		cached->length = end_offset;	/* id marks each entry, and change each time it's modified,	 * used in HTML renderer. */	cached->id = id_counter++;	/* Possibly insert the new data in the middle of existing fragment. */	foreach (f, cached->frag) {		int ret = 0;		int f_end_offset = f->offset + f->length;		/* No intersection? */		if (f->offset > offset) break;		if (f_end_offset < offset) continue;		if (end_offset > f_end_offset) {			/* Overlap - we end further than original fragment. */			if (end_offset - f->offset <= f->real_length) {				/* We fit here, so let's enlarge it by delta of				 * old and new end.. */				enlarge_entry(cached, end_offset - f_end_offset);				/* ..and length is now total length. */				f->length = end_offset - f->offset;				ret = 1; /* It was enlarged. */			} else {				/* We will reduce fragment length only to the				 * starting non-interjecting size and add new				 * fragment directly after this one. */				f->length = offset - f->offset;				f = f->next;				break;			}		} /* else We are subset of original fragment. */		/* Copy the stuff over there. */		memcpy(f->data + offset - f->offset, data, length);		remove_overlaps(cached, f, &trunc);		/* We truncate the entry even if the data contents is the		 * same as what we have in the fragment, because that does		 * not mean that what is going to follow won't differ, This		 * is a serious problem when rendering HTML frame with onload		 * snippets - we "guess" the rest of the document here,		 * interpret the snippet, then it turns out in the real		 * document the snippet is different and we are in trouble.		 *		 * Debugging this took me about 1.5 day (really), the diff with

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品全国免费观看高清 | 亚洲视频图片小说| 精品国产乱码久久久久久蜜臀| 欧亚一区二区三区| 成人在线综合网站| 成人av网站在线观看免费| 久久99国产精品麻豆| 日本欧美韩国一区三区| 免费日韩伦理电影| 国产一区二区三区在线观看免费视频 | 678五月天丁香亚洲综合网| 欧美日韩国产经典色站一区二区三区 | 92国产精品观看| 色婷婷激情综合| 91精品欧美久久久久久动漫| 在线不卡欧美精品一区二区三区| 7777女厕盗摄久久久| 精品电影一区二区| 中文字幕精品综合| 亚洲精品国产精品乱码不99| 午夜精品久久久久久久久久 | 色香蕉成人二区免费| 欧美日韩专区在线| 欧美va亚洲va香蕉在线| 欧美激情资源网| 一个色综合av| 青青国产91久久久久久| 国产精品羞羞答答xxdd| 色久优优欧美色久优优| 欧美成人精品3d动漫h| 欧美国产成人精品| 亚洲国产精品尤物yw在线观看| 强制捆绑调教一区二区| 成年人网站91| 91精品国产美女浴室洗澡无遮挡| 久久久亚洲精华液精华液精华液| 亚洲免费观看高清完整版在线观看熊 | 亚洲成国产人片在线观看| 国产毛片精品一区| 色94色欧美sute亚洲线路二| 日韩欧美成人一区| 一区二区三区久久| 国产精品一区专区| 这里是久久伊人| 亚洲欧美激情一区二区| 蜜桃视频在线观看一区| 91福利小视频| 国产精品沙发午睡系列990531| 日韩精品一级中文字幕精品视频免费观看 | 丝袜国产日韩另类美女| 99精品国产91久久久久久| 精品国产乱子伦一区| 亚洲国产综合视频在线观看| 高清shemale亚洲人妖| 欧美一级久久久久久久大片| 成人免费在线播放视频| 久久狠狠亚洲综合| 欧美日韩精品系列| 一区二区三区日韩| 丁香婷婷综合五月| www久久精品| 免费久久精品视频| 制服.丝袜.亚洲.另类.中文| 一区二区视频在线看| 不卡电影一区二区三区| 欧美激情中文不卡| 国产成人在线看| 精品久久久久久无| 免费高清成人在线| 欧美一区二区视频在线观看| 亚洲最大成人综合| 在线观看日韩电影| 亚洲人精品一区| 91亚洲永久精品| 亚洲精品乱码久久久久久黑人 | 一区二区在线观看av| 一道本成人在线| 亚洲欧美日韩久久| 99精品久久只有精品| 亚洲欧美激情插| 欧美性极品少妇| 午夜影院在线观看欧美| 7777精品伊人久久久大香线蕉最新版 | 国产喂奶挤奶一区二区三区| 国产在线不卡一卡二卡三卡四卡| 精品久久国产字幕高潮| 国产剧情av麻豆香蕉精品| 亚洲国产精品成人综合色在线婷婷| 国产一区二区按摩在线观看| 国产女同互慰高潮91漫画| 成人sese在线| 亚洲国产裸拍裸体视频在线观看乱了 | 自拍偷拍国产亚洲| 91视频免费观看| 一区二区三区精品| 欧美大胆一级视频| av在线综合网| 日韩电影免费在线看| 欧美一级爆毛片| 不卡av免费在线观看| 一区二区三区在线免费视频| 欧美一区二区三区色| 成人性色生活片| 亚洲va欧美va人人爽午夜| 久久久久一区二区三区四区| 99国产精品久久久久久久久久| 亚洲成人av免费| 久久精品亚洲麻豆av一区二区| 色综合久久九月婷婷色综合| 乱中年女人伦av一区二区| 中文字幕乱码日本亚洲一区二区 | 亚洲图片欧美一区| 在线观看欧美精品| 天堂久久一区二区三区| 欧美一卡2卡三卡4卡5免费| 久久国产精品免费| 国产欧美日韩中文久久| 成人蜜臀av电影| 亚洲一区av在线| 欧美久久一二区| 精东粉嫩av免费一区二区三区| 亚洲欧美日韩国产成人精品影院| 久久九九全国免费| 99久久久无码国产精品| 美女网站色91| 精品国产乱码久久久久久夜甘婷婷| 琪琪一区二区三区| 国产日本亚洲高清| 国产91精品一区二区| 一区在线中文字幕| 日韩无一区二区| 99久久精品国产网站| a级精品国产片在线观看| 午夜精品久久久久久久久久久 | 午夜精品久久久久久久久| 中文字幕免费一区| 欧美日韩国产一二三| 老色鬼精品视频在线观看播放| 亚洲国产成人porn| 久久影视一区二区| 亚洲精品一区在线观看| 欧美在线你懂得| 99精品热视频| 国产美女主播视频一区| 免费高清在线一区| 亚洲一区免费观看| 亚洲一区二区三区在线看| 久久久亚洲午夜电影| 欧美一级生活片| 欧美日韩亚洲综合在线| 久久99这里只有精品| 久久精品国产色蜜蜜麻豆| 国产精品丝袜在线| 国产精品高潮呻吟久久| 精品理论电影在线| 亚洲国产精品v| 欧美mv日韩mv国产网站| 久久久精品综合| 日韩女优av电影| 9191国产精品| 色狠狠桃花综合| 91视视频在线直接观看在线看网页在线看| 国产欧美日韩卡一| 久久精品免费在线观看| 国产一区二区0| 精品一区二区三区久久| 一区二区国产视频| 日本伊人色综合网| 亚洲国产成人av网| 精品一区二区三区免费| 五月婷婷激情综合网| 韩国三级在线一区| 久久精品久久99精品久久| 国产91富婆露脸刺激对白| 国产一二三精品| 色婷婷综合久久久中文字幕| 成人高清免费观看| 欧美精品一卡两卡| 欧美日韩国产天堂| 国产三级精品三级| 久久九九影视网| 亚洲丰满少妇videoshd| 亚洲最新视频在线观看| 国内精品免费在线观看| 国产在线视频一区二区| 色88888久久久久久影院野外| 色综合天天综合给合国产| 欧美一区二区三区小说| 69精品人人人人| 亚洲欧美二区三区| 亚洲风情在线资源站| 成人在线一区二区三区| 国产酒店精品激情| www.日韩精品| 欧美在线影院一区二区| 在线观看区一区二| 在线一区二区三区四区五区| 欧美精品aⅴ在线视频| 正在播放亚洲一区| 国产精品久久久久久久久免费樱桃|