increase timer resolution to milliseconds
seconds are too coarse for what we intend. technically, centisecs would be sufficient (and more honest, given that we prefer coarse timers, which have only tick precision), but that's a somewhat untypical unit.
This commit is contained in:
parent
8566283c59
commit
1867a7c5ea
|
@ -323,9 +323,11 @@ typedef struct {
|
||||||
list_head_t links;
|
list_head_t links;
|
||||||
void (*cb)( void *aux );
|
void (*cb)( void *aux );
|
||||||
void *aux;
|
void *aux;
|
||||||
time_t timeout;
|
int64_t timeout;
|
||||||
} wakeup_t;
|
} wakeup_t;
|
||||||
|
|
||||||
|
void init_timers( void );
|
||||||
|
int64_t get_now( void );
|
||||||
void init_wakeup( wakeup_t *tmr, void (*cb)( void * ), void *aux );
|
void init_wakeup( wakeup_t *tmr, void (*cb)( void * ), void *aux );
|
||||||
void conf_wakeup( wakeup_t *tmr, int timeout );
|
void conf_wakeup( wakeup_t *tmr, int timeout );
|
||||||
void wipe_wakeup( wakeup_t *tmr );
|
void wipe_wakeup( wakeup_t *tmr );
|
||||||
|
|
|
@ -3713,7 +3713,7 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
server->sconf.timeout = 20;
|
server->sconf.timeout = 20000;
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
server->ssl_type = -1;
|
server->ssl_type = -1;
|
||||||
server->sconf.ssl_versions = -1;
|
server->sconf.ssl_versions = -1;
|
||||||
|
@ -3761,7 +3761,7 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep )
|
||||||
server->sconf.port = (ushort)port;
|
server->sconf.port = (ushort)port;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp( "Timeout", cfg->cmd )) {
|
} else if (!strcasecmp( "Timeout", cfg->cmd )) {
|
||||||
server->sconf.timeout = parse_int( cfg );
|
server->sconf.timeout = parse_int( cfg ) * 1000;
|
||||||
} else if (!strcasecmp( "PipelineDepth", cfg->cmd )) {
|
} else if (!strcasecmp( "PipelineDepth", cfg->cmd )) {
|
||||||
if ((server->max_in_progress = parse_int( cfg )) < 1) {
|
if ((server->max_in_progress = parse_int( cfg )) < 1) {
|
||||||
error( "%s:%d: PipelineDepth must be at least 1\n", cfg->file, cfg->line );
|
error( "%s:%d: PipelineDepth must be at least 1\n", cfg->file, cfg->line );
|
||||||
|
|
|
@ -665,7 +665,7 @@ maildir_store_uidval( maildir_store_t *ctx )
|
||||||
return DRV_BOX_BAD;
|
return DRV_BOX_BAD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conf_wakeup( &ctx->lcktmr, 2 );
|
conf_wakeup( &ctx->lcktmr, 2000 );
|
||||||
return DRV_OK;
|
return DRV_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -761,7 +761,7 @@ maildir_uidval_lock( maildir_store_t *ctx )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx->uvok = 1;
|
ctx->uvok = 1;
|
||||||
conf_wakeup( &ctx->lcktmr, 2 );
|
conf_wakeup( &ctx->lcktmr, 2000 );
|
||||||
return DRV_OK;
|
return DRV_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,7 @@ main( int argc, char **argv )
|
||||||
int oind, cops = 0, op, ms_warn = 0, renew_warn = 0, delete_warn = 0;
|
int oind, cops = 0, op, ms_warn = 0, renew_warn = 0, delete_warn = 0;
|
||||||
|
|
||||||
tzset();
|
tzset();
|
||||||
|
init_timers();
|
||||||
gethostname( Hostname, sizeof(Hostname) );
|
gethostname( Hostname, sizeof(Hostname) );
|
||||||
if ((ochar = strchr( Hostname, '.' )))
|
if ((ochar = strchr( Hostname, '.' )))
|
||||||
*ochar = 0;
|
*ochar = 0;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int id;
|
int id;
|
||||||
int first, other, morph_at, morph_to;
|
int first, other, morph_at, morph_to;
|
||||||
time_t start;
|
int64_t start;
|
||||||
wakeup_t timer;
|
wakeup_t timer;
|
||||||
wakeup_t morph_timer;
|
wakeup_t morph_timer;
|
||||||
} tst_t;
|
} tst_t;
|
||||||
|
@ -18,7 +18,7 @@ static void
|
||||||
timer_start( tst_t *timer, int to )
|
timer_start( tst_t *timer, int to )
|
||||||
{
|
{
|
||||||
printf( "starting timer %d, should expire after %d\n", timer->id, to );
|
printf( "starting timer %d, should expire after %d\n", timer->id, to );
|
||||||
time( &timer->start );
|
timer->start = get_now();
|
||||||
conf_wakeup( &timer->timer, to );
|
conf_wakeup( &timer->timer, to );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ timed_out( void *aux )
|
||||||
tst_t *timer = (tst_t *)aux;
|
tst_t *timer = (tst_t *)aux;
|
||||||
|
|
||||||
printf( "timer %d expired after %d, repeat %d\n",
|
printf( "timer %d expired after %d, repeat %d\n",
|
||||||
timer->id, (int)(time( 0 ) - timer->start), timer->other );
|
timer->id, (int)(get_now() - timer->start), timer->other );
|
||||||
if (timer->other >= 0) {
|
if (timer->other >= 0) {
|
||||||
timer_start( timer, timer->other );
|
timer_start( timer, timer->other );
|
||||||
} else {
|
} else {
|
||||||
|
@ -44,7 +44,7 @@ morph_timed_out( void *aux )
|
||||||
tst_t *timer = (tst_t *)aux;
|
tst_t *timer = (tst_t *)aux;
|
||||||
|
|
||||||
printf( "morphing timer %d after %d\n",
|
printf( "morphing timer %d after %d\n",
|
||||||
timer->id, (int)(time( 0 ) - timer->start) );
|
timer->id, (int)(get_now() - timer->start) );
|
||||||
timer_start( timer, timer->morph_to );
|
timer_start( timer, timer->morph_to );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
init_timers();
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
char *val = argv[i];
|
char *val = argv[i];
|
||||||
tst_t *timer = nfmalloc( sizeof(*timer) );
|
tst_t *timer = nfmalloc( sizeof(*timer) );
|
||||||
|
|
48
src/util.c
48
src/util.c
|
@ -12,6 +12,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
int Verbosity = TERSE;
|
int Verbosity = TERSE;
|
||||||
int DFlags;
|
int DFlags;
|
||||||
|
@ -1000,10 +1001,41 @@ wipe_notifier( notifier_t *sn )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static time_t
|
#if _POSIX_TIMERS - 0 > 0
|
||||||
|
static clockid_t clkid;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
init_timers( void )
|
||||||
|
{
|
||||||
|
#if _POSIX_TIMERS - 0 > 0
|
||||||
|
struct timespec ts;
|
||||||
|
# ifdef CLOCK_BOOTTIME
|
||||||
|
if (!clock_gettime( CLOCK_BOOTTIME, &ts )) {
|
||||||
|
clkid = CLOCK_BOOTTIME;
|
||||||
|
} else
|
||||||
|
# endif
|
||||||
|
# ifdef CLOCK_MONOTONIC_COARSE
|
||||||
|
if (!clock_gettime( CLOCK_MONOTONIC_COARSE, &ts )) {
|
||||||
|
clkid = CLOCK_MONOTONIC_COARSE;
|
||||||
|
} else
|
||||||
|
# endif
|
||||||
|
clkid = CLOCK_MONOTONIC;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
get_now( void )
|
get_now( void )
|
||||||
{
|
{
|
||||||
return time( NULL );
|
#if _POSIX_TIMERS - 0 > 0
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime( clkid, &ts );
|
||||||
|
return ts.tv_sec * 1000LL + ts.tv_nsec / 1000000;
|
||||||
|
#else
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday( &tv, NULL );
|
||||||
|
return tv.tv_sec * 1000LL + tv.tv_usec / 1000;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static list_head_t timers = { &timers, &timers };
|
static list_head_t timers = { &timers, &timers };
|
||||||
|
@ -1032,7 +1064,7 @@ conf_wakeup( wakeup_t *tmr, int to )
|
||||||
if (tmr->links.next)
|
if (tmr->links.next)
|
||||||
list_unlink( &tmr->links );
|
list_unlink( &tmr->links );
|
||||||
} else {
|
} else {
|
||||||
time_t timeout = to;
|
int64_t timeout = to;
|
||||||
if (!to) {
|
if (!to) {
|
||||||
/* We always prepend null timers, to cluster related events. */
|
/* We always prepend null timers, to cluster related events. */
|
||||||
succ = timers.next;
|
succ = timers.next;
|
||||||
|
@ -1066,13 +1098,13 @@ event_wait( void )
|
||||||
int timeout = -1;
|
int timeout = -1;
|
||||||
if ((head = timers.next) != &timers) {
|
if ((head = timers.next) != &timers) {
|
||||||
wakeup_t *tmr = (wakeup_t *)head;
|
wakeup_t *tmr = (wakeup_t *)head;
|
||||||
time_t delta = tmr->timeout;
|
int64_t delta = tmr->timeout;
|
||||||
if (!delta || (delta -= get_now()) <= 0) {
|
if (!delta || (delta -= get_now()) <= 0) {
|
||||||
list_unlink( head );
|
list_unlink( head );
|
||||||
tmr->cb( tmr->aux );
|
tmr->cb( tmr->aux );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timeout = (int)delta * 1000;
|
timeout = (int)delta;
|
||||||
}
|
}
|
||||||
switch (poll( pollfds, npolls, timeout )) {
|
switch (poll( pollfds, npolls, timeout )) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -1102,14 +1134,14 @@ event_wait( void )
|
||||||
|
|
||||||
if ((head = timers.next) != &timers) {
|
if ((head = timers.next) != &timers) {
|
||||||
wakeup_t *tmr = (wakeup_t *)head;
|
wakeup_t *tmr = (wakeup_t *)head;
|
||||||
time_t delta = tmr->timeout;
|
int64_t delta = tmr->timeout;
|
||||||
if (!delta || (delta -= get_now()) <= 0) {
|
if (!delta || (delta -= get_now()) <= 0) {
|
||||||
list_unlink( head );
|
list_unlink( head );
|
||||||
tmr->cb( tmr->aux );
|
tmr->cb( tmr->aux );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
to_tv.tv_sec = delta;
|
to_tv.tv_sec = delta / 1000;
|
||||||
to_tv.tv_usec = 0;
|
to_tv.tv_usec = delta * 1000;
|
||||||
timeout = &to_tv;
|
timeout = &to_tv;
|
||||||
}
|
}
|
||||||
FD_ZERO( &rfds );
|
FD_ZERO( &rfds );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user