diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-04-23 06:54:45 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-04-23 06:54:45 -0700 |
commit | 7fbf6b853893f65193ea9c81cf467be08c651244 (patch) | |
tree | 23f312ec0794edc5d653f67a652317f1b05e5502 /sysif.c | |
parent | 269044136fa1d73a6bc1a764211cc18119bc1207 (diff) | |
download | txr-7fbf6b853893f65193ea9c81cf467be08c651244.tar.gz txr-7fbf6b853893f65193ea9c81cf467be08c651244.tar.bz2 txr-7fbf6b853893f65193ea9c81cf467be08c651244.zip |
poll: allow execution of async signal handlers.
* sysif.c (poll_wrap): Allocate poll array using alloca so it
will be disposed of naturally if an exception occurs.
Place sig_save_enable and sig_restore_disable around poll call
to allow non-deferred handler execution.
Diffstat (limited to 'sysif.c')
-rw-r--r-- | sysif.c | 15 |
1 files changed, 7 insertions, 8 deletions
@@ -1311,7 +1311,7 @@ static val poll_wrap(val poll_list, val timeout_in) { nfds_t i, len = c_num(length(poll_list)); val iter; - struct pollfd *pfd = coerce(struct pollfd *, chk_calloc(len, sizeof *pfd)); + struct pollfd *pfd = coerce(struct pollfd *, alloca(len * sizeof *pfd)); val timeout = default_arg(timeout_in, negone); int res; @@ -1346,18 +1346,18 @@ static val poll_wrap(val poll_list, val timeout_in) } } + sig_save_enable; + res = poll(pfd, len, c_num(timeout)); - if (res < 0) { - free(pfd); + sig_restore_enable; + + if (res < 0) uw_throwf(file_error_s, lit("poll failed: ~d/~s"), num(errno), string_utf8(strerror(errno)), nao); - } - if (res == 0) { - free(pfd); + if (res == 0) return nil; - } { list_collect_decl (out, ptail); @@ -1368,7 +1368,6 @@ static val poll_wrap(val poll_list, val timeout_in) ptail = list_collect(ptail, cons(car(pair), num(pfd[i].revents))); } - free(pfd); return out; } } |