Deferred statements in C

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.