Adjust the llcache behaviour to use scheduler for user notification.

This change updates the llcache to use the scheduler to notify users of the
llcache of events.  This should be just as safe as before and is part of an
effort to remove hlcache_poll and llcache_poll eventually because fetchers
should schedule themselves if need-be.

This is a big change despite the diminutive nature of the patch.  Please report
issues promptly if they turn up after this and are not visible before it.

Signed-off-by: Daniel Silverstone <dsilvers@netsurf-browser.org>
Reviewed-by: Vincent Sanders <vince@netsurf-browser.org>
This commit is contained in:
Daniel Silverstone 2014-06-03 17:00:23 +01:00
parent d96e805428
commit b5461c8313
1 changed files with 44 additions and 3 deletions

View File

@ -215,6 +215,8 @@ struct llcache_s {
/** The maximum bandwidth to allow the backing store to use. */
size_t bandwidth;
/** Whether or not our users are caught up */
bool all_caught_up;
};
/** low level cache state */
@ -222,6 +224,8 @@ static struct llcache_s *llcache = NULL;
/* forward referenced callback function */
static void llcache_fetch_callback(const fetch_msg *msg, void *p);
/* forward referenced catch up function */
static void llcache_users_not_caught_up(void);
/******************************************************************************
@ -2465,6 +2469,9 @@ static void llcache_fetch_callback(const fetch_msg *msg, void *p)
object->fetch.state = LLCACHE_FETCH_COMPLETE;
}
}
/* There may be users which are not caught up so schedule ourselves */
llcache_users_not_caught_up();
}
/**
@ -2628,6 +2635,7 @@ static nserror llcache_object_notify_users(llcache_object *object)
* reemit the event next time round */
user->iterator_target = false;
next_user = user->next;
llcache_users_not_caught_up();
continue;
} else if (error != NSERROR_OK) {
user->iterator_target = false;
@ -2681,6 +2689,7 @@ static nserror llcache_object_notify_users(llcache_object *object)
* reemit the data next time round */
user->iterator_target = false;
next_user = user->next;
llcache_users_not_caught_up();
continue;
} else if (error != NSERROR_OK) {
user->iterator_target = false;
@ -2714,6 +2723,7 @@ static nserror llcache_object_notify_users(llcache_object *object)
* reemit the event next time round */
user->iterator_target = false;
next_user = user->next;
llcache_users_not_caught_up();
continue;
} else if (error != NSERROR_OK) {
user->iterator_target = false;
@ -3013,6 +3023,7 @@ llcache_initialise(const struct llcache_parameters *prm)
llcache->limit = prm->limit;
llcache->minimum_lifetime = prm->minimum_lifetime;
llcache->bandwidth = prm->bandwidth;
llcache->all_caught_up = true;
LOG(("llcache initialising with a limit of %d bytes", llcache->limit));
@ -3076,10 +3087,26 @@ void llcache_finalise(void)
/* See llcache.h for documentation */
nserror llcache_poll(void)
{
fetch_poll();
return NSERROR_OK;
}
/**
* Catch up the cache users with state changes from fetchers.
*
* \param ignored We ignore this because all our state comes from llcache.
*/
static void llcache_catch_up_all_users(void *ignored)
{
llcache_object *object;
fetch_poll();
/* Assume after this we'll be all caught up. If any user of a handle
* defers then we'll end up set not caught up and we'll
* reschedule at that point via llcache_users_not_caught_up()
*/
llcache->all_caught_up = true;
/* Catch new users up with state of objects */
for (object = llcache->cached_objects; object != NULL;
@ -3091,10 +3118,21 @@ nserror llcache_poll(void)
object = object->next) {
llcache_object_notify_users(object);
}
return NSERROR_OK;
}
/**
* Ask for ::llcache_catch_up_all_users to be scheduled ASAP to pump the
* user state machines.
*/
static void llcache_users_not_caught_up()
{
if (llcache->all_caught_up) {
llcache->all_caught_up = false;
guit->browser->schedule(0, llcache_catch_up_all_users, NULL);
}
}
/* See llcache.h for documentation */
nserror llcache_handle_retrieve(nsurl *url, uint32_t flags,
nsurl *referer, const llcache_post_data *post,
@ -3127,6 +3165,9 @@ nserror llcache_handle_retrieve(nsurl *url, uint32_t flags,
*result = user->handle;
/* Users exist which are now not caught up! */
llcache_users_not_caught_up();
return NSERROR_OK;
}