Skip to content

Instantly share code, notes, and snippets.

@pervognsen
Last active February 23, 2019 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pervognsen/499c36ea5381faf958ce8e052a729535 to your computer and use it in GitHub Desktop.
Save pervognsen/499c36ea5381faf958ce8e052a729535 to your computer and use it in GitHub Desktop.
typedef DisposeFunc = func(void*);
typedef DisposeMark = usize;
struct Disposable {
dispose: DisposeFunc;
mark: DisposeMark;
}
@threadlocal
var disposables: Disposable*[];
func make_disposable(dispose: DisposeFunc): Disposable {
return {dispose, alen(disposables)};
}
func secured(data: void*): bool {
if (!data) {
return false;
}
self: Disposable* = data;
mark := self.mark;
return mark < alen(disposables) && disposables[mark] == self;
}
func secure(data: void*): void* {
if (data && !secured(data)) {
self: Disposable* = data;
self.mark = apush(disposables, self);
}
return data;
}
func unsecure(data: void*): void* {
if (data && secured(data)) {
self: Disposable* = data;
disposables[self.mark] = 0;
self.mark = -1;
}
return data;
}
func dispose(data: void*) {
if (!data) {
return;
}
self: Disposable* = data;
mark := self.mark;
for (i := alen(disposables); i > mark; i--) {
disposable := disposables[i-1];
if (disposable) {
disposable.dispose(disposable);
}
}
asetlen(disposables, mark);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment