Page MenuHomeFreeBSD

D31037.diff
No OneTemporary

D31037.diff

Index: sys/compat/linux/linux_event.c
===================================================================
--- sys/compat/linux/linux_event.c
+++ sys/compat/linux/linux_event.c
@@ -219,18 +219,22 @@
if ((levents & LINUX_EPOLL_EVRD) != 0) {
EV_SET(kevent, fd, EVFILT_READ, kev_flags, 0, 0, 0);
kevent->ext[0] = l_event->data;
+ kevent->pmask = levents;
++kevent;
++(*nkevents);
}
if ((levents & LINUX_EPOLL_EVWR) != 0) {
EV_SET(kevent, fd, EVFILT_WRITE, kev_flags, 0, 0, 0);
kevent->ext[0] = l_event->data;
+ kevent->pmask = levents;
++kevent;
++(*nkevents);
}
/* zero event mask is legal */
if ((levents & (LINUX_EPOLL_EVRD | LINUX_EPOLL_EVWR)) == 0) {
- EV_SET(kevent++, fd, EVFILT_READ, EV_ADD|EV_DISABLE, 0, 0, 0);
+ EV_SET(kevent, fd, EVFILT_READ, EV_ADD|EV_DISABLE, 0, 0, 0);
+ kevent->pmask = levents;
+ ++kevent;
++(*nkevents);
}
@@ -262,12 +266,10 @@
static void
kevent_to_epoll(struct kevent *kevent, struct epoll_event *l_event)
{
-
l_event->data = kevent->ext[0];
if ((kevent->flags & EV_ERROR) != 0) {
l_event->events = LINUX_EPOLLERR;
- return;
}
/* XXX EPOLLPRI, EPOLLHUP */
@@ -281,6 +283,37 @@
l_event->events = LINUX_EPOLLOUT;
break;
}
+
+ /* Handle all events to meet all Linux epoll cases */
+ if ((kevent->pevents & EV_POLLIN) != 0) {
+ l_event->events |= LINUX_EPOLLIN;
+ }
+ if ((kevent->pevents & EV_POLLHUP) != 0) {
+ l_event->events |= LINUX_EPOLLHUP;
+ }
+ if ((kevent->pevents & EV_POLLRDHUP) != 0) {
+ l_event->events |= LINUX_EPOLLRDHUP;
+ }
+ if ((kevent->pevents & EV_POLLRDNORM) != 0) {
+ l_event->events |= LINUX_EPOLLRDNORM;
+ }
+ if ((kevent->pevents & EV_POLLERR) != 0) {
+ l_event->events |= LINUX_EPOLLERR;
+ }
+ if ((kevent->pevents & EV_POLLOUT) != 0) {
+ l_event->events |= LINUX_EPOLLOUT;
+ }
+ if ((kevent->pevents & EV_POLLWRNORM) != 0) {
+ l_event->events |= LINUX_EPOLLWRNORM;
+ }
+ if ((kevent->pevents & EV_POLLRDBAND) != 0) {
+ l_event->events |= LINUX_EPOLLRDBAND;
+ }
+ if ((kevent->pevents & EV_POLLWRBAND) != 0) {
+ l_event->events |= LINUX_EPOLLWRBAND;
+ }
+
+ l_event->events = (l_event->events & kevent->pmask);
}
/*
@@ -380,6 +413,8 @@
ciargs.changelist = kev;
if (args->op != LINUX_EPOLL_CTL_DEL) {
+ /* For Linux, 'EPOLLERR' and 'EPOLLHUP' are always in mask. */
+ le.events |= LINUX_EPOLLERR | LINUX_EPOLLHUP;
error = epoll_to_kevent(td, args->fd, &le, kev, &nchanges);
if (error != 0)
goto leave0;
Index: sys/kern/uipc_socket.c
===================================================================
--- sys/kern/uipc_socket.c
+++ sys/kern/uipc_socket.c
@@ -3830,6 +3830,10 @@
kn->kn_data = sbavail(&so->so_rcv) - so->so_rcv.sb_ctl;
if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
kn->kn_flags |= EV_EOF;
+ kn->kn_pevents |= EV_POLLIN | EV_POLLRDHUP | EV_POLLRDNORM;
+ if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
+ kn->kn_pevents |= EV_POLLHUP;
+ }
kn->kn_fflags = so->so_error;
return (1);
} else if (so->so_error) /* temporary udp error */
@@ -3875,6 +3879,10 @@
if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
kn->kn_flags |= EV_EOF;
+ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
+ kn->kn_pevents |= EV_POLLHUP
+ | EV_POLLIN | EV_POLLRDHUP | EV_POLLRDNORM;
+ }
kn->kn_fflags = so->so_error;
return (1);
} else if (so->so_error) /* temporary udp error */
Index: sys/sys/event.h
===================================================================
--- sys/sys/event.h
+++ sys/sys/event.h
@@ -33,6 +33,7 @@
#include <sys/_types.h>
#include <sys/queue.h>
+#include <sys/poll.h>
#define EVFILT_READ (-1)
#define EVFILT_WRITE (-2)
@@ -58,6 +59,8 @@
.fflags = (d), \
.data = (e), \
.udata = (f), \
+ .pevents = 0, \
+ .pmask = 0, \
.ext = {0}, \
}; \
} while(0)
@@ -73,10 +76,11 @@
(kevp)->fflags = (d); \
(kevp)->data = (e); \
(kevp)->udata = (f); \
+ (kevp)->pevents = 0; \
+ (kevp)->pmask = 0; \
(kevp)->ext[0] = 0; \
(kevp)->ext[1] = 0; \
(kevp)->ext[2] = 0; \
- (kevp)->ext[3] = 0; \
} while(0)
#endif
@@ -87,7 +91,9 @@
unsigned int fflags; /* filter flag value */
__int64_t data; /* filter data value */
void *udata; /* opaque user data identifier */
- __uint64_t ext[4]; /* extensions */
+ unsigned int pevents; /* poll events, used to Linux epoll */
+ unsigned int pmask; /* poll mask, used to Linux epoll */
+ __uint64_t ext[3]; /* extensions */
};
#if defined(_WANT_FREEBSD11_KEVENT)
@@ -153,6 +159,19 @@
#define EV_EOF 0x8000 /* EOF detected */
#define EV_ERROR 0x4000 /* error, data contains errno */
+/* poll event */
+#define EV_POLLIN POLLIN
+#define EV_POLLPRI POLLPRI
+#define EV_POLLOUT POLLOUT
+#define EV_POLLERR POLLERR
+#define EV_POLLHUP POLLHUP
+#define EV_POLLRDNORM POLLRDNORM
+#define EV_POLLWRNORM POLLWRNORM
+#define EV_POLLRDBAND POLLRDBAND
+#define EV_POLLWRBAND POLLWRBAND
+#define EV_POLLRDHUP 0x00002000
+
+
/*
* data/hint flags/masks for EVFILT_USER, shared with userspace
*
@@ -311,6 +330,7 @@
#define kn_fflags kn_kevent.fflags
#define kn_data kn_kevent.data
#define kn_fp kn_ptr.p_fp
+#define kn_pevents kn_kevent.pevents
};
struct kevent_copyops {
void *arg;

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 21, 5:53 AM (11 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25752876
Default Alt Text
D31037.diff (5 KB)

Event Timeline