FreeBSD Bugzilla – Attachment 227065 Details for
Bug 256952
kqueue(2): Improve epoll Linux compatibility (compat/linux/linux_event)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
note_hup.patch
note_hup.patch (text/plain), 4.50 KB, created by
Vladimir Kondratyev
on 2021-08-09 23:44:02 UTC
(
hide
)
Description:
note_hup.patch
Filename:
MIME Type:
Creator:
Vladimir Kondratyev
Created:
2021-08-09 23:44:02 UTC
Size:
4.50 KB
patch
obsolete
>diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c >index 331732eb423..d71542656d7 100644 >--- a/sys/compat/linux/linux_event.c >+++ b/sys/compat/linux/linux_event.c >@@ -83,7 +83,7 @@ __attribute__((packed)) > > #define LINUX_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) > >-static int epoll_to_kevent(struct thread *td, int fd, >+static int epoll_to_kevent(struct thread *td, struct file *fp, int fd, > struct epoll_event *l_event, struct kevent *kevent, > int *nkevents); > static void kevent_to_epoll(struct kevent *kevent, struct epoll_event *l_event); >@@ -196,8 +196,8 @@ linux_epoll_create1(struct thread *td, struct linux_epoll_create1_args *args) > > /* Structure converting function from epoll to kevent. */ > static int >-epoll_to_kevent(struct thread *td, int fd, struct epoll_event *l_event, >- struct kevent *kevent, int *nkevents) >+epoll_to_kevent(struct thread *td, struct file *fp, int fd, >+ struct epoll_event *l_event, struct kevent *kevent, int *nkevents) > { > uint32_t levents = l_event->events; > struct linux_pemuldata *pem; >@@ -216,14 +216,18 @@ epoll_to_kevent(struct thread *td, int fd, struct epoll_event *l_event, > > /* flags related to what event is registered */ > if ((levents & LINUX_EPOLL_EVRD) != 0) { >- EV_SET(kevent, fd, EVFILT_READ, kev_flags, 0, 0, 0); >+ EV_SET(kevent, fd, EVFILT_READ, kev_flags, NOTE_HUP, 0, 0); > kevent->ext[0] = l_event->data; >+ kevent->ext[1] = fp->f_type; >+ kevent->ext[2] = l_event->events; > ++kevent; > ++(*nkevents); > } > if ((levents & LINUX_EPOLL_EVWR) != 0) { >- EV_SET(kevent, fd, EVFILT_WRITE, kev_flags, 0, 0, 0); >+ EV_SET(kevent, fd, EVFILT_WRITE, kev_flags, NOTE_HUP, 0, 0); > kevent->ext[0] = l_event->data; >+ kevent->ext[1] = fp->f_type; >+ kevent->ext[2] = l_event->events; > ++kevent; > ++(*nkevents); > } >@@ -269,17 +273,33 @@ kevent_to_epoll(struct kevent *kevent, struct epoll_event *l_event) > return; > } > >- /* XXX EPOLLPRI, EPOLLHUP */ >+ /* XXX EPOLLPRI */ > switch (kevent->filter) { > case EVFILT_READ: >- l_event->events = LINUX_EPOLLIN; >- if ((kevent->flags & EV_EOF) != 0) >- l_event->events |= LINUX_EPOLLRDHUP; >+ l_event->events = LINUX_EPOLL_EVRD; >+ if (kevent->ext[1] == DTYPE_SOCKET) { >+ if ((kevent->flags & EV_EOF) != 0) >+ l_event->events |= LINUX_EPOLLRDHUP; >+ if ((kevent->fflags & NOTE_HUP) != 0) >+ l_event->events |= LINUX_EPOLLHUP; >+ } else >+ if ((kevent->flags & EV_EOF) != 0) >+ l_event->events |= LINUX_EPOLLHUP; > break; > case EVFILT_WRITE: >- l_event->events = LINUX_EPOLLOUT; >+ l_event->events = LINUX_EPOLL_EVWR; >+ if (kevent->ext[1] == DTYPE_SOCKET) { >+ if ((kevent->fflags & NOTE_HUP) != 0) >+ l_event->events |= LINUX_EPOLL_EVRD | >+ LINUX_EPOLLHUP | LINUX_EPOLLRDHUP; >+ } else >+ if ((kevent->flags & EV_EOF) != 0) >+ l_event->events |= >+ LINUX_EPOLL_EVRD | LINUX_EPOLLHUP; > break; > } >+ >+ l_event->events &= (kevent->ext[2] | LINUX_EPOLLHUP | LINUX_EPOLLERR); > } > > /* >@@ -379,7 +399,7 @@ linux_epoll_ctl(struct thread *td, struct linux_epoll_ctl_args *args) > ciargs.changelist = kev; > > if (args->op != LINUX_EPOLL_CTL_DEL) { >- error = epoll_to_kevent(td, args->fd, &le, kev, &nchanges); >+ error = epoll_to_kevent(td, fp, args->fd, &le, kev, &nchanges); > if (error != 0) > goto leave0; > } >diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c >index 602d6c8b421..98e37db0079 100644 >--- a/sys/kern/uipc_socket.c >+++ b/sys/kern/uipc_socket.c >@@ -3852,6 +3852,9 @@ filt_soread(struct knote *kn, long hint) > if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { > kn->kn_flags |= EV_EOF; > kn->kn_fflags = so->so_error; >+ if (so->so_snd.sb_state & SBS_CANTSENDMORE && >+ kn->kn_sfflags & NOTE_HUP) >+ kn->kn_fflags |= NOTE_HUP; > return (1); > } else if (so->so_error || so->so_rerror) > return (1); >@@ -3897,6 +3900,9 @@ filt_sowrite(struct knote *kn, long hint) > if (so->so_snd.sb_state & SBS_CANTSENDMORE) { > kn->kn_flags |= EV_EOF; > kn->kn_fflags = so->so_error; >+ if (so->so_rcv.sb_state & SBS_CANTRCVMORE && >+ kn->kn_sfflags & NOTE_HUP) >+ kn->kn_fflags |= NOTE_HUP; > return (1); > } else if (so->so_error) /* temporary udp error */ > return (1); >diff --git a/sys/sys/event.h b/sys/sys/event.h >index cf7db43475f..b27ae17045c 100644 >--- a/sys/sys/event.h >+++ b/sys/sys/event.h >@@ -178,6 +178,7 @@ struct kevent32_freebsd11 { > */ > #define NOTE_LOWAT 0x0001 /* low water mark */ > #define NOTE_FILE_POLL 0x0002 /* behave like poll() */ >+#define NOTE_HUP 0x80000000 /* socket disconnected */ > > /* > * data/hint flags for EVFILT_VNODE, shared with userspace
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 256952
:
226189
|
227028
|
227040
| 227065