Skip to content

Commit 58b231a

Browse files
committed
allow user interrupts
1 parent 952ccfe commit 58b231a

File tree

3 files changed

+21
-25
lines changed

3 files changed

+21
-25
lines changed

R/server.R

+4-3
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@
3232
#' string (if of the appropriate type), or otherwise a serialized R object,
3333
#' which should be passed to \code{\link{unserialize}}.
3434
#'
35-
#' Use only in a new session. Use \sQuote{ctrl + \\} to forcibly quit
36-
#' when finished as the function blocks with no means of interruption.
37-
#'
3835
#' If the expression could not be parsed or evaluated, the response will be
3936
#' returned with a status code of 500 and a blank body.
4037
#'
38+
#' User interrupts will only be processed after the next query has been
39+
#' completed, hence return from the function may not be immediate. Use
40+
#' \sQuote{ctrl + \\} to forcibly quit the entire R session if required.
41+
#'
4142
#' @return This function never returns.
4243
#'
4344
#' @examples

man/server.Rd

+4-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/server.c

+13-19
Original file line numberDiff line numberDiff line change
@@ -243,25 +243,30 @@ void parse_eval_safe(void *data) {
243243
nano_parse_eval_res = R_ParseEvalString((const char *) data, R_GlobalEnv);
244244
}
245245

246-
void inproc_server(const char* url) {
246+
SEXP rnng_rest_server(SEXP url) {
247247

248+
const char *addr[2] = {CHAR(STRING_ELT(url, 0)), "inproc://n-a-n-o-serv"};
249+
nng_thread *thr;
248250
nng_socket s;
249251
nng_msg *msg;
250252
int xc;
251253

252-
if ((xc = nng_rep0_open(&s)) || (xc = nng_listen(s, url, NULL, 0)))
254+
if ((xc = nng_thread_create(&thr, rest_start, (void *) addr)))
255+
ERROR_OUT(xc);
256+
257+
if ((xc = nng_rep0_open(&s)) ||
258+
(xc = nng_listen(s, addr[1], NULL, 0)))
253259
fatal("unable to set up inproc", xc);
254260

255261
for (;;) {
262+
256263
if ((xc = nng_recvmsg(s, &msg, 0)))
257264
fatal("inproc recvmsg", xc);
258265

259-
const char *body = nng_msg_body(msg);
260-
nano_buf buf;
261-
262266
nano_parse_eval_res = R_BlankScalarString;
263-
R_ToplevelExec(parse_eval_safe, (void *) body);
267+
R_ToplevelExec(parse_eval_safe, (void *) nng_msg_body(msg));
264268

269+
nano_buf buf;
265270
if (TYPEOF(nano_parse_eval_res) == STRSXP) {
266271
const char *string = NANO_STRING(nano_parse_eval_res);
267272
buf.buf = (unsigned char *) string;
@@ -274,20 +279,9 @@ void inproc_server(const char* url) {
274279
if ((xc = nng_sendmsg(s, msg, 0)))
275280
fatal("inproc sendmsg", xc);
276281

277-
}
282+
R_CheckUserInterrupt();
278283

279-
}
280-
281-
SEXP rnng_rest_server(SEXP url) {
282-
283-
const char *addr[2] = {CHAR(STRING_ELT(url, 0)), "inproc://n-a-n-o-serv"};
284-
nng_thread *thr;
285-
int xc;
286-
287-
if ((xc = nng_thread_create(&thr, rest_start, (void *) addr)))
288-
ERROR_OUT(xc);
289-
290-
inproc_server(addr[1]);
284+
}
291285

292286
nng_thread_destroy(thr);
293287
return R_NilValue;

0 commit comments

Comments
 (0)