Global: adds general cache layer

This commit is contained in:
李通洲
2026-09-21 22:46:40 +08:00
parent 2f74d6be4d
commit 7f3209181e
14 changed files with 728 additions and 207 deletions
+53
View File
@@ -0,0 +1,53 @@
#include "common/FFcache.h"
// Entries are file scope statics owned by the cache owner, so they can be linked into a list
// without any allocation. The list holds every entry that has been used at least once: an entry
// that was never used has nothing to drop.
static FFcacheEntry* entries = nullptr;
static void registerEntry(FFcacheEntry* entry) {
if (entry->registered) {
return;
}
entry->registered = true;
entry->next = entries;
entries = entry;
}
void* ffCacheGet(FFcacheEntry* entry) {
if (ffCacheBeginInit(entry) && entry->init) {
entry->init(entry->storage);
}
return entry->storage;
}
bool ffCacheBeginInit(FFcacheEntry* entry) {
registerEntry(entry);
if (entry->initialized) {
return false;
}
entry->initialized = true;
return true;
}
void ffCacheInvalidate(FFcacheEntry* entry) {
if (!entry->initialized) {
return;
}
entry->initialized = false;
if (entry->destroy) {
entry->destroy(entry->storage);
}
}
void ffCacheInvalidateAll(void) {
for (FFcacheEntry* entry = entries; entry; entry = entry->next) {
ffCacheInvalidate(entry);
}
}
+39 -14
View File
@@ -1,22 +1,47 @@
#include "common/netif.h"
#include "common/FFcache.h"
#ifndef _WIN32
#include <net/if.h>
#include <netinet/in.h>
#endif
#include <string.h>
// netio, localip and dns resolve the default route on every round, and it can change while a
// `--dynamic-interval` run is going on: a laptop switching from Wi-Fi to Ethernet, a VPN coming up.
static FFNetifDefaultRouteResult defaultRouteV4;
static FFNetifDefaultRouteResult defaultRouteV6;
static void resetDefaultRoute(void* storage) {
// The impls only write the fields they found, so without this a round that finds no default
// route would keep reporting the interface of the previous one.
memset(storage, 0, sizeof(FFNetifDefaultRouteResult));
}
static void initDefaultRouteV4(void* storage) {
FFNetifDefaultRouteResult* result = storage;
result->status = ffNetifGetDefaultRouteImplV4(result) ? FF_NETIF_OK : FF_NETIF_INVALID;
}
static void initDefaultRouteV6(void* storage) {
FFNetifDefaultRouteResult* result = storage;
result->status = ffNetifGetDefaultRouteImplV6(result) ? FF_NETIF_OK : FF_NETIF_INVALID;
}
static FFcacheEntry ffCacheEntryDefaultRouteV4 = {
.name = "default route V4",
.storage = &defaultRouteV4,
.init = initDefaultRouteV4,
.destroy = resetDefaultRoute,
};
static FFcacheEntry ffCacheEntryDefaultRouteV6 = {
.name = "default route V6",
.storage = &defaultRouteV6,
.init = initDefaultRouteV6,
.destroy = resetDefaultRoute,
};
const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV4(void) {
static FFNetifDefaultRouteResult result;
if (result.status == FF_NETIF_UNINITIALIZED) {
result.status = ffNetifGetDefaultRouteImplV4(&result) ? FF_NETIF_OK : FF_NETIF_INVALID;
}
return &result;
return ffCacheGet(&ffCacheEntryDefaultRouteV4);
}
const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV6(void) {
static FFNetifDefaultRouteResult result;
if (result.status == FF_NETIF_UNINITIALIZED) {
result.status = ffNetifGetDefaultRouteImplV6(&result) ? FF_NETIF_OK : FF_NETIF_INVALID;
}
return &result;
return ffCacheGet(&ffCacheEntryDefaultRouteV6);
}