ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev_epoll.c
(Generate patch)

Comparing libev/ev_epoll.c (file contents):
Revision 1.35 by root, Thu Oct 23 04:56:49 2008 UTC vs.
Revision 1.36 by root, Mon Oct 27 11:08:29 2008 UTC

83 return; 83 return;
84 84
85 oldmask = anfds [fd].emask; 85 oldmask = anfds [fd].emask;
86 anfds [fd].emask = nev; 86 anfds [fd].emask = nev;
87 87
88 ev.data.u64 = fd; /* use u64 to fully initialise the struct, for nicer strace etc. */ 88 /* store the generation counter in the upper 32 bits */
89 ev.data.u64 = fd | ((uint64_t)++anfds [fd].egen << 32);
89 ev.events = (nev & EV_READ ? EPOLLIN : 0) 90 ev.events = (nev & EV_READ ? EPOLLIN : 0)
90 | (nev & EV_WRITE ? EPOLLOUT : 0); 91 | (nev & EV_WRITE ? EPOLLOUT : 0);
91 92
92 if (expect_true (!epoll_ctl (backend_fd, oev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev))) 93 if (expect_true (!epoll_ctl (backend_fd, oev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev)))
93 return; 94 return;
94 95
95 if (expect_true (errno == ENOENT)) 96 if (expect_true (errno == ENOENT))
96 { 97 {
97 /* if ENOENT then the fd went away, so try to do the right thing */ 98 /* if ENOENT then the fd went away, so try to do the right thing */
98 if (!nev) 99 if (!nev)
99 return; 100 goto dec_egen;
100 101
101 if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev)) 102 if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev))
102 return; 103 return;
103 } 104 }
104 else if (expect_true (errno == EEXIST)) 105 else if (expect_true (errno == EEXIST))
105 { 106 {
106 /* EEXIST means we ignored a previous DEL, but the fd is still active */ 107 /* EEXIST means we ignored a previous DEL, but the fd is still active */
107 /* if the kernel mask is the same as the new mask, we assume it hasn't changed */ 108 /* if the kernel mask is the same as the new mask, we assume it hasn't changed */
109 if (oldmask == nev)
110 goto dec_egen;
111
108 if (oldmask == nev || !epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev)) 112 if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev))
109 return; 113 return;
110 } 114 }
111 115
112 fd_kill (EV_A_ fd); 116 fd_kill (EV_A_ fd);
117
118dec_egen:
119 /* we didn't successfully call epoll_ctl, so decrement the generation counter again */
120 --anfds [fd].egen;
113} 121}
114 122
115static void 123static void
116epoll_poll (EV_P_ ev_tstamp timeout) 124epoll_poll (EV_P_ ev_tstamp timeout)
117{ 125{
128 136
129 for (i = 0; i < eventcnt; ++i) 137 for (i = 0; i < eventcnt; ++i)
130 { 138 {
131 struct epoll_event *ev = epoll_events + i; 139 struct epoll_event *ev = epoll_events + i;
132 140
133 int fd = ev->data.u64; 141 int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */
134 int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0) 142 int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
135 | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0); 143 | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0);
136 int want = anfds [fd].events; 144 int want = anfds [fd].events;
145
146 if (anfds [fd].egen != (unsigned char)(ev->data.u64 >> 32))
147 /*fprintf (stderr, "spurious notification fd %d, %d vs %d\n", fd, (int)(ev->data.u64 >> 32), anfds [fd].egen);*/
148 continue;
137 149
138 if (expect_false (got & ~want)) 150 if (expect_false (got & ~want))
139 { 151 {
140 anfds [fd].emask = want; 152 anfds [fd].emask = want;
141 153

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines