2020#define NANONEXT_SUPPLEMENTALS
2121#define NANONEXT_SIGNALS
2222#include "nanonext.h"
23+ #include "later_shim.h"
2324
2425// internals -------------------------------------------------------------------
2526
@@ -195,6 +196,21 @@ static void isaio_complete(void *arg) {
195196
196197}
197198
199+
200+ static void raio_invoke_cb (void * arg ) {
201+ nano_aio * raio = (nano_aio * ) arg ;
202+ if (raio -> cb == NULL || Rf_isNull (raio -> cb )) return ;
203+ SEXP func = (SEXP )raio -> cb ;
204+ SEXP callExpr , result ;
205+ if (!Rf_isNull (func )) {
206+ PROTECT (callExpr = Rf_lcons (func , R_NilValue )); // Prepare call
207+ PROTECT (result = Rf_eval (callExpr , R_GlobalEnv )); // Execute call
208+
209+ UNPROTECT (2 );
210+ R_ReleaseObject (func );
211+ }
212+ }
213+
198214static void raio_complete (void * arg ) {
199215
200216 nano_aio * raio = (nano_aio * ) arg ;
@@ -210,6 +226,7 @@ static void raio_complete(void *arg) {
210226 raio -> result = res - !res ;
211227#endif
212228
229+ later2 (raio_invoke_cb , arg , 0 );
213230}
214231
215232static void raio_complete_signal (void * arg ) {
@@ -229,6 +246,7 @@ static void raio_complete_signal(void *arg) {
229246 nng_cv_wake (cv );
230247 nng_mtx_unlock (mtx );
231248
249+ later2 (raio_invoke_cb , arg , 0 );
232250}
233251
234252static void request_complete_signal (void * arg ) {
@@ -709,7 +727,7 @@ SEXP rnng_send_aio(SEXP con, SEXP data, SEXP mode, SEXP timeout, SEXP clo) {
709727}
710728
711729SEXP rnng_recv_aio_impl (const SEXP con , const SEXP mode , const SEXP timeout ,
712- const SEXP bytes , const SEXP clo , nano_cv * ncv ) {
730+ const SEXP bytes , const SEXP clo , const SEXP cb , nano_cv * ncv ) {
713731
714732 const nng_duration dur = timeout == R_NilValue ? NNG_DURATION_DEFAULT : (nng_duration ) Rf_asInteger (timeout );
715733 const int signal = ncv != NULL ;
@@ -725,6 +743,12 @@ SEXP rnng_recv_aio_impl(const SEXP con, const SEXP mode, const SEXP timeout,
725743 raio -> next = ncv ;
726744 raio -> type = RECVAIO ;
727745 raio -> mode = mod ;
746+ if (Rf_isNull (cb )) {
747+ raio -> cb = NULL ;
748+ } else {
749+ R_PreserveObject (cb );
750+ raio -> cb = (void * )cb ;
751+ }
728752
729753 if ((xc = nng_aio_alloc (& raio -> aio , signal ? raio_complete_signal : raio_complete , raio )))
730754 goto exitlevel1 ;
@@ -791,19 +815,19 @@ SEXP rnng_recv_aio_impl(const SEXP con, const SEXP mode, const SEXP timeout,
791815
792816}
793817
794- SEXP rnng_recv_aio (SEXP con , SEXP mode , SEXP timeout , SEXP bytes , SEXP clo ) {
818+ SEXP rnng_recv_aio (SEXP con , SEXP mode , SEXP timeout , SEXP bytes , SEXP clo , SEXP cb ) {
795819
796- return rnng_recv_aio_impl (con , mode , timeout , bytes , clo , NULL );
820+ return rnng_recv_aio_impl (con , mode , timeout , bytes , clo , cb , NULL );
797821
798822}
799823
800- SEXP rnng_recv_aio_signal (SEXP con , SEXP cvar , SEXP mode , SEXP timeout , SEXP bytes , SEXP clo ) {
824+ SEXP rnng_recv_aio_signal (SEXP con , SEXP cvar , SEXP mode , SEXP timeout , SEXP bytes , SEXP clo , SEXP cb ) {
801825
802826 if (R_ExternalPtrTag (cvar ) != nano_CvSymbol )
803827 Rf_error ("'cv' is not a valid Condition Variable" );
804828 nano_cv * ncv = (nano_cv * ) R_ExternalPtrAddr (cvar );
805829
806- return rnng_recv_aio_impl (con , mode , timeout , bytes , clo , ncv );
830+ return rnng_recv_aio_impl (con , mode , timeout , bytes , clo , cb , ncv );
807831
808832}
809833
0 commit comments