mirror of
https://github.com/janet-lang/janet
synced 2025-02-21 18:50:02 +00:00
Add more cases for checking coerce error.
Channel operations inside a janet_call could wreak more havoc later, when scheduled fibers are shooting off when they shouldn't be. The easiest way to prevent this is simply check that we are not inside janet_call before doing channel operations. We also get nicer error messages this way.
This commit is contained in:
parent
2e6001316a
commit
3441bcbd69
@ -64,6 +64,11 @@ void janet_signalv(JanetSignal sig, Janet message) {
|
||||
if (janet_vm.return_reg != NULL) {
|
||||
/* Should match logic in janet_call for coercing everything not ok to an error (no awaits, yields, etc.) */
|
||||
if (janet_vm.coerce_error && sig != JANET_SIGNAL_OK) {
|
||||
#ifdef JANET_EV
|
||||
if (NULL != janet_vm.root_fiber && sig == JANET_SIGNAL_EVENT) {
|
||||
janet_vm.root_fiber->sched_id++;
|
||||
}
|
||||
#endif
|
||||
if (sig != JANET_SIGNAL_ERROR) {
|
||||
message = janet_wrap_string(janet_formatc("%v coerced from %s to error", message, janet_signal_names[sig]));
|
||||
}
|
||||
|
@ -1037,6 +1037,9 @@ JANET_CORE_FN(cfun_channel_push,
|
||||
"Returns the channel if the write succeeded, nil otherwise.") {
|
||||
janet_fixarity(argc, 2);
|
||||
JanetChannel *channel = janet_getchannel(argv, 0);
|
||||
if (janet_vm.coerce_error) {
|
||||
janet_panic("cannot give to channel inside janet_call");
|
||||
}
|
||||
if (janet_channel_push(channel, argv[1], 0)) {
|
||||
janet_await();
|
||||
}
|
||||
@ -1049,6 +1052,9 @@ JANET_CORE_FN(cfun_channel_pop,
|
||||
janet_fixarity(argc, 1);
|
||||
JanetChannel *channel = janet_getchannel(argv, 0);
|
||||
Janet item;
|
||||
if (janet_vm.coerce_error) {
|
||||
janet_panic("cannot take from channel inside janet_call");
|
||||
}
|
||||
if (janet_channel_pop(channel, &item, 0)) {
|
||||
janet_schedule(janet_vm.root_fiber, item);
|
||||
}
|
||||
@ -1085,6 +1091,10 @@ JANET_CORE_FN(cfun_channel_choice,
|
||||
int32_t len;
|
||||
const Janet *data;
|
||||
|
||||
if (janet_vm.coerce_error) {
|
||||
janet_panic("cannot select from channel inside janet_call");
|
||||
}
|
||||
|
||||
/* Check channels for immediate reads and writes */
|
||||
for (int32_t i = 0; i < argc; i++) {
|
||||
if (janet_indexed_view(argv[i], &data, &len) && len == 2) {
|
||||
|
@ -1388,6 +1388,11 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
|
||||
|
||||
if (signal != JANET_SIGNAL_OK) {
|
||||
/* Should match logic in janet_signalv */
|
||||
#ifdef JANET_EV
|
||||
if (janet_vm.root_fiber != NULL && signal == JANET_SIGNAL_EVENT) {
|
||||
janet_vm.root_fiber->sched_id++;
|
||||
}
|
||||
#endif
|
||||
if (signal != JANET_SIGNAL_ERROR) {
|
||||
*janet_vm.return_reg = janet_wrap_string(janet_formatc("%v coerced from %s to error", *janet_vm.return_reg, janet_signal_names[signal]));
|
||||
}
|
||||
|
@ -482,6 +482,14 @@
|
||||
(:close chat-server)
|
||||
|
||||
# Issue #1531
|
||||
(defn sleep-print [x] (ev/sleep 0) (print x))
|
||||
(protect (with-dyns [*out* sleep-print] (prin :foo)))
|
||||
(defn level-trigger-handling [conn &] (:close conn))
|
||||
(def s (assert (net/server test-host test-port level-trigger-handling)))
|
||||
(def c (assert (net/connect test-host test-port)))
|
||||
(:close s)
|
||||
|
||||
# Issue #1531 no. 2
|
||||
(def c (ev/chan 0))
|
||||
(ev/spawn (while (def x (ev/take c))))
|
||||
(defn print-to-chan [x] (ev/give c x))
|
||||
|
Loading…
x
Reference in New Issue
Block a user