mirror of
https://github.com/darlinghq/darling-libkqueue.git
synced 2024-11-26 21:20:38 +00:00
Attempt to fix darlinghq/darling#420
This commit is contained in:
parent
f411d4553d
commit
1d627ad694
@ -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 */
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user