X-Git-Url: https://git.distorted.org.uk/~mdw/fwd/blobdiff_plain/270b8403580b7fd0feae995b9e8bad4a2ff660ff..57ceb980e3c55306f3f70f92604703abf132cf27:/source.c diff --git a/source.c b/source.c index 96b7f81..f515ae2 100644 --- a/source.c +++ b/source.c @@ -45,11 +45,15 @@ static source *sources = 0; void source_add(source *s) { + assert(s->ops->shutdown); + assert(!(s->f&SF_ACTIVE)); s->next = sources; s->prev = 0; if (sources) sources->prev = s; sources = s; + s->f |= SF_ACTIVE; + source_inc(s); } /* --- @source_remove@ --- * @@ -63,12 +67,45 @@ void source_add(source *s) void source_remove(source *s) { + assert(s->f&SF_ACTIVE); if (s->next) s->next->prev = s->prev; if (s->prev) s->prev->next = s->next; else sources = s->next; + s->f &= ~SF_ACTIVE; + source_dec(s); +} + +/* --- @source_inc@ --- * + * + * Arguments: @source *s@ = pointer to a source + * + * Returns: --- + * + * Use: Increments a source's refcount. + */ + +void source_inc(source *s) { s->ref++; } + +/* --- @source_dec@ --- * + * + * Arguments: @source *s@ = pointer to a source + * + * Returns: --- + * + * Use: Decrements a source's refcount, destroying it if necessary. + */ + +void source_dec(source *s) +{ + assert(s->ref > 0); + s->ref--; + if (!s->ref) { + if (s->f&SF_ACTIVE) s->ops->shutdown(s); + s->ops->destroy(s); + } } /* --- @source_killall@ --- * @@ -86,7 +123,7 @@ void source_killall(void) while (s) { source *ss = s; s = s->next; - ss->ops->destroy(ss); + ss->ops->shutdown(ss); } sources = 0; }