Created
July 20, 2011 20:02
-
-
Save niuk/1095789 to your computer and use it in GitHub Desktop.
Resource Handling, PART II
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* The Hammer code for read_buf_from_file would look like this: */ | |
void *read_buf_from_file(char *path) { | |
int ret = -1; | |
void *buf = malloc(512) <- | |
lambda(buf) { | |
if (ret < 0) free(buf); | |
}; | |
int fd = open(path, O_RDONLY) <- | |
lambda(fd) { | |
if (close(fd) < 0) throw new FileCloseException(); | |
}; | |
ret = read(fd, buf, 512); | |
return buf; | |
} | |
/* The backwards arrow (<-) notation is used to "hook up" a "destructor" to | |
* the result of an expression, which gets executed at stack unwinding. | |
* Furthermore, the destructors are run in the reverse order of the execution | |
* of their associated expressions, even if the programmer himself has no | |
* information about the evaluation order. Also, since the destructor is | |
* attached to the results of expressions rather than variables, one could | |
* write the function in a more direct way, without allocating variables: */ | |
void closeWrapper(int fd) { | |
if (close(fd) < 0) throw new FileCloseException(); | |
} | |
void *read_buf_from_file(char *path) { | |
bool success = false; | |
void freeWrapper(void *buf) { | |
if (success) free(buf); | |
} | |
void *buf = malloc(512) <- freeWrapper; | |
read(open(path, O_RDONLY) <- closeWrapper, buf, 512); | |
success = true; | |
return buf; | |
} | |
/* Note that we have eliminated the file descriptor variable. Also, there is no | |
* fear in throwing a new exception in a destructor because, in Hammer, | |
* exceptions are aggregated and it is guaranteed that EVERY exception will | |
* either be caught or propagated to the toplevel (where it is usually printed | |
* verbatim to stderr) immediately after throwing. The main problem, now, is | |
* verbosity. Neither freeWrapper nor closeWrapper can be put into a library | |
* because it is conceivable that a function might want to preserve the opened | |
* file or the allocated buffer in the case of success. We want a generic way | |
* to let destructors know in what circumstances they were called. */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment