summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cache.c6
-rw-r--r--src/cache.h1
-rw-r--r--src/dicache.c73
-rw-r--r--src/dicache.h6
-rw-r--r--src/gif.c7
-rw-r--r--src/html.cc6
-rw-r--r--src/html_common.hh1
-rw-r--r--src/imgbuf.cc3
-rw-r--r--src/jpeg.c5
-rw-r--r--src/nav.c3
-rw-r--r--src/png.c12
11 files changed, 67 insertions, 56 deletions
diff --git a/src/cache.c b/src/cache.c
index 831ad411..c1bdcec1 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -161,6 +161,7 @@ static int Cache_client_enqueue(const DilloUrl *Url, DilloWeb *Web,
ClientKey = Cache_client_make_key();
NewClient->Key = ClientKey;
NewClient->Url = Url;
+ NewClient->Version = 0;
NewClient->Buf = NULL;
NewClient->Callback = Callback;
NewClient->CbData = CbData;
@@ -1258,9 +1259,14 @@ CacheClient_t *a_Cache_client_get_if_unique(int Key)
void a_Cache_stop_client(int Key)
{
CacheClient_t *Client;
+ DICacheEntry *DicEntry;
if ((Client = dList_find_custom(ClientQueue, INT2VOIDP(Key),
Cache_client_by_key_cmp))) {
+ DicEntry = a_Dicache_get_entry(Client->Url, Client->Version);
+ if (DicEntry) {
+ a_Dicache_unref(Client->Url, Client->Version);
+ }
Cache_client_dequeue(Client, NULLKey);
} else {
_MSG("WARNING: Cache_stop_client, nonexistent client\n");
diff --git a/src/cache.h b/src/cache.h
index 6099447c..bb30d9a0 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -46,6 +46,7 @@ typedef void (*CA_Callback_t)(int Op, CacheClient_t *Client);
struct _CacheClient {
int Key; /* Primary Key for this client */
const DilloUrl *Url; /* Pointer to a cache entry Url */
+ int Version; /* Dicache version of this Url (0 if not used) */
void *Buf; /* Pointer to cache-data */
uint_t BufSize; /* Valid size of cache-data */
CA_Callback_t Callback; /* Client function */
diff --git a/src/dicache.c b/src/dicache.c
index 5dc0080f..9a34544e 100644
--- a/src/dicache.c
+++ b/src/dicache.c
@@ -87,7 +87,7 @@ static DICacheEntry *Dicache_entry_new(void)
entry->ScanNumber = 0;
entry->BitVec = NULL;
entry->State = DIC_Empty;
- entry->version = 0;
+ entry->version = 1;
entry->Decoder = NULL;
entry->DecoderData = NULL;
@@ -133,41 +133,31 @@ DICacheEntry *a_Dicache_add_entry(const DilloUrl *Url)
}
/*
- * Search an entry in the dicache (given the Url).
- * Return value: a pointer to the entry of the _newest_ (i.e. highest)
- * version if found; NULL otherwise.
- */
-DICacheEntry *a_Dicache_get_entry(const DilloUrl *Url)
-{
- DICacheNode *node;
- DICacheEntry *entry;
-
- node = dList_find_sorted(CachedIMGs, Url, Dicache_node_by_url_cmp);
-
- if (!node || !node->valid)
- return NULL;
-
- for (entry = node->first; (entry && entry->next); entry = entry->next);
-
- return entry;
-}
-
-/*
* Search a particular version of a URL in the Dicache.
* Return value: a pointer to the entry if found; NULL otherwise.
+ *
+ * Notes: DIC_Last means last version of the image.
+ * version zero is not allowed.
*/
-static DICacheEntry *Dicache_get_entry_version(const DilloUrl *Url,
- int version)
+DICacheEntry *a_Dicache_get_entry(const DilloUrl *Url, int version)
{
DICacheNode *node;
- DICacheEntry *entry;
+ DICacheEntry *entry = NULL;
- node = dList_find_sorted(CachedIMGs, Url, Dicache_node_by_url_cmp);
- entry = (node) ? node->first : NULL;
-
- while (entry && entry->version != version)
- entry = entry->next;
+ dReturn_val_if_fail(version != 0, NULL);
+ node = dList_find_sorted(CachedIMGs, Url, Dicache_node_by_url_cmp);
+ if (node) {
+ if (version == DIC_Last) {
+ if (node->valid) {
+ entry = node->first;
+ for ( ; (entry && entry->next); entry = entry->next);
+ }
+ } else {
+ entry = node->first;
+ for ( ; entry && entry->version != version; entry = entry->next) ;
+ }
+ }
return entry;
}
@@ -217,7 +207,7 @@ void a_Dicache_unref(const DilloUrl *Url, int version)
{
DICacheEntry *entry;
- if ((entry = Dicache_get_entry_version(Url, version))) {
+ if ((entry = a_Dicache_get_entry(Url, version))) {
if (--entry->RefCount == 0) {
Dicache_remove(Url, version);
}
@@ -231,7 +221,7 @@ DICacheEntry* a_Dicache_ref(const DilloUrl *Url, int version)
{
DICacheEntry *entry;
- if ((entry = Dicache_get_entry_version(Url, version))) {
+ if ((entry = a_Dicache_get_entry(Url, version))) {
++entry->RefCount;
}
return entry;
@@ -239,7 +229,8 @@ DICacheEntry* a_Dicache_ref(const DilloUrl *Url, int version)
/*
* Invalidate this entry. This is used for the reloading mechanism.
- * Can't erase current versions, but a_Dicache_get_entry must return NULL.
+ * Can't erase current versions, but a_Dicache_get_entry(url, DIC_Last)
+ * must return NULL.
*/
void a_Dicache_invalidate_entry(const DilloUrl *Url)
{
@@ -261,10 +252,14 @@ void a_Dicache_callback(int Op, CacheClient_t *Client)
uint_t i;
DilloWeb *Web = Client->Web;
DilloImage *Image = Web->Image;
- DICacheEntry *DicEntry = a_Dicache_get_entry(Web->url);
+ DICacheEntry *DicEntry = a_Dicache_get_entry(Web->url, DIC_Last);
dReturn_if_fail ( DicEntry != NULL );
+ /* Copy the version number in the Client */
+ if (Client->Version == 0)
+ Client->Version = DicEntry->version;
+
/* Only call the decoder when necessary */
if (Op == CA_Send && DicEntry->State < DIC_Close &&
DicEntry->DecodedSize < Client->BufSize) {
@@ -322,7 +317,7 @@ void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image,
MSG("a_Dicache_set_parms (%s)\n", URL_STR(url));
dReturn_if_fail ( Image != NULL && width && height );
/* Find the DicEntry for this Image */
- DicEntry = Dicache_get_entry_version(url, version);
+ DicEntry = a_Dicache_get_entry(url, version);
dReturn_if_fail ( DicEntry != NULL );
/* Parameters already set? */
dReturn_if_fail ( DicEntry->State < DIC_SetParms );
@@ -350,7 +345,7 @@ void a_Dicache_set_cmap(DilloUrl *url, int version, DilloImage *Image,
const uchar_t *cmap, uint_t num_colors,
int num_colors_max, int bg_index)
{
- DICacheEntry *DicEntry = Dicache_get_entry_version(url, version);
+ DICacheEntry *DicEntry = a_Dicache_get_entry(url, version);
dReturn_if_fail ( DicEntry != NULL );
@@ -375,7 +370,7 @@ void a_Dicache_new_scan(const DilloUrl *url, int version)
MSG("a_Dicache_new_scan\n");
dReturn_if_fail ( url != NULL );
- DicEntry = Dicache_get_entry_version(url, version);
+ DicEntry = a_Dicache_get_entry(url, version);
dReturn_if_fail ( DicEntry != NULL );
if (DicEntry->State < DIC_SetParms) {
MSG("a_Dicache_new_scan before DIC_SetParms\n");
@@ -398,7 +393,7 @@ void a_Dicache_write(DilloImage *Image, DilloUrl *url, int version,
_MSG("a_Dicache_write\n");
dReturn_if_fail ( Image != NULL );
- DicEntry = Dicache_get_entry_version(url, version);
+ DicEntry = a_Dicache_get_entry(url, version);
dReturn_if_fail ( DicEntry != NULL );
dReturn_if_fail ( DicEntry->width > 0 && DicEntry->height > 0 );
@@ -417,10 +412,10 @@ void a_Dicache_write(DilloImage *Image, DilloUrl *url, int version,
void a_Dicache_close(DilloUrl *url, int version, CacheClient_t *Client)
{
DilloWeb *Web = Client->Web;
- DICacheEntry *DicEntry = Dicache_get_entry_version(url, version);
+ DICacheEntry *DicEntry = a_Dicache_get_entry(url, version);
- MSG("a_Dicache_close RefCount=%d\n", DicEntry->RefCount);
dReturn_if_fail ( DicEntry != NULL );
+ MSG("a_Dicache_close RefCount=%d\n", DicEntry->RefCount);
DicEntry->State = DIC_Close;
dFree(DicEntry->cmap);
diff --git a/src/dicache.h b/src/dicache.h
index 4c4b93d6..51d67de2 100644
--- a/src/dicache.h
+++ b/src/dicache.h
@@ -10,6 +10,10 @@ extern "C" {
#include "image.hh"
#include "cache.h"
+/* Symbolic name to request the last version of an image */
+#define DIC_Last -1
+
+
/* These will reflect the entry's "state" */
typedef enum {
DIC_Empty, /* Just created the entry */
@@ -47,7 +51,7 @@ struct _DICacheEntry {
void a_Dicache_init (void);
-DICacheEntry *a_Dicache_get_entry(const DilloUrl *Url);
+DICacheEntry *a_Dicache_get_entry(const DilloUrl *Url, int version);
DICacheEntry *a_Dicache_add_entry(const DilloUrl *Url);
void a_Dicache_callback(int Op, CacheClient_t *Client);
diff --git a/src/gif.c b/src/gif.c
index 57506590..ea6990b3 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -157,7 +157,8 @@ void *a_Gif_image(const char *Type, void *Ptr, CA_Callback_t *Call,
/*
* MIME handler for "image/gif" type
- * (Sets Gif_callback as cache-client)
+ * Sets a_Dicache_callback as the cache-client,
+ * and Gif_callback as the image decoder.
*/
void *a_Gif_image(const char *Type, void *Ptr, CA_Callback_t *Call,
void **Data)
@@ -172,7 +173,7 @@ void *a_Gif_image(const char *Type, void *Ptr, CA_Callback_t *Call,
/* Add an extra reference to the Image (for dicache usage) */
a_Image_ref(web->Image);
- DicEntry = a_Dicache_get_entry(web->url);
+ DicEntry = a_Dicache_get_entry(web->url, DIC_Last);
if (!DicEntry) {
/* Let's create an entry for this image... */
DicEntry = a_Dicache_add_entry(web->url);
@@ -261,7 +262,7 @@ static void Gif_close(DilloGif *gif, CacheClient_t *Client)
{
int i;
- _MSG("destroy gif %p\n", gif);
+ MSG("Gif_close: destroy gif %p\n", gif);
a_Dicache_close(gif->url, gif->version, Client);
diff --git a/src/html.cc b/src/html.cc
index e3b961c5..6454d6df 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -467,7 +467,6 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url,
a_Misc_parse_content_type(content_type, NULL, NULL, &charset);
stop_parser = false;
- stop_parser_after_head = false;
repush_after_head = false;
CurrTagOfs = 0;
@@ -1607,10 +1606,10 @@ static void Html_tag_close_head(DilloHtml *html, int TagIdx)
html->InFlags &= ~IN_HEAD;
- if (html->stop_parser_after_head)
+ if (html->repush_after_head) {
html->stop_parser = true;
- if (html->repush_after_head)
a_Nav_repush(html->bw);
+ }
}
}
@@ -2937,7 +2936,6 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
* this code in another bw might have already changed it for us.
*/
if (a_Misc_content_type_cmp(html->content_type, new_content)) {
- html->stop_parser_after_head = true;
html->repush_after_head = true;
}
}
diff --git a/src/html_common.hh b/src/html_common.hh
index 4c6f40c5..fb470c27 100644
--- a/src/html_common.hh
+++ b/src/html_common.hh
@@ -172,7 +172,6 @@ public: //BUG: for now everything is public
char *content_type, *charset;
bool stop_parser;
- bool stop_parser_after_head;
bool repush_after_head;
size_t CurrTagOfs;
diff --git a/src/imgbuf.cc b/src/imgbuf.cc
index 26ccb059..ee8f918a 100644
--- a/src/imgbuf.cc
+++ b/src/imgbuf.cc
@@ -70,7 +70,8 @@ void a_Imgbuf_ref(void *v_imgbuf)
*/
void a_Imgbuf_unref(void *v_imgbuf)
{
- ((Imgbuf*)v_imgbuf)->unref();
+ if (v_imgbuf)
+ ((Imgbuf*)v_imgbuf)->unref();
}
/*
diff --git a/src/jpeg.c b/src/jpeg.c
index 8391227f..c495dbbe 100644
--- a/src/jpeg.c
+++ b/src/jpeg.c
@@ -103,7 +103,8 @@ METHODDEF(void) Jpeg_errorexit (j_common_ptr cinfo)
/*
* MIME handler for "image/jpeg" type
- * (Sets Jpeg_callback or a_Dicache_callback as the cache-client)
+ * Sets a_Dicache_callback as the cache-client,
+ * and Jpeg_callback as the image decoder.
*/
void *a_Jpeg_image(const char *Type, void *P, CA_Callback_t *Call,
void **Data)
@@ -117,7 +118,7 @@ void *a_Jpeg_image(const char *Type, void *P, CA_Callback_t *Call,
/* Add an extra reference to the Image (for dicache usage) */
a_Image_ref(web->Image);
- DicEntry = a_Dicache_get_entry(web->url);
+ DicEntry = a_Dicache_get_entry(web->url, DIC_Last);
if (!DicEntry) {
/* Let's create an entry for this image... */
DicEntry = a_Dicache_add_entry(web->url);
diff --git a/src/nav.c b/src/nav.c
index d6293143..ad8eb43b 100644
--- a/src/nav.c
+++ b/src/nav.c
@@ -378,6 +378,9 @@ static void Nav_repush_callback(void *data)
* Repush current URL: not an end-to-end reload but from cache.
* - Currently used to switch to a charset decoder given by the META element.
* - Delayed to let dillo finish the call flow into a known state.
+ *
+ * There's no need to stop the parser before calling this function:
+ * When the timeout activates, a_Bw_stop_clients will stop the data feed.
*/
void a_Nav_repush(BrowserWindow *bw)
{
diff --git a/src/png.c b/src/png.c
index dee8d5b4..989809e8 100644
--- a/src/png.c
+++ b/src/png.c
@@ -304,12 +304,13 @@ static void
*/
static void Png_close(DilloPng *png, CacheClient_t *Client)
{
- /* Free up the resources for this image */
+ /* Let dicache know decoding is over */
a_Dicache_close(png->url, png->version, Client);
+
+ /* Free up the resources for this image */
dFree(png->image_data);
dFree(png->row_pointers);
dFree(png->linebuf);
-
if (setjmp(png->jmpbuf))
MSG_WARN("PNG: can't destroy read structure\n");
else if (png->png_ptr)
@@ -444,8 +445,9 @@ static DilloPng *Png_new(DilloImage *Image, DilloUrl *url, int version)
}
/*
- * MIME handler for "image/png" type
- * (Sets Png_callback or a_Dicache_callback as the cache-client)
+ * MIME handler for "image/png" type.
+ * Sets a_Dicache_callback as the cache-client,
+ * and Png_callback as the image decoder.
*
* Parameters:
* Type: MIME type
@@ -465,7 +467,7 @@ void *a_Png_image(const char *Type, void *Ptr, CA_Callback_t *Call,
/* Add an extra reference to the Image (for dicache usage) */
a_Image_ref(web->Image);
- DicEntry = a_Dicache_get_entry(web->url);
+ DicEntry = a_Dicache_get_entry(web->url, DIC_Last);
if (!DicEntry) {
/* Let's create an entry for this image... */
DicEntry = a_Dicache_add_entry(web->url);