lighttpd 1.4.x https://www.lighttpd.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
2.3 KiB

#include "first.h"
#include "mod_magnet_cache.h"
#include "log.h"
#include "stat_cache.h"
#include "sys-time.h"
#include <stdlib.h>
#include <lualib.h>
#include <lauxlib.h>
__attribute_cold__
static script *script_init(void)
{
script *const sc = calloc(1, sizeof(*sc));
force_assert(sc);
return sc;
}
__attribute_cold__
static void script_free(script *sc)
{
if (!sc) return;
lua_pop(sc->L, 1); /* the function copy */
lua_close(sc->L);
free(sc->name.ptr);
free(sc->etag.ptr);
free(sc);
}
#if 0
script_cache *script_cache_init(void)
{
script_cache *p = calloc(1, sizeof(script_cache));
force_assert(p);
return p;
}
#endif
void script_cache_free_data(script_cache *p)
{
if (!p) return;
for (uint32_t i = 0; i < p->used; ++i)
script_free(p->ptr[i]);
free(p->ptr);
}
lua_State *script_cache_get_script(script_cache *cache, const buffer *name, int etag_flags)
{
script *sc = NULL;
stat_cache_entry *sce;
for (uint32_t i = 0; i < cache->used; ++i, sc = NULL) {
sc = cache->ptr[i];
if (!buffer_is_equal(name, &sc->name)) continue;
if (lua_gettop(sc->L) == 0) break;
force_assert(lua_gettop(sc->L) == 1);
sce = stat_cache_get_entry(&sc->name);
if (NULL == sce) {
lua_pop(sc->L, 1); /* pop the old function */
break;
}
const buffer *etag = stat_cache_etag_get(sce, etag_flags);
if (NULL == etag || !buffer_is_equal(&sc->etag, etag)) {
/* the etag is outdated, reload the function */
lua_pop(sc->L, 1);
break;
}
force_assert(lua_isfunction(sc->L, -1));
return sc->L;
}
/* if the script was script already loaded but either got changed or
* failed to load last time */
if (sc == NULL) {
sc = script_init();
if (cache->used == cache->size) {
cache->size += 16;
cache->ptr = realloc(cache->ptr, cache->size * sizeof(*(cache->ptr)));
}
cache->ptr[cache->used++] = sc;
buffer_copy_buffer(&sc->name, name);
sc->L = luaL_newstate();
luaL_openlibs(sc->L);
}
buffer_clear(&sc->etag);
if (0 != luaL_loadfile(sc->L, name->ptr)) {
/* oops, an error, return it */
return sc->L;
}
sce = stat_cache_get_entry(&sc->name);
if (sce) {
[multiple] reduce redundant NULL buffer checks This commit is a large set of code changes and results in removal of hundreds, perhaps thousands, of CPU instructions, a portion of which are on hot code paths. Most (buffer *) used by lighttpd are not NULL, especially since buffers were inlined into numerous larger structs such as request_st and chunk. In the small number of instances where that is not the case, a NULL check is often performed earlier in a function where that buffer is later used with a buffer_* func. In the handful of cases that remained, a NULL check was added, e.g. with r->http_host and r->conf.server_tag. - check for empty strings at config time and set value to NULL if blank string will be ignored at runtime; at runtime, simple pointer check for NULL can be used to check for a value that has been set and is not blank ("") - use buffer_is_blank() instead of buffer_string_is_empty(), and use buffer_is_unset() instead of buffer_is_empty(), where buffer is known not to be NULL so that NULL check can be skipped - use buffer_clen() instead of buffer_string_length() when buffer is known not to be NULL (to avoid NULL check at runtime) - use buffer_truncate() instead of buffer_string_set_length() to truncate string, and use buffer_extend() to extend Examples where buffer known not to be NULL: - cpv->v.b from config_plugin_values_init is not NULL if T_CONFIG_BOOL (though we might set it to NULL if buffer_is_blank(cpv->v.b)) - address of buffer is arg (&foo) (compiler optimizer detects this in most, but not all, cases) - buffer is checked for NULL earlier in func - buffer is accessed in same scope without a NULL check (e.g. b->ptr) internal behavior change: callers must not pass a NULL buffer to some funcs. - buffer_init_buffer() requires non-null args - buffer_copy_buffer() requires non-null args - buffer_append_string_buffer() requires non-null args - buffer_string_space() requires non-null arg
11 months ago
const buffer *etag = stat_cache_etag_get(sce, etag_flags);
if (etag)
buffer_copy_buffer(&sc->etag, etag);
}
force_assert(lua_isfunction(sc->L, -1));
return sc->L;
}