Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aml for openSUSE:Factory checked in at 2023-01-28 18:42:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aml (Old) and /work/SRC/openSUSE:Factory/.aml.new.32243 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aml" Sat Jan 28 18:42:44 2023 rev:6 rq:1060476 version:0.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/aml/aml.changes 2022-12-13 18:56:36.727569849 +0100 +++ /work/SRC/openSUSE:Factory/.aml.new.32243/aml.changes 2023-01-28 18:47:20.323297746 +0100 @@ -1,0 +2,11 @@ +Mon Jan 23 16:46:39 UTC 2023 - Michael Vetter <[email protected]> + +- Update to 0.3.0: + * The time unit has been changed from milliseconds to microseconds + * The global object registry has been replaced with weak references + * It is now guaranteed that a callback will not be called after aml_stop(). + * Worker threads now keep references to work objects that are being + executed. This ensures that they cannot be freed while they + are being worked + +------------------------------------------------------------------- Old: ---- aml-0.2.2.tar.gz New: ---- aml-0.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aml.spec ++++++ --- /var/tmp/diff_new_pack.l1OPtM/_old 2023-01-28 18:47:20.683299799 +0100 +++ /var/tmp/diff_new_pack.l1OPtM/_new 2023-01-28 18:47:20.687299822 +0100 @@ -1,7 +1,7 @@ # # spec file for package aml # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: aml -Version: 0.2.2 +Version: 0.3.0 Release: 0 Summary: Another Main Loop License: ISC ++++++ aml-0.2.2.tar.gz -> aml-0.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/.gitignore new/aml-0.3.0/.gitignore --- old/aml-0.2.2/.gitignore 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/.gitignore 2023-01-22 13:57:53.000000000 +0100 @@ -1,2 +1,3 @@ build* .ycm_extra_conf.py +.clang_complete diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/COPYING new/aml-0.3.0/COPYING --- old/aml-0.2.2/COPYING 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/COPYING 2023-01-22 13:57:53.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright (c) 2020 Andri Yngvason +Copyright (c) 2020 - 2022 Andri Yngvason Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/examples/nested-ticker.c new/aml-0.3.0/examples/nested-ticker.c --- old/aml-0.2.2/examples/nested-ticker.c 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/examples/nested-ticker.c 2023-01-22 13:57:53.000000000 +0100 @@ -43,7 +43,7 @@ aml_start(aml, sig); aml_unref(sig); - struct aml_ticker* ticker = aml_ticker_new(1000, on_tick, &count, NULL); + struct aml_ticker* ticker = aml_ticker_new(1000000, on_tick, &count, NULL); if (!ticker) goto failure; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/examples/ticker.c new/aml-0.3.0/examples/ticker.c --- old/aml-0.2.2/examples/ticker.c 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/examples/ticker.c 2023-01-22 13:57:53.000000000 +0100 @@ -36,7 +36,7 @@ aml_start(aml, sig); aml_unref(sig); - struct aml_ticker* ticker = aml_ticker_new(1000, on_tick, &count, NULL); + struct aml_ticker* ticker = aml_ticker_new(1000000, on_tick, &count, NULL); if (!ticker) goto failure; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/include/aml.h new/aml-0.3.0/include/aml.h --- old/aml-0.2.2/include/aml.h 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/include/aml.h 2023-01-22 13:57:53.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Andri Yngvason + * Copyright (c) 2020 - 2022 Andri Yngvason * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,6 +16,17 @@ #pragma once +#ifndef AML_UNSTABLE_API +#define AML_UNSTABLE_API 0 +#endif + +/* Something like this is necessary when changes are made that don't break the + * build but will cause nasty bugs if ignored. + */ +#if AML_UNSTABLE_API != 1 +#error "API has changed! Please, observe the changes and acknowledge by defining AML_UNSTABLE_API as 1 before including aml.h" +#endif + #include <stdint.h> #include <stdbool.h> #include <unistd.h> @@ -32,12 +43,14 @@ AML_EVENT_NONE = 0, AML_EVENT_READ = 1 << 0, AML_EVENT_WRITE = 1 << 1, + AML_EVENT_OOB = 1 << 2, }; typedef void (*aml_callback_fn)(void* obj); typedef void (*aml_free_fn)(void*); extern const char aml_version[]; +extern const int aml_unstable_abi_version; /* Create a new main loop instance */ struct aml* aml_new(void); @@ -56,12 +69,12 @@ /* Check if there are pending events. The user should call aml_dispatch() * afterwards if there are any pending events. * - * This function behaves like poll(): it will wait for either a timeout (in ms) - * or a signal. + * This function behaves like poll(): it will wait for either a timeout (in µs) + * or a signal. Will block indefinitely if timeout is -1. * * Returns: -1 on timeout or signal; otherwise number of pending events. */ -int aml_poll(struct aml*, int timeout); +int aml_poll(struct aml*, int64_t timeout); /* This is a convenience function that calls aml_poll() and aml_dispatch() in * a loop until aml_exit() is called. @@ -91,21 +104,22 @@ */ int aml_unref(void* obj); -/* Get global object id. - * - * This can be used to break reference loops. +/* Create a new weak reference to the object. * - * Returns an id that can be used to access the object using aml_try_ref(). + * The reference object must be deleted using aml_weak_ref_del(). */ -unsigned long long aml_get_id(const void* obj); +struct aml_weak_ref* aml_weak_ref_new(void* obj); -/* Try to reference an object with an id returned by aml_get_id(). - * - * This increments the reference count by one. +/* Delete a weak reference created by aml_weak_ref_new(). + */ +void aml_weak_ref_del(struct aml_weak_ref* self); + +/* Try to get a new strong reference from a weak reference object. * - * Returns the aml object if found. Otherwise NULL. + * If the weak reference is still valid, the reference count on the returned + * aml object will be increased by one. Otherwise NULL is returned. */ -void* aml_try_ref(unsigned long long id); +void* aml_weak_ref_read(struct aml_weak_ref* self); /* The following calls create event handler objects. * @@ -115,10 +129,10 @@ struct aml_handler* aml_handler_new(int fd, aml_callback_fn, void* userdata, aml_free_fn); -struct aml_timer* aml_timer_new(uint32_t timeout, aml_callback_fn, +struct aml_timer* aml_timer_new(uint64_t timeout, aml_callback_fn, void* userdata, aml_free_fn); -struct aml_ticker* aml_ticker_new(uint32_t period, aml_callback_fn, +struct aml_ticker* aml_ticker_new(uint64_t period, aml_callback_fn, void* userdata, aml_free_fn); struct aml_signal* aml_signal_new(int signo, aml_callback_fn, @@ -155,11 +169,11 @@ */ enum aml_event aml_get_revents(const struct aml_handler* obj); -/* Set timeout/period of a timer/ticker +/* Set timeout/period of a timer/ticker in µs * * Calling this on a started timer/ticker yields undefined behaviour */ -void aml_set_duration(void* obj, uint32_t value); +void aml_set_duration(void* obj, uint64_t value); /* Start an event handler. * @@ -173,6 +187,10 @@ * * This decreases the reference count on a handler object. * + * The callback or done function will not be run after this is called. However, + * for aml_work, the work function may already be executing and it will be + * allowed to complete. + * * Returns: 0 on success, -1 if the handler is already stopped. */ int aml_stop(struct aml*, void* obj); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/meson.build new/aml-0.3.0/meson.build --- old/aml-0.2.2/meson.build 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/meson.build 2023-01-22 13:57:53.000000000 +0100 @@ -1,10 +1,11 @@ project( 'aml', 'c', - version: '0.2.2', + version: '0.3.0', license: 'ISC', default_options: [ 'c_std=c11', + 'warning_level=2', ] ) @@ -16,7 +17,10 @@ '-DPROJECT_VERSION="@0@"'.format(meson.project_version()), '-D_POSIX_C_SOURCE=200809L', '-fvisibility=hidden', + '-DAML_UNSTABLE_API=1', + '-Wmissing-prototypes', + '-Wno-unused-parameter', ] git = find_program('git', native: true, required: false) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/src/aml.c new/aml-0.3.0/src/aml.c --- old/aml-0.2.2/src/aml.c 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/src/aml.c 2023-01-22 13:57:53.000000000 +0100 @@ -50,6 +50,13 @@ AML_OBJ_IDLE, }; +struct aml_weak_ref { + void* obj; + LIST_ENTRY(aml_weak_ref) link; +}; + +LIST_HEAD(aml_weak_ref_list, aml_weak_ref); + struct aml_obj { enum aml_obj_type type; int ref; @@ -58,11 +65,11 @@ aml_callback_fn cb; unsigned long long id; uint32_t n_events; + struct aml_weak_ref_list weak_refs; void* backend_data; LIST_ENTRY(aml_obj) link; - LIST_ENTRY(aml_obj) global_link; TAILQ_ENTRY(aml_obj) event_link; }; @@ -82,8 +89,9 @@ struct aml_timer { struct aml_obj obj; - uint32_t timeout; + uint64_t timeout; uint64_t deadline; + bool expired; LIST_ENTRY(aml_timer) link; }; @@ -136,9 +144,6 @@ static struct aml* aml__default = NULL; -static unsigned long long aml__obj_id = 0; -static struct aml_obj_list aml__obj_list = LIST_HEAD_INITIALIZER(aml__obj_list); - // TODO: Properly initialise this? static pthread_mutex_t aml__ref_mutex; @@ -154,6 +159,8 @@ EXPORT const char aml_version[] = "UNKNOWN"; #endif +EXPORT const int aml_unstable_abi_version = AML_UNSTABLE_API; + EXPORT void aml_set_default(struct aml* aml) { @@ -207,11 +214,11 @@ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); } -static uint64_t aml__gettime_ms(struct aml* self) +static uint64_t aml__gettime_us(struct aml* self) { struct timespec ts = { 0 }; clock_gettime(self->backend.clock, &ts); - return ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000ULL; + return ts.tv_sec * UINT64_C(1000000) + ts.tv_nsec / UINT64_C(1000); } static void aml__ref_lock(void) @@ -224,12 +231,45 @@ pthread_mutex_unlock(&aml__ref_mutex); } -static void aml__obj_global_ref(struct aml_obj* obj) +EXPORT +struct aml_weak_ref* aml_weak_ref_new(void* obj_ptr) +{ + struct aml_obj* obj = obj_ptr; + + struct aml_weak_ref* self = calloc(1, sizeof(*self)); + if (!self) + return NULL; + + self->obj = obj; + aml__ref_lock(); + LIST_INSERT_HEAD(&obj->weak_refs, self, link); + aml__ref_unlock(); + + return self; +} + +EXPORT +void aml_weak_ref_del(struct aml_weak_ref* self) { + if (!self) + return; + aml__ref_lock(); - obj->id = aml__obj_id++; - LIST_INSERT_HEAD(&aml__obj_list, obj, global_link); + if (self->obj) + LIST_REMOVE(self, link); aml__ref_unlock(); + free(self); +} + +EXPORT +void* aml_weak_ref_read(struct aml_weak_ref* self) +{ + aml__ref_lock(); + struct aml_obj* obj = self->obj; + if (obj) + obj->ref++; + aml__ref_unlock(); + return obj; } static void on_self_pipe_read(void* obj) { @@ -302,6 +342,7 @@ self->obj.type = AML_OBJ_AML; self->obj.ref = 1; + LIST_INIT(&self->obj.weak_refs); LIST_INIT(&self->obj_list); LIST_INIT(&self->timer_list); @@ -328,8 +369,6 @@ if (aml__init_self_pipe(self) < 0) goto pipe_failure; - aml__obj_global_ref(&self->obj); - return self; pipe_failure: @@ -374,17 +413,16 @@ self->obj.userdata = userdata; self->obj.free_fn = free_fn; self->obj.cb = callback; + LIST_INIT(&self->obj.weak_refs); self->fd = fd; self->event_mask = EVENT_MASK_DEFAULT; - aml__obj_global_ref(&self->obj); - return self; } EXPORT -struct aml_timer* aml_timer_new(uint32_t timeout, aml_callback_fn callback, +struct aml_timer* aml_timer_new(uint64_t timeout, aml_callback_fn callback, void* userdata, aml_free_fn free_fn) { struct aml_timer* self = calloc(1, sizeof(*self)); @@ -396,16 +434,15 @@ self->obj.userdata = userdata; self->obj.free_fn = free_fn; self->obj.cb = callback; + LIST_INIT(&self->obj.weak_refs); self->timeout = timeout; - aml__obj_global_ref(&self->obj); - return self; } EXPORT -struct aml_ticker* aml_ticker_new(uint32_t period, aml_callback_fn callback, +struct aml_ticker* aml_ticker_new(uint64_t period, aml_callback_fn callback, void* userdata, aml_free_fn free_fn) { struct aml_timer* timer = @@ -427,11 +464,10 @@ self->obj.userdata = userdata; self->obj.free_fn = free_fn; self->obj.cb = callback; + LIST_INIT(&self->obj.weak_refs); self->signo = signo; - aml__obj_global_ref(&self->obj); - return self; } @@ -448,11 +484,10 @@ self->obj.userdata = userdata; self->obj.free_fn = free_fn; self->obj.cb = callback; + LIST_INIT(&self->obj.weak_refs); self->work_fn = work_fn; - aml__obj_global_ref(&self->obj); - return self; } @@ -469,12 +504,23 @@ self->obj.userdata = userdata; self->obj.free_fn = free_fn; self->obj.cb = callback; - - aml__obj_global_ref(&self->obj); + LIST_INIT(&self->obj.weak_refs); return self; } +static bool aml__obj_is_single_shot(void* ptr) +{ + struct aml_obj* obj = ptr; + switch (obj->type) { + case AML_OBJ_TIMER: /* fallthrough */ + case AML_OBJ_WORK: + return true; + default:; + } + return false; +} + static bool aml__obj_is_started_unlocked(struct aml* self, void* obj) { struct aml_obj* elem; @@ -552,7 +598,8 @@ static int aml__start_timer(struct aml* self, struct aml_timer* timer) { - timer->deadline = aml__gettime_ms(self) + timer->timeout; + timer->deadline = aml__gettime_us(self) + timer->timeout; + timer->expired = false; pthread_mutex_lock(&self->timer_list_mutex); LIST_INSERT_HEAD(&self->timer_list, timer, link); @@ -560,7 +607,6 @@ if (timer->timeout == 0) { assert(timer->obj.type != AML_OBJ_TICKER); - aml_stop(self, timer); aml_emit(self, timer, 0); aml_interrupt(self); return 0; @@ -646,7 +692,6 @@ static int aml__stop_work(struct aml* self, struct aml_work* work) { - /* Note: The cb may be executed anyhow */ return 0; } @@ -697,7 +742,7 @@ pthread_mutex_lock(&self->timer_list_mutex); LIST_FOREACH(timer, &self->timer_list, link) - if (timer->deadline < deadline) { + if (!timer->expired && timer->deadline < deadline) { deadline = timer->deadline; result = timer; } @@ -716,7 +761,7 @@ switch (timer->obj.type) { case AML_OBJ_TIMER: - aml_stop(self, timer); + timer->expired = true; break; case AML_OBJ_TICKER: timer->deadline += timer->timeout; @@ -732,9 +777,10 @@ static void aml__handle_idle(struct aml* self) { struct aml_idle* idle; + struct aml_idle* tmp; - LIST_FOREACH(idle, &self->idle_list, link) - if (idle->obj.cb) + LIST_FOREACH_SAFE(idle, &self->idle_list, link, tmp) + if (idle->obj.cb && aml_is_started(self, idle)) idle->obj.cb(idle); } @@ -745,8 +791,15 @@ */ aml_ref(obj); - if (obj->cb) + if (obj->cb && aml_is_started(self, obj)) { + /* Single-shot objects must be stopped before the callback so + * that they can be restarted from within the callback. + */ + if (aml__obj_is_single_shot(obj)) + aml_stop(self, obj); + obj->cb(obj); + } if (obj->type == AML_OBJ_HANDLER) { struct aml_handler* handler = (struct aml_handler*)obj; @@ -761,9 +814,11 @@ /* Might exit earlier than timeout. It's up to the user to check */ EXPORT -int aml_poll(struct aml* self, int timeout) +int aml_poll(struct aml* self, int64_t timeout_us) { - return aml__poll(self, timeout); + int timeout_ms = (timeout_us == INT64_C(-1)) + ? -1 : timeout_us / INT64_C(1000); + return aml__poll(self, timeout_ms); } static struct aml_obj* aml__event_dequeue(struct aml* self) @@ -779,7 +834,7 @@ EXPORT void aml_dispatch(struct aml* self) { - uint64_t now = aml__gettime_ms(self); + uint64_t now = aml__gettime_us(self); while (aml__handle_timeout(self, now)); struct aml_timer* earliest = aml__get_timer_with_earliest_deadline(self); @@ -833,6 +888,7 @@ struct aml_obj* self = obj; aml__ref_lock(); + assert(self->ref >= 0); int ref = self->ref++; aml__ref_unlock(); @@ -913,13 +969,20 @@ aml__ref_lock(); int ref = --self->ref; - if (ref == 0) - LIST_REMOVE(self, global_link); aml__ref_unlock(); + assert(ref >= 0); if (ref > 0) goto done; + aml__ref_lock(); + while (!LIST_EMPTY(&self->weak_refs)) { + struct aml_weak_ref* ref = LIST_FIRST(&self->weak_refs); + ref->obj = NULL; + LIST_REMOVE(ref, link); + } + aml__ref_unlock(); + switch (self->type) { case AML_OBJ_AML: aml__free(obj); @@ -951,32 +1014,6 @@ } EXPORT -unsigned long long aml_get_id(const void* obj) -{ - const struct aml_obj* aml_obj = obj; - return aml_obj->id; -} - -EXPORT -void* aml_try_ref(unsigned long long id) -{ - struct aml_obj* obj = NULL; - - aml__ref_lock(); - LIST_FOREACH(obj, &aml__obj_list, global_link) - if (obj->id == id) - break; - - if (obj && obj->id == id) - obj->ref++; - else - obj = NULL; - - aml__ref_unlock(); - return obj; -} - -EXPORT void* aml_get_userdata(const void* obj) { const struct aml_obj* aml_obj = obj; @@ -1083,7 +1120,7 @@ } EXPORT -void aml_set_duration(void* ptr, uint32_t duration) +void aml_set_duration(void* ptr, uint64_t duration) { struct aml_obj* obj = ptr; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/src/epoll.c new/aml-0.3.0/src/epoll.c --- old/aml-0.2.2/src/epoll.c 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/src/epoll.c 2023-01-22 13:57:53.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Andri Yngvason + * Copyright (c) 2020 - 2022 Andri Yngvason * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -37,7 +37,7 @@ struct epoll_signal { struct epoll_state* state; int fd; - int ref; + struct aml_weak_ref* ref; }; static void* epoll_new_state(struct aml* aml) @@ -98,10 +98,12 @@ } enum aml_event aml_events = AML_EVENT_NONE; - if (event->events & (EPOLLIN | EPOLLPRI)) + if (event->events & EPOLLIN) aml_events |= AML_EVENT_READ; if (event->events & EPOLLOUT) aml_events |= AML_EVENT_WRITE; + if (event->events & EPOLLPRI) + aml_events |= AML_EVENT_OOB; aml_emit(self->aml, event->data.ptr, aml_events); } @@ -126,9 +128,11 @@ event->events = 0; if (in & AML_EVENT_READ) - event->events |= EPOLLIN | EPOLLPRI; + event->events |= EPOLLIN; if (in & AML_EVENT_WRITE) event->events |= EPOLLOUT; + if (in & AML_EVENT_OOB) + event->events |= EPOLLPRI; event->data.ptr = handler; } @@ -164,6 +168,7 @@ { struct epoll_signal* sig = userdata; close(sig->fd); + aml_weak_ref_del(sig->ref); free(sig); } @@ -175,7 +180,7 @@ struct signalfd_siginfo fdsi; (void)read(ctx->fd, &fdsi, sizeof(fdsi)); - struct aml_signal* sig = aml_try_ref(ctx->ref); + struct aml_signal* sig = aml_weak_ref_read(ctx->ref); if (!sig) return; @@ -198,7 +203,7 @@ sigaddset(&ss, signo); ctx->state = self; - ctx->ref = aml_get_id(sig); + ctx->ref = aml_weak_ref_new(sig); ctx->fd = signalfd(-1, &ss, SFD_NONBLOCK | SFD_CLOEXEC); if (ctx->fd < 0) @@ -247,9 +252,9 @@ struct itimerspec it = { .it_value = { - .tv_sec = (uint32_t)(deadline / UINT64_C(1000)), - .tv_nsec = (uint32_t)((deadline % UINT64_C(1000)) * - UINT64_C(1000000)), + .tv_sec = (uint32_t)(deadline / UINT64_C(1000000)), + .tv_nsec = (uint32_t)((deadline % UINT64_C(1000000)) * + UINT64_C(1000)), }, }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/src/kqueue.c new/aml-0.3.0/src/kqueue.c --- old/aml-0.2.2/src/kqueue.c 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/src/kqueue.c 2023-01-22 13:57:53.000000000 +0100 @@ -181,7 +181,7 @@ struct kevent event; EV_SET(&event, 0, EVFILT_TIMER, EV_ADD | EV_ONESHOT, - NOTE_MSECONDS | NOTE_ABSTIME, deadline, NULL); + NOTE_USECONDS | NOTE_ABSTIME, deadline, NULL); return kevent(self->fd, &event, 1, NULL, 0, NULL); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aml-0.2.2/src/thread-pool.c new/aml-0.3.0/src/thread-pool.c --- old/aml-0.2.2/src/thread-pool.c 2022-07-03 22:18:54.000000000 +0200 +++ new/aml-0.3.0/src/thread-pool.c 2023-01-22 13:57:53.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Andri Yngvason + * Copyright (c) 2020 - 2022 Andri Yngvason * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,7 +29,7 @@ #include "sys/queue.h" struct default_work { - unsigned long long aml_id; + struct aml_weak_ref* aml_ref; struct aml_work* work; TAILQ_ENTRY(default_work) link; @@ -66,6 +66,8 @@ while (!TAILQ_EMPTY(&default_work_queue)) { struct default_work* work = TAILQ_FIRST(&default_work_queue); TAILQ_REMOVE(&default_work_queue, work, link); + if (work->work) + aml_unref(work->work); free(work); } } @@ -108,14 +110,16 @@ if (cb) cb(work->work); - struct aml* aml = aml_try_ref(work->aml_id); + struct aml* aml = work->aml_ref ? + aml_weak_ref_read(work->aml_ref) : NULL; if (aml) { aml_emit(aml, work->work, 0); - aml_stop(aml, work->work); aml_interrupt(aml); aml_unref(aml); } + aml_weak_ref_del(work->aml_ref); + aml_unref(work->work); free(work); } @@ -170,12 +174,11 @@ if (!default_work) return -1; - default_work->work = work; + if (work) + aml_ref(work); - if (aml) - default_work->aml_id = aml_get_id(aml); - else - default_work->aml_id = ULLONG_MAX; + default_work->work = work; + default_work->aml_ref = aml ? aml_weak_ref_new(aml) : NULL; pthread_mutex_lock(&work_queue_mutex); TAILQ_INSERT_TAIL(&default_work_queue, default_work, link);
