[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] concurrency-libtask 38b61be 06/10: Transfer signals to mai
From: |
Philipp Stephani |
Subject: |
[Emacs-diffs] concurrency-libtask 38b61be 06/10: Transfer signals to main coroutine |
Date: |
Wed, 26 Oct 2016 21:32:44 +0000 (UTC) |
branch: concurrency-libtask
commit 38b61be088b6ac59da56b4541f6bbe17c23c843a
Author: Philipp Stephani <address@hidden>
Commit: Philipp Stephani <address@hidden>
Transfer signals to main coroutine
---
src/coroutine.c | 66 +++++++++++++++++++++++++++++++++++++++++++
src/emacs.c | 2 ++
src/lisp.h | 1 +
test/src/coroutine-tests.el | 5 ++++
4 files changed, 74 insertions(+)
diff --git a/src/coroutine.c b/src/coroutine.c
index 601773a..5eae40b 100644
--- a/src/coroutine.c
+++ b/src/coroutine.c
@@ -73,11 +73,17 @@ coroutine_reset_handlerlist (const int *dummy)
handlerlist = handlerlist->next;
}
+static bool pending_error;
+
/* Called on `signal'. ERR is a pair (SYMBOL . DATA). */
static void
coroutine_handle_signal (Lisp_Object err)
{
+ eassert (! pending_error);
print_error_message (err, Qnil, "signal in coroutine caught: ", Qnil);
+ pending_error = true;
+ Vpending_coroutine_error_symbol = XCAR (err);
+ Vpending_coroutine_error_data = XCDR (err);
taskexit (1);
}
@@ -85,14 +91,22 @@ coroutine_handle_signal (Lisp_Object err)
static void
coroutine_handle_throw (Lisp_Object tag_val)
{
+ eassert (! pending_error);
print_error_message (tag_val, Qnil, "throw in coroutine caught: ", Qnil);
+ pending_error = true;
+ Vpending_coroutine_error_symbol = Qno_catch;
+ Vpending_coroutine_error_data = list2 (XCAR (tag_val), XCDR (tag_val));
taskexit (1);
}
static void
coroutine_out_of_memory (void)
{
+ eassert (! pending_error);
fputs ("OOM in coroutine\n", stderr);
+ pending_error = true;
+ Vpending_coroutine_error_symbol = Qnil;
+ Vpending_coroutine_error_data = Vmemory_signal_data;
taskexit (1);
}
@@ -124,6 +138,37 @@ DEFUN ("start-coroutine", Fstart_coroutine,
Sstart_coroutine, 1, 1, 0,
return Qnil;
}
+static unsigned int main_task_id;
+
+static bool
+in_main_task (void)
+{
+ return taskid () == main_task_id;
+}
+
+static void
+check_coroutine_signal (void)
+{
+ if (! pending_error)
+ return;
+ if (in_main_task ())
+ {
+ pending_error = false;
+ Lisp_Object symbol = Vpending_coroutine_error_symbol;
+ Lisp_Object data = Vpending_coroutine_error_data;
+ eassert (SYMBOLP (symbol) || CONSP (data));
+ Vpending_coroutine_error_symbol = Qnil;
+ Vpending_coroutine_error_data = Qnil;
+ xsignal (symbol, data);
+ }
+ else
+ {
+ int woken = taskyield ();
+ eassert (woken > 0);
+ eassert (! pending_error);
+ }
+}
+
static void
CHECK_CHANNEL (Lisp_Object x)
{
@@ -149,6 +194,7 @@ CHANNEL must be a communication channel created by
`make-channel'. */)
Lisp_Object result;
int status = chanrecv (XCHANNEL (channel)->channel, &result);
eassert (status == 1);
+ check_coroutine_signal ();
return result;
}
@@ -177,6 +223,7 @@ created by `make-channel'. */)
CHECK_CHANNEL (channel);
int status = chansend (XCHANNEL (channel)->channel, &value);
eassert (status == 1);
+ check_coroutine_signal ();
return Qnil;
}
@@ -315,6 +362,7 @@ is returned. */)
// Actually perform the select operation.
int choice = chanalt (alts);
+ check_coroutine_signal ();
if (choice == -1)
{
@@ -381,16 +429,34 @@ pselect_noblock (int nfds,
};
taskcreate (do_pselect, &args, 0x1000);
tasksleep (&args.rendez);
+ check_coroutine_signal ();
return args.result;
}
void
+coroutine_init (void)
+{
+ main_task_id = taskid ();
+ pending_error = false;
+}
+
+void
syms_of_coroutine (void)
{
DEFSYM (Qchannelp, "channelp");
DEFSYM (Qreceive, "receive");
DEFSYM (Qsend, "send");
+ DEFVAR_LISP ("pending-coroutine-error-symbol",
Vpending_coroutine_error_symbol,
+ doc: /* Pending error symbol. */);
+ DEFSYM (Qpending_coroutine_error_symbol, "pending-coroutine-error-symbol");
+ Funintern (Qpending_coroutine_error_symbol, Qnil);
+
+ DEFVAR_LISP ("pending-coroutine-error-data", Vpending_coroutine_error_data,
+ doc: /* Pending error data. */);
+ DEFSYM (Qpending_coroutine_error_data, "pending-coroutine-error-data");
+ Funintern (Qpending_coroutine_error_data, Qnil);
+
defsubr (&Sstart_coroutine);
defsubr (&Sreceive_from_channel);
defsubr (&Stry_receive_from_channel);
diff --git a/src/emacs.c b/src/emacs.c
index adb972e..474e87f 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -748,6 +748,8 @@ taskmain (int argc, char **argv)
module_init ();
#endif
+ coroutine_init ();
+
sort_args (argc, argv);
argc = 0;
while (argv[argc]) argc++;
diff --git a/src/lisp.h b/src/lisp.h
index 7efdd45..3d69f34 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3436,6 +3436,7 @@ extern void init_coding_once (void);
extern void syms_of_coding (void);
/* Defined in coroutine.c. */
+extern void coroutine_init (void);
extern void syms_of_coroutine (void);
/* Defined in character.c. */
diff --git a/test/src/coroutine-tests.el b/test/src/coroutine-tests.el
index d86fe6c..778f3de 100644
--- a/test/src/coroutine-tests.el
+++ b/test/src/coroutine-tests.el
@@ -163,4 +163,9 @@
;; (receive-from-channel ch-2)
;; (send-to-channel ch-1 nil)))
+(ert-deftest coroutines-test--signal ()
+ (start-coroutine (lambda () (signal 'beginning-of-buffer '(foo))))
+ (let ((err (should-error (sleep-for 0.1))))
+ (should (equal err '(beginning-of-buffer foo)))))
+
;;; coroutine-tests.el ends here
- [Emacs-diffs] concurrency-libtask updated (6852791 -> 9d613e5), Philipp Stephani, 2016/10/26
- [Emacs-diffs] concurrency-libtask f6aa233 09/10: Revert change in fd_handler., Philipp Stephani, 2016/10/26
- [Emacs-diffs] concurrency-libtask b09d4ba 08/10: Fix format specifiers, Philipp Stephani, 2016/10/26
- [Emacs-diffs] concurrency-libtask 38b61be 06/10: Transfer signals to main coroutine,
Philipp Stephani <=
- [Emacs-diffs] concurrency-libtask 0875d8d 05/10: Remove wrong assertion, Philipp Stephani, 2016/10/26
- [Emacs-diffs] concurrency-libtask b075dc7 04/10: malloc is redefined by config.h, Philipp Stephani, 2016/10/26
- [Emacs-diffs] concurrency-libtask 3a1331b 01/10: Clarify the behavior of minor mode commands, Philipp Stephani, 2016/10/26
- [Emacs-diffs] concurrency-libtask 7be3718 07/10: Add missing defsubr, Philipp Stephani, 2016/10/26
- [Emacs-diffs] concurrency-libtask a856316 03/10: Support for Windows fibers, Philipp Stephani, 2016/10/26
- [Emacs-diffs] concurrency-libtask 9d613e5 10/10: Merge branch 'concurrency-libtask' of git.sv.gnu.org:/srv/git/emacs into concurrency-libtask, Philipp Stephani, 2016/10/26
- [Emacs-diffs] concurrency-libtask ee44c80 02/10: WIP: CSP based on libtask, Philipp Stephani, 2016/10/26