Andrew Klofas
Andrew Klofas

Reputation: 620

select()-able timers

select() is a great system call. You can pack any number of file descriptors, socket descriptors, pipes, etc. and get notified in a synchronous fashion when input becomes available.

Is there a way to create an interval/oneshot timer and use it with select()? That would save me from having multiple threads for IO and timing.

Upvotes: 11

Views: 5539

Answers (4)

Mike Mestnik
Mike Mestnik

Reputation: 323

Building on @MarkR, using a sorted structure to store callback+closure with an int and a pointer to an int. If the two ints have the same value then the event is active otherwise it was discarded.

This way events can be discarded simply by increasing an int. Perhaps not the most straightforward solution but it was all I could think of.

https://github.com/cheako/tor2web/tree/6ac67f80daaea01d14a5d07e6026e1af4258dc96/src

hextree.c contains the code for the data structure used.
schedule.c:156 is where the int is changed.
gnutls.c:197 is where the timers are created.

Upvotes: 0

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215287

MarkR has a nice portable solution, but here's another:

Use a POSIX timer (timer_create) and you can transform the problem into "select-able signals". This problem has a classic solution: writing to a pipe from the signal handler and selecting on the read end of the pipe.

Upvotes: 2

MarkR
MarkR

Reputation: 63548

Use the timeout parameter - keep your timer events in a priority queue, check the top item and set the timeout accordingly - if the timeout is reached, then you can check that the event is ready to run, run the event and continue.

At least that's what I do.

Note that poll has a nicer interface (in some ways) and may be more efficient with lots of file descriptors.

Upvotes: 7

nos
nos

Reputation: 229118

timerfd_create does exactly this. It's a fairly recent addition to the linux kernel and might not be available on all distros yet though.

Upvotes: 13

Related Questions