1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
/* timerfd FDs */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/timerfd.h>
#include "fd.h"
#include "files.h"
#include "objects.h"
#include "random.h"
#include "sanitise.h"
#include "shm.h"
#include "compat.h"
static void timerfd_destructor(struct object *obj)
{
close(obj->timerfdobj.fd);
}
static void timerfd_dump(struct object *obj, bool global)
{
struct timerfdobj *to = &obj->timerfdobj;
output(2, "timerfd fd:%d clockid:%d flags:%x global:%d\n", to->fd, to->clockid, to->flags, global);
}
static int __open_timerfd_fds(int clockid)
{
struct objhead *head;
unsigned int i;
unsigned int flags[] = {
0,
TFD_NONBLOCK,
TFD_CLOEXEC,
TFD_NONBLOCK | TFD_CLOEXEC,
};
head = get_objhead(OBJ_GLOBAL, OBJ_FD_TIMERFD);
head->destroy = &timerfd_destructor;
head->dump = &timerfd_dump;
for (i = 0; i < ARRAY_SIZE(flags); i++) {
struct object *obj;
int fd;
fd = timerfd_create(clockid, flags[i]);
if (fd == -1)
if (errno == ENOSYS)
return FALSE;
obj = alloc_object();
obj->timerfdobj.fd = fd;
obj->timerfdobj.clockid = clockid;
obj->timerfdobj.flags = flags[i];
add_object(obj, OBJ_GLOBAL, OBJ_FD_TIMERFD);
}
return TRUE;
}
static int open_timerfd_fds(void)
{
int ret;
ret = __open_timerfd_fds(CLOCK_REALTIME);
if (ret != FALSE)
ret = __open_timerfd_fds(CLOCK_MONOTONIC);
return ret;
}
static int get_rand_timerfd_fd(void)
{
struct object *obj;
/* check if timerfd unavailable/disabled. */
if (objects_empty(OBJ_FD_TIMERFD) == TRUE)
return -1;
obj = get_random_object(OBJ_FD_TIMERFD, OBJ_GLOBAL);
return obj->timerfdobj.fd;
}
static const struct fd_provider timerfd_fd_provider = {
.name = "timerfd",
.enabled = TRUE,
.open = &open_timerfd_fds,
.get = &get_rand_timerfd_fd,
};
REG_FD_PROV(timerfd_fd_provider);
|