1/* 2 * Copyright (c) 2010 Mark Heily <mark@heily.com> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include <errno.h> 18#include <fcntl.h> 19#include <stdlib.h> 20#include <stdio.h> 21#include <sys/socket.h> 22#include <unistd.h> 23 24#include "private.h" 25 26struct eventfd { 27 int fd[2]; 28}; 29 30struct eventfd * 31eventfd_create(void) 32{ 33 struct eventfd *e; 34 35 e = malloc(sizeof(*e)); 36 if (e == NULL) 37 return (NULL); 38 39 if (socketpair(AF_UNIX, SOCK_STREAM, 0, e->fd) < 0) { 40 free(e); 41 return (NULL); 42 } 43 if ((fcntl(e->fd[0], F_SETFL, O_NONBLOCK) < 0) || 44 (fcntl(e->fd[1], F_SETFL, O_NONBLOCK) < 0)) { 45 free(e); 46 close(e->fd[0]); 47 close(e->fd[1]); 48 return (NULL); 49 } 50 51 return (e); 52} 53 54void 55eventfd_free(struct eventfd *e) 56{ 57 close(e->fd[0]); 58 close(e->fd[1]); 59 free(e); 60} 61 62int 63eventfd_raise(struct eventfd *e) 64{ 65 dbg_puts("raising event level"); 66 if (write(e->fd[0], ".", 1) < 0) { 67 /* FIXME: handle EAGAIN and EINTR */ 68 dbg_printf("write(2): %s", strerror(errno)); 69 return (-1); 70 } 71 return (0); 72} 73 74int 75eventfd_lower(struct eventfd *e) 76{ 77 char buf[1024]; 78 79 /* Reset the counter */ 80 dbg_puts("lowering event level"); 81 if (read(e->fd[1], &buf, sizeof(buf)) < 0) { 82 /* FIXME: handle EAGAIN and EINTR */ 83 /* FIXME: loop so as to consume all data.. may need mutex */ 84 dbg_printf("read(2): %s", strerror(errno)); 85 return (-1); 86 } 87 return (0); 88} 89 90int 91eventfd_reader(struct eventfd *e) 92{ 93 return (e->fd[1]); 94} 95 96int 97eventfd_writer(struct eventfd *e) 98{ 99 return (e->fd[0]); 100} 101