I got a design question about error handling. I am developing my personal project rrxv6, and I encounter this in kvm design.
When a user process is being allocated, it has to map two pages in page table.
However if the mapping failed, it has to free that page in page table.
The code is here
The error handling part is un-implemented and TODO comment are there right now.
I do know there is railway oriented programming. However it does not quite fit my scenarios since I will need to handle the error reversely.
Hope someone can give me some advice on how to write this clean and neat.
Unfortunately, when you're working with functions that have an effective C-like semantic, like kalloc and uvfree and uvunmap, you have very little choice other than repeating code.
A solution would be to make a Box-like wrapper around kalloc and uvfree - that way you can ensure that memory is always freed.
I am guessing you need a similar idea for uvunmap although I don't have enough domain knowledge to suggest a wrapper for that.
The best way to handle this is with the RAII pattern.
The idea is you create some object which represents a mapped page, and you unmap the page as part of its Drop implementation. Local variables are dropped in the opposite order to how they were created, so this should automatically give you the stack-like semantics you want.
As a bonus, when you use a RAII guard you could allocate 50 different pages and wouldn't need to add any extra cleanup code because the compiler makes sure all variables are dropped correctly.