Golang has a lot of nice features – and one I found pretty interesting is called deferred statements. This can be implemented in C++ pretty easily through RAII, but in C we’re pretty much out of luck. Or are we?
In lwan, I’m using my own home-cooked coroutine implementation. All requests are handled by coroutines, so that it makes easy to condition the execution of deferred statements with the cleanup of a coroutine. And that’s what I did, by implementing coro_defer(), which adds hooks that will be called sequentially by coro_free().
This can be used for various purposes, including garbage collection and other miscellaneous cleanup code:
void* coro_malloc(coro_t *coro, size_t sz) {
void *ptr = malloc(sz);
if (ptr)
coro_defer(coro, free, ptr);
return ptr;
}
void* coro_strdup(coro_t *coro, const char *str) {
char *dup = strdup(str);
if (dup)
coro_defer(coro, free, ptr);
return dup;
}
int coro_open(coro_t *coro, const char *path, int flags)
{
int fd = open(path, flags);
if (fd >= 0)
coro_defer(coro, close, INT_TO_PTR(fd));
return fd;
}
This way, one can easily allocate memory, lock mutexes, open files – and leave the cleanup to lwan.
Copyright © 2023 L. A. F. Pereira