EVFILT_TIMER just broken
EVFILT_TIMER just broken
- Subject: EVFILT_TIMER just broken
- From: Godfrey van der Linden <email@hidden>
- Date: Thu, 11 Mar 2010 22:15:55 +1100
I've now explored every variant I can think of for using kevent with EVFILT_TIMER. If I read kevent(2) properly the default implementation for the TIMER is to set a repeating timeout that can fire every ident timeperiods and delivers a EVFILT_TIMER event.
Yet only ever get one hit, immediately and the event never fires again. Is this a documentation problem or am I missing something?
Here is the code that demonstrates the problem, not that it never returns after the initial immediate and incorrect kevents.
I'm running a vanilla x86_64 macbook pro with 10.6.2.
Please help, this problem has been screwing me over for the last week.
Godfrey
/*
gcc -std=c99 -Wall -Wextra -Werror -g -o kevent_timer kevent_timer.c
*/
#include <sys/cdefs.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdbool.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/event.h>
#define kLongTimer_ms (1000)
#define kShortTimer_ms ( 10)
static struct timeval sStart;
static int sKQ;
static void
logKEvent(const struct kevent64_s *kep, int ind, const char * const pfx);
int main(int argc __unused, char *argv[] __unused)
{
sKQ = kqueue();
gettimeofday(&sStart, NULL);
uintptr_t nch = 0;
struct kevent64_s timers[2];
EV_SET64(&timers[nch], kLongTimer_ms,
EVFILT_TIMER, EV_ADD, 0, 0, nch, 0, 0); nch++;
EV_SET64(&timers[nch], kShortTimer_ms,
EVFILT_TIMER, EV_ADD, 0, 0, nch, 0, 0); nch++;
struct kevent64_s *chList = timers;
bool seenLong = false, seenShort = false;
do
{
struct kevent64_s evList[2];
bzero(evList, sizeof(evList));
for (int i = 0; i < (int) nch; i++)
logKEvent(&chList[i], i, "change");
int nev = kevent64(sKQ, chList, nch, evList, 2, 0, NULL);
chList = NULL; nch = 0;
for (int i = 0; i < nev; i++)
{
struct kevent64_s *kevp = &evList[i];
logKEvent(kevp, i, "kev");
assert(kevp->filter == EVFILT_TIMER);
if (kevp->udata == 0)
seenLong = true;
else if (kevp->udata == 1)
seenShort = true;
else
assert(false);
};
if (seenLong && seenShort && !(timers[0].flags & EV_CLEAR))
{
seenLong = seenShort = false;
chList = timers; nch = sizeof(timers)/sizeof(timers[0]);
for (int i = 0; i < (int) nch; i++)
chList[i].flags = EV_ADD|EV_CLEAR;
};
} while ( true );
// } while ( !seenLong || !seenShort );
}
static void
logKEvent(const struct kevent64_s *kep, int ind, const char * const pfx)
{
static const char *sFilterNames[] = {
"EVNULL", "EVFILT_READ", "EVFILT_WRITE", "EVFILT_AIO",
"EVFILT_VNODE", "EVFILT_PROC", "EVFILT_SIGNAL", "EVFILT_TIMER",
"EVFILT_MACHPORT", "EVFILT_FS", "EVFILT_USER", "EVFILT_SESSION"
};
// 1 2 3 4 5 6 7
// 12345678901234567890123456789012345678901234567890123456789012345678901234567
// ADD|DELETE|ENABLE|DISABLE|ONESHOT|CLEAR|RECEIPT|DISPATCH|BAD0x0100|BAD0x0200|
// 8 9 10 11
// 890123456789012345678901234567890123456789
// BAD0x0400|BAD0x0800|FLAG1|FLAG2|ERROR|EOF0
#define kMaxFlagCharacters 119
static const char *sFlagNames[] = {
"ADD", "DELETE", "ENABLE", "DISABLE",
"ONESHOT", "CLEAR", "RECEIPT", "DISPATCH",
"BAD0x0100", "BAD0x0200", "BAD0x0400", "BAD0x0800",
"FLAG1", "FLAG2", "ERROR", "EOF"
};
char flagBuffer[kMaxFlagCharacters], *cp = flagBuffer;
int cc;
#define kNumFilterNames (sizeof(sFilterNames)/sizeof(sFilterNames[0]))
#define kNumFlagNames (sizeof(sFlagNames) /sizeof(sFlagNames[0]))
#define kNumFlagChars (sizeof(flagBuffer) /sizeof(flagBuffer[0]))
cp[0] = '\0';
for (size_t i = 0; i < kNumFlagNames; i++)
{
cc = 0;
if ( kep->flags & (1 << i) )
cc = sprintf(cp, "%s|", sFlagNames[i]);
cp += cc;
}
cp[-1] = '\0'; // Overwrite trailing |
assert(cp < &flagBuffer[kNumFlagChars]);
unsigned filter = - kep->filter; assert(filter < kNumFilterNames);
struct timeval delta; gettimeofday(&delta, NULL);
timersub(&delta, &sStart, &delta);
fprintf(stderr, "%7ldus: %s[%d] = { %lld, %s, %s, %x, %lld }\n",
delta.tv_sec * 1000 * 1000 + delta.tv_usec,
pfx, ind, kep->ident, sFilterNames[filter], flagBuffer,
kep->fflags, kep->data);
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden