diff --git a/include/libwebsockets/lws-dll2.h b/include/libwebsockets/lws-dll2.h index a4542aa25..478aa4344 100644 --- a/include/libwebsockets/lws-dll2.h +++ b/include/libwebsockets/lws-dll2.h @@ -207,8 +207,8 @@ typedef struct lws_dll2_owner { uint32_t count; } lws_dll2_owner_t; -static LWS_INLINE int -lws_dll2_is_detached(const struct lws_dll2 *d) { return !d->owner; } +LWS_VISIBLE LWS_EXTERN int +lws_dll2_is_detached(const struct lws_dll2 *d); static LWS_INLINE const struct lws_dll2_owner * lws_dll2_owner(const struct lws_dll2 *d) { return d->owner; } diff --git a/lib/core/lws_dll2.c b/lib/core/lws_dll2.c index 9b9e6b37e..18888dd07 100644 --- a/lib/core/lws_dll2.c +++ b/lib/core/lws_dll2.c @@ -28,6 +28,31 @@ #include #endif +int +lws_dll2_is_detached(const struct lws_dll2 *d) +{ + if (d->owner) + return 0; + + if (d->next || d->prev) { + lwsl_err("%s: dll2 %p: detached but next %p, prev %p\n", + __func__, d, d->next, d->prev); + /* + * New lws_dll2 objects and removed lws_dll2 objects + * have .owner, .next and .prev all set to NULL, so we + * can just check .owner to see if we are detached. + * + * We assert here if we encounter an lws_dll2 in the illegal + * state of NULL .owner, but non-NULL in .next or .prev, + * it's evidence of corruption, use-after-free, threads + * contending on accessing without locking etc. + */ + assert(0); + } + + return 1; +} + int lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user, int (*cb)(struct lws_dll2 *d, void *user))