This commit is contained in:
Lubos Dolezel 2018-08-27 11:30:03 +02:00
parent f411d4553d
commit 1d627ad694
4 changed files with 27 additions and 4 deletions

View File

@ -317,7 +317,6 @@ kevent_impl(int kqfd, const struct kevent *changelist, int nchanges,
return rv;
}
int VISIBLE
kevent64_impl(int kqfd, const struct kevent64_s *changelist, int nchanges,
struct kevent64_s *eventlist, int nevents,
@ -386,6 +385,11 @@ again:
rv = kqops.kevent_copyout(kq, rv, eventlist, nevents);
kqueue_unlock(kq);
}
kqueue_lock(kq);
kqueue_cleanup(kq);
kqueue_unlock(kq);
if (rv == 0) {
/* Timeout reached */
/* Avoid returning 0 when waiting indefinitely in case of spurious wakeups */

View File

@ -60,8 +60,9 @@ knote_release(struct knote *kn)
if (atomic_dec(&kn->kn_ref) == 0) {
// This can happen if the note never made it into a filter
if (/*kn->kn_flags & KNFL_KNOTE_DELETED*/ 1) {
dbg_printf("freeing knote at %p", kn);
free(kn);
dbg_printf("freeing knote at %p (delayed)", kn);
LIST_INSERT_HEAD(&kn->kn_kq->kq_tofree, kn, kn_entries2free);
kn->kev.filter = 0;
} else {
dbg_puts("this should never happen");
}

View File

@ -106,10 +106,22 @@ kqueue_cmp(struct kqueue *a, struct kqueue *b)
}
#endif
void kqueue_cleanup(struct kqueue* kq)
{
struct knote *next, *tmp;
for (next = kq->kq_tofree.lh_first; next != NULL; next = tmp)
{
tmp = next->kn_entries2free.le_next;
free(next);
}
LIST_INIT(&kq->kq_tofree);
}
/* Must hold the kqtree_mtx when calling this */
void
kqueue_free(struct kqueue *kq)
{
kqueue_cleanup(kq);
map_delete(kqmap, kq->kq_id);
filter_unregister_all(kq);
kqops.kqueue_free(kq);
@ -150,7 +162,7 @@ kqueue_close(int kqfd)
// It is not a kqueue fd, but it could be a fd inside a kqueue
// Since we're creating duplicates of all fd's, we now have to walk
// through all known kqueues and remove the fd from them.
map_foreach(kqmap, _kqueue_close_cb, (void*) kqfd);
map_foreach(kqmap, _kqueue_close_cb, (void*)(long) kqfd);
}
else {
kqueue_delref(kq);
@ -194,6 +206,7 @@ kqueue_impl(void)
kq->kq_ref = 1;
tracing_mutex_init(&kq->kq_mtx, NULL);
LIST_INIT(&kq->kq_tofree);
if (kqops.kqueue_init(kq) < 0) {
free(kq);

View File

@ -22,6 +22,7 @@
#include <string.h>
// #include "config.h"
#include "tree.h"
#include <sys/queue.h>
/* Maximum events returnable in a single kevent() call */
#define MAX_KEVENT 512
@ -96,6 +97,7 @@ struct knote {
KNOTE_PLATFORM_SPECIFIC;
#endif
RB_ENTRY(knote) kn_entries;
LIST_ENTRY(knote) kn_entries2free;
};
#define KNOTE_ENABLE(ent) do { \
@ -154,6 +156,7 @@ struct kqueue {
KQUEUE_PLATFORM_SPECIFIC;
#endif
RB_ENTRY(kqueue) entries;
LIST_HEAD(knt2free, knote) kq_tofree;
};
struct kqueue_vtable {
@ -214,6 +217,8 @@ struct kqueue * kqueue_lookup(int);
int kqueue_validate(struct kqueue *);
void kqueue_addref(struct kqueue *);
void kqueue_delref(struct kqueue *);
// execute pending free() operations
void kqueue_cleanup(struct kqueue* kq);
struct map *map_new(size_t);
int map_insert(struct map *, int, void *);