diff --git a/test/agent/Makefile.am b/test/agent/Makefile.am index b031ff6e33fcbbc4623bc99f9767336e569d8320..8e0df4771b01570b3181f9e9dead5db90ce0cf5a 100644 --- a/test/agent/Makefile.am +++ b/test/agent/Makefile.am @@ -23,6 +23,7 @@ MODULES = \ examples/active-agent.scm \ examples/passive-agent.scm \ jami/logger.scm \ + jami/signal.scm \ scenarios/peer-monitor/scenario.scm GOBJECTS = $(MODULES:%=%.go) diff --git a/test/agent/jami/signal.scm b/test/agent/jami/signal.scm new file mode 100644 index 0000000000000000000000000000000000000000..ba33c3c5934a0c0d930f0989dacdcc8debf7a5cb --- /dev/null +++ b/test/agent/jami/signal.scm @@ -0,0 +1,58 @@ +(define-module (jami signal) + #:use-module (ice-9 atomic) + #:use-module (ice-9 format) + #:use-module (ice-9 threads) + #:use-module (jami logger) + #:use-module (jami signal bindings) + #:re-export (on-signal) + #:export-syntax (with-signal + with-signal-sync) + #:export (log-signal)) + +;;; Install for signal SIG an HANDLER and execute bodies. HANDLER is removed +;;; for SIG at the exit of the dynamic extent. +(define-syntax-rule (with-signal sig handler body body* ...) + (let ([continue? (make-atomic-box #t)]) + (dynamic-wind + (const #f) + (lambda () + (on-signal + sig + (lambda args + (let ([continue? (atomic-box-ref continue?)]) + (when continue? (apply handler args)) + continue?))) + body + body* ...) + (lambda () (atomic-box-set! continue? #f))))) + +(define* (wait-cnd cnd mtx #:optional timeout) + (if timeout + (wait-condition-variable cnd mtx (+ (current-time) timeout)) + (wait-condition-variable cnd mtx))) + +;;; Synchronize with Jami's signal. Install signal handler for SIG and wait for +;;; either PRED to return #t or that TIMEOUT seconds has expired, after TRIGGERS +;;; are been executed. +(define-syntax with-signal-sync + (syntax-rules () + [(_ sig pred) (with-signal-sync sig pred #f #f)] + [(_ sig pred timeout) (with-signal-sync sig pred timeout #f)] + [(_ sig pred timeout triggers ...) + (let ([mtx (make-recursive-mutex)] + [cnd (make-condition-variable)]) + (with-mutex mtx + (on-signal sig (lambda args + (let ([sync? (apply pred args)]) + (when sync? + (with-mutex mtx + (signal-condition-variable cnd))) + (not sync?)))) + (begin triggers ...) + (wait-cnd cnd mtx timeout)))])) + +;;; Install signal handler for SIG that print the arguments of the signal. +(define (log-signal sig) + (on-signal sig (lambda args + (info "Signal ~a:~{ ~a~}" sig args) + #t))) diff --git a/test/agent/src/bindings/bindings.cpp b/test/agent/src/bindings/bindings.cpp index ca076fdcaf2356f4edab2cb35f2b6ffca9d5780c..6fc36ee44ef45388096473cca62ec82ae16fbafc 100644 --- a/test/agent/src/bindings/bindings.cpp +++ b/test/agent/src/bindings/bindings.cpp @@ -40,7 +40,7 @@ install_scheme_primitives() load_module("jami call", install_call_primitives); load_module("jami conversation", install_conversation_primitives); load_module("jami logger bindings", install_logger_primitives); - load_module("jami signal", install_signal_primitives); + load_module("jami signal bindings", install_signal_primitives); } /*