掩码的使用,还真得会:
- /*
- * Helper function to invoke port_associate for the given fd and mask.
- */
- static int aeApiAssociate(const char *where, int portfd, int fd, int mask) {
- int events = 0;
- int rv, err;
-
- if (mask & AE_READABLE)
- events |= POLLIN;
- if (mask & AE_WRITABLE)
- events |= POLLOUT;
-
- if (evport_debug)
- fprintf(stderr, "%s: port_associate(%d, 0x%x) = ", where, fd, events);
-
- rv = port_associate(portfd, PORT_SOURCE_FD, fd, events,
- (void *)(uintptr_t)mask);
- err = errno;
-
- if (evport_debug)
- fprintf(stderr, "%d (%s)\n", rv, rv == 0 ? "no error" : strerror(err));
-
- if (rv == -1) {
- fprintf(stderr, "%s: port_associate: %s\n", where, strerror(err));
-
- if (err == EAGAIN)
- fprintf(stderr, "aeApiAssociate: event port limit exceeded.");
- }
-
- return rv;
- }
-
- static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
- aeApiState *state = eventLoop->apidata;
- int fullmask, pfd;
-
- if (evport_debug)
- fprintf(stderr, "aeApiAddEvent: fd %d mask 0x%x\n", fd, mask);
-
- /*
- * Since port_associate's "events" argument replaces any existing events, we
- * must be sure to include whatever events are already associated when
- * we call port_associate() again.
- */
- fullmask = mask | eventLoop->events[fd].mask;
- pfd = aeApiLookupPending(state, fd);
-
- if (pfd != -1) {
- /*
- * This fd was recently returned from aeApiPoll. It should be safe to
- * assume that the consumer has processed that poll event, but we play
- * it safer by simply updating pending_mask. The fd will be
- * re-associated as usual when aeApiPoll is called again.
- */
- if (evport_debug)
- fprintf(stderr, "aeApiAddEvent: adding to pending fd %d\n", fd);
- state->pending_masks[pfd] |= fullmask;
- return 0;
- }
-
- return (aeApiAssociate("aeApiAddEvent", state->portfd, fd, fullmask));
- }