~ubuntu-branches/ubuntu/vivid/nodejs/vivid

« back to all changes in this revision

Viewing changes to deps/uv/src/unix/linux-core.c

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-11-13 23:17:51 UTC
  • mfrom: (1.1.29)
  • mto: This revision was merged to the branch mainline in revision 33.
  • Revision ID: package-import@ubuntu.com-20131113231751-m6uqywp5dc4s4fxo
Tags: 0.10.22~dfsg1-1
* Upstream update. 
* Refresh patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
97
97
}
98
98
 
99
99
 
 
100
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
 
101
  struct uv__epoll_event* events;
 
102
  uintptr_t i;
 
103
  uintptr_t nfds;
 
104
 
 
105
  assert(loop->watchers != NULL);
 
106
 
 
107
  events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers];
 
108
  nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
 
109
  if (events == NULL)
 
110
    return;
 
111
 
 
112
  /* Invalidate events with same file descriptor */
 
113
  for (i = 0; i < nfds; i++)
 
114
    if ((int) events[i].data == fd)
 
115
      events[i].data = -1;
 
116
}
 
117
 
 
118
 
100
119
void uv__io_poll(uv_loop_t* loop, int timeout) {
101
120
  struct uv__epoll_event events[1024];
102
121
  struct uv__epoll_event* pe;
189
208
 
190
209
    nevents = 0;
191
210
 
 
211
    assert(loop->watchers != NULL);
 
212
    loop->watchers[loop->nwatchers] = (void*) events;
 
213
    loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
192
214
    for (i = 0; i < nfds; i++) {
193
215
      pe = events + i;
194
216
      fd = pe->data;
195
217
 
 
218
      /* Skip invalidated events, see uv__platform_invalidate_fd */
 
219
      if (fd == -1)
 
220
        continue;
 
221
 
196
222
      assert(fd >= 0);
197
223
      assert((unsigned) fd < loop->nwatchers);
198
224
 
208
234
        continue;
209
235
      }
210
236
 
211
 
      w->cb(loop, w, pe->events);
212
 
      nevents++;
 
237
      /* Give users only events they're interested in. Prevents spurious
 
238
       * callbacks when previous callback invocation in this loop has stopped
 
239
       * the current watcher. Also, filters out events that users has not
 
240
       * requested us to watch.
 
241
       */
 
242
      pe->events &= w->pevents | UV__POLLERR | UV__POLLHUP;
 
243
 
 
244
      /* Work around an epoll quirk where it sometimes reports just the
 
245
       * EPOLLERR or EPOLLHUP event.  In order to force the event loop to
 
246
       * move forward, we merge in the read/write events that the watcher
 
247
       * is interested in; uv__read() and uv__write() will then deal with
 
248
       * the error or hangup in the usual fashion.
 
249
       *
 
250
       * Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user
 
251
       * reads the available data, calls uv_read_stop(), then sometime later
 
252
       * calls uv_read_start() again.  By then, libuv has forgotten about the
 
253
       * hangup and the kernel won't report EPOLLIN again because there's
 
254
       * nothing left to read.  If anything, libuv is to blame here.  The
 
255
       * current hack is just a quick bandaid; to properly fix it, libuv
 
256
       * needs to remember the error/hangup event.  We should get that for
 
257
       * free when we switch over to edge-triggered I/O.
 
258
       */
 
259
      if (pe->events == UV__EPOLLERR || pe->events == UV__EPOLLHUP)
 
260
        pe->events |= w->pevents & (UV__EPOLLIN | UV__EPOLLOUT);
 
261
 
 
262
      if (pe->events != 0) {
 
263
        w->cb(loop, w, pe->events);
 
264
        nevents++;
 
265
      }
213
266
    }
 
267
    loop->watchers[loop->nwatchers] = NULL;
 
268
    loop->watchers[loop->nwatchers + 1] = NULL;
214
269
 
215
270
    if (nevents != 0) {
216
271
      if (nfds == ARRAY_SIZE(events) && --count != 0) {