Last active
December 29, 2019 22:48
-
-
Save voldyman/a9284b1ee5fc2ff7234829f6e5ea160b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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