Skip to content

Instantly share code, notes, and snippets.

@voldyman
Last active December 29, 2019 22:48
Show Gist options
  • Save voldyman/a9284b1ee5fc2ff7234829f6e5ea160b to your computer and use it in GitHub Desktop.
Save voldyman/a9284b1ee5fc2ff7234829f6e5ea160b to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/timerfd.h>
typedef struct TimeEvent {
int fd;
char* message;
struct timespec added_time;
struct TimeEvent* next;
struct TimeEvent* prev;
} TimeEvent;
typedef struct EventList{
TimeEvent* head;
TimeEvent* tail;
} EventList;
TimeEvent* delete_event(EventList* list, TimeEvent* event) {
if (list->head == event) {
list->head = event->next;
}
if (list->tail == event) {
list->tail = event->prev;
}
if (event->prev != NULL) {
event->prev->next = event->next;
}
TimeEvent* next = event->next;
free(event->message);
free(event);
return next;
}
EventList* create_list() {
return malloc(sizeof(EventList));
}
void delete_list(EventList* list) {
TimeEvent* iter = list->head;
while (iter != NULL) {
delete_event(list, iter);
}
free(list);
}
void add_event(EventList* list, int fd, char* message) {
TimeEvent* ev = (TimeEvent*) malloc(sizeof(TimeEvent));
ev->fd = fd;
ev->message = strdup(message);
ev->next = NULL;
ev->prev = list->tail;
clock_gettime(CLOCK_REALTIME, &ev->added_time);
TimeEvent* old_tail = list->tail;
list->tail = ev;
if (old_tail == NULL) {
list->head = list->tail;
} else {
old_tail->next = ev;
}
}
void print_time(struct timespec time) {
struct tm std_time;
localtime_r(&(time.tv_sec), &std_time);
char output[200];
int n = strftime(output, sizeof(output), "%F %T", &std_time);
fprintf(stdout, "%.*s\n", n, output);
fflush(stdout);
}
int main() {
fd_set rfds;
struct timeval tv;
int retval;
EventList* list = create_list();
while(1) {
FD_ZERO(&rfds);
FD_SET(0, &rfds);
int largest = 1;
TimeEvent* iter = list->head;
while (iter != NULL) {
FD_SET(iter->fd, &rfds);
if (iter->fd > largest) {
largest = iter->fd;
}
iter = iter->next;
}
if (select(1+largest, &rfds, NULL, NULL, &tv) < 0) {
perror("select()");
}
if (FD_ISSET(0, &rfds)) {
char line[512];
int n = read(0, line, 512);
if (n>0) {
line[n-1] = 0;
fprintf(stdout, "Added timer by the name of: %.*s\n", n-1, line);
fflush(stdout);
struct itimerspec alerttime;
alerttime.it_value.tv_sec = 2;
alerttime.it_value.tv_nsec = 0;
alerttime.it_interval.tv_sec = 0; // no interval
alerttime.it_interval.tv_sec = 0; // no interval
int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
if (fd < 0) {
perror("timerfd");
}
timerfd_settime(fd, 0, &alerttime, 0);
add_event(list, fd, line);
}
}
iter = list->head;
while (iter != NULL) {
if (FD_ISSET(iter->fd, &rfds)) {
fprintf(stdout, "%s: timer triggered, added at: ", iter->message);
print_time(iter->added_time);
close(iter->fd);
iter = delete_event(list, iter);
continue;
}
iter = iter->next;
}
}
delete_list(list);
exit(EXIT_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment