Tizen 2.1 base
[platform/upstream/gcd.git] / kqueue-1.0.4 / src / linux / eventfd.c
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/eventfd.h>
22 #include <unistd.h>
23
24 #include "private.h"
25
26 /* A structure is used to allow other targets to emulate this */
27 struct eventfd {
28     int fd;
29 };
30
31 struct eventfd *
32 eventfd_create(void)
33 {
34     struct eventfd *e;
35     int evfd;
36
37     e = malloc(sizeof(*e));
38     if (e == NULL)
39         return (NULL);
40
41     if ((evfd = eventfd(0, 0)) < 0) {
42         free(e);
43         return (NULL);
44     }
45     if (fcntl(evfd, F_SETFL, O_NONBLOCK) < 0) {
46         free(e);
47         close(evfd);
48         return (NULL);
49     }
50     e->fd = evfd;
51
52     return (e);
53 }
54
55 void
56 eventfd_free(struct eventfd *e)
57 {
58     close(e->fd);
59     free(e);
60 }
61
62 int
63 eventfd_raise(struct eventfd *e)
64 {
65     uint64_t counter;
66     int rv = 0;
67
68     dbg_puts("raising event level");
69     counter = 1;
70     if (write(e->fd, &counter, sizeof(counter)) < 0) {
71         switch (errno) {
72             case EAGAIN:    
73                 /* Not considered an error */
74                 break;
75
76             case EINTR:
77                 rv = -EINTR;
78                 break;
79
80             default:
81                 dbg_printf("write(2): %s", strerror(errno));
82                 rv = -1;
83         }
84     }
85     return (rv);
86 }
87
88 int
89 eventfd_lower(struct eventfd *e)
90 {
91     uint64_t cur;
92     int rv = 0;
93
94     /* Reset the counter */
95     dbg_puts("lowering event level");
96     if (read(e->fd, &cur, sizeof(cur)) < sizeof(cur)) {
97         switch (errno) {
98             case EAGAIN:    
99                 /* Not considered an error */
100                 break;
101
102             case EINTR:
103                 rv = -EINTR;
104                 break;
105
106             default:
107                 dbg_printf("read(2): %s", strerror(errno));
108                 rv = -1;
109         }
110     } 
111
112     return (rv);
113 }
114
115 int
116 eventfd_reader(struct eventfd *e)
117 {
118     return (e->fd);
119 }
120
121 int
122 eventfd_writer(struct eventfd *e)
123 {
124     return (e->fd);
125 }