Make news item merging deterministic and safe for year 2038
News reporting merges news items into recent items with same contents. For that purpuse, we keep a small cache of recent items. When a new item can't be merged into an item in the cache, the oldest item gets evicted to make space for the new one. ncache() evicts the first item with the smallest timestamp (struct nwsstr member nws_when). Timestamps are in seconds, therefore clashes are common, and eviction depends on exact timing. Such indeterminism can make the smoke test fail. Moreover, ncache() assumes timestamps cannot exceed 0x7fffffff. If they do, it always evicts the slot 0. They will in 2038. Fix by evicting round robin. This always evicts the oldest item.
This commit is contained in:
parent
e9fdc200e4
commit
5738e399c4
1 changed files with 8 additions and 11 deletions
|
@ -30,7 +30,7 @@
|
||||||
* Dave Pare, 1994
|
* Dave Pare, 1994
|
||||||
* Steve McClure, 1997
|
* Steve McClure, 1997
|
||||||
* Ron Koenderink, 2005
|
* Ron Koenderink, 2005
|
||||||
* Markus Armbruster, 2004-2011
|
* Markus Armbruster, 2004-2012
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
@ -49,6 +49,7 @@ struct newscache {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct newscache cache[MAXNOC][SLOTS];
|
static struct newscache cache[MAXNOC][SLOTS];
|
||||||
|
static unsigned char cache_oldest[MAXNOC];
|
||||||
static int news_tail;
|
static int news_tail;
|
||||||
|
|
||||||
static struct newscache *
|
static struct newscache *
|
||||||
|
@ -157,18 +158,12 @@ ncache(int actor, int event, int victim, int times)
|
||||||
{
|
{
|
||||||
struct newscache *np;
|
struct newscache *np;
|
||||||
int i;
|
int i;
|
||||||
int oldslot;
|
unsigned oldslot;
|
||||||
time_t oldtime, dur;
|
time_t dur;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
||||||
oldslot = -1;
|
|
||||||
oldtime = 0x7fffffff;
|
|
||||||
for (i = 0; i < SLOTS; i++) {
|
for (i = 0; i < SLOTS; i++) {
|
||||||
np = &cache[actor][i];
|
np = &cache[actor][i];
|
||||||
if (np->news.nws_when < oldtime) {
|
|
||||||
oldslot = i;
|
|
||||||
oldtime = np->news.nws_when;
|
|
||||||
}
|
|
||||||
if (np->news.nws_vrb == 0)
|
if (np->news.nws_vrb == 0)
|
||||||
continue;
|
continue;
|
||||||
dur = now - np->news.nws_when;
|
dur = now - np->news.nws_when;
|
||||||
|
@ -181,11 +176,13 @@ ncache(int actor, int event, int victim, int times)
|
||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CANT_HAPPEN(oldslot < 0))
|
|
||||||
oldslot = 0;
|
|
||||||
if (CANT_HAPPEN(!strstr(rpt[event].r_newstory[0], "%s") && victim != 0))
|
if (CANT_HAPPEN(!strstr(rpt[event].r_newstory[0], "%s") && victim != 0))
|
||||||
victim = 0;
|
victim = 0;
|
||||||
|
oldslot = cache_oldest[actor];
|
||||||
|
if (CANT_HAPPEN(oldslot >= SLOTS))
|
||||||
|
oldslot = 0;
|
||||||
np = &cache[actor][oldslot];
|
np = &cache[actor][oldslot];
|
||||||
|
cache_oldest[actor] = (oldslot + 1) % SLOTS;
|
||||||
ef_blank(EF_NEWS, news_tail, &np->news);
|
ef_blank(EF_NEWS, news_tail, &np->news);
|
||||||
np->news.nws_ano = actor;
|
np->news.nws_ano = actor;
|
||||||
np->news.nws_vrb = event;
|
np->news.nws_vrb = event;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue