Skip to content

Optimize initialization and error paths #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 4, 2025
Merged
2 changes: 1 addition & 1 deletion man/nanonext-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 30 additions & 34 deletions src/aio.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,37 +508,39 @@ SEXP rnng_unresolved2(SEXP x) {
SEXP rnng_send_aio(SEXP con, SEXP data, SEXP mode, SEXP timeout, SEXP pipe, SEXP clo) {

const nng_duration dur = timeout == R_NilValue ? NNG_DURATION_DEFAULT : (nng_duration) nano_integer(timeout);

const int raw = nano_encodes(mode) == 2;
SEXP aio, env, fun;
nano_aio *saio;
nano_aio *saio = NULL;
nano_buf buf;
int sock, xc;

if ((sock = !NANO_PTR_CHECK(con, nano_SocketSymbol)) || !NANO_PTR_CHECK(con, nano_ContextSymbol)) {

const int pipeid = sock ? nano_integer(pipe) : 0;
nano_encodes(mode) == 2 ? nano_encode(&buf, data) : nano_serialize(&buf, data, NANO_PROT(con));
nng_msg *msg;
if (raw) {
nano_encode(&buf, data);
} else {
nano_serialize(&buf, data, NANO_PROT(con));
}
nng_msg *msg = NULL;

saio = calloc(1, sizeof(nano_aio));
NANO_ENSURE_ALLOC(saio);
if (saio == NULL) { xc = 2; goto failmem; }
saio->type = SENDAIO;

if ((xc = nng_msg_alloc(&msg, 0)))
goto exitlevel1;
if ((xc = nng_msg_alloc(&msg, 0)) ||
(xc = nng_msg_append(msg, buf.buf, buf.cur)) ||
(xc = nng_aio_alloc(&saio->aio, saio_complete, saio))) {
nng_msg_free(msg);
goto fail;
}

if (pipeid) {
nng_pipe p;
p.id = (uint32_t) pipeid;
nng_msg_set_pipe(msg, p);
}

if ((xc = nng_msg_append(msg, buf.buf, buf.cur)) ||
(xc = nng_aio_alloc(&saio->aio, saio_complete, saio))) {
nng_msg_free(msg);
goto exitlevel1;
}

nng_aio_set_msg(saio->aio, msg);
nng_aio_set_timeout(saio->aio, dur);
sock ? nng_send_aio(*(nng_socket *) NANO_PTR(con), saio->aio) :
Expand All @@ -557,19 +559,17 @@ SEXP rnng_send_aio(SEXP con, SEXP data, SEXP mode, SEXP timeout, SEXP pipe, SEXP
nng_iov iov;

saio = calloc(1, sizeof(nano_aio));
NANO_ENSURE_ALLOC(saio);
if (saio == NULL) { xc = 2; goto failmem; }
saio->type = IOV_SENDAIO;
saio->data = calloc(buf.cur, sizeof(unsigned char));
NANO_ENSURE_ALLOC_FREE(saio->data, saio);
if (saio->data == NULL) { xc = 2; goto failmem; }
memcpy(saio->data, buf.buf, buf.cur);
iov.iov_len = buf.cur - nst->textframes;
iov.iov_buf = saio->data;

if ((xc = nng_aio_alloc(&saio->aio, isaio_complete, saio)))
goto exitlevel2;

if ((xc = nng_aio_set_iov(saio->aio, 1u, &iov)))
goto exitlevel3;
if ((xc = nng_aio_alloc(&saio->aio, isaio_complete, saio)) ||
(xc = nng_aio_set_iov(saio->aio, 1u, &iov)))
goto fail;

nng_aio_set_timeout(saio->aio, dur);
nng_stream_send(sp, saio->aio);
Expand All @@ -594,11 +594,10 @@ SEXP rnng_send_aio(SEXP con, SEXP data, SEXP mode, SEXP timeout, SEXP pipe, SEXP
UNPROTECT(3);
return env;

exitlevel3:
fail:
nng_aio_free(saio->aio);
exitlevel2:
free(saio->data);
exitlevel1:
failmem:
NANO_FREE(buf);
free(saio);
return mk_error_data(-xc);
Expand All @@ -617,7 +616,7 @@ SEXP rnng_recv_aio(SEXP con, SEXP mode, SEXP timeout, SEXP cvar, SEXP bytes, SEX
interrupt = 1 - signal;
}
nano_cv *ncv = signal ? (nano_cv *) NANO_PTR(cvar) : NULL;
nano_aio *raio;
nano_aio *raio = NULL;
SEXP aio, env, fun;
int sock, xc;

Expand All @@ -631,7 +630,7 @@ SEXP rnng_recv_aio(SEXP con, SEXP mode, SEXP timeout, SEXP cvar, SEXP bytes, SEX
raio->mode = mod;

if ((xc = nng_aio_alloc(&raio->aio, interrupt ? raio_complete_interrupt : raio_complete, raio)))
goto exitlevel1;
goto fail;

nng_aio_set_timeout(raio->aio, dur);
sock ? nng_recv_aio(*(nng_socket *) NANO_PTR(con), raio->aio) :
Expand All @@ -653,15 +652,13 @@ SEXP rnng_recv_aio(SEXP con, SEXP mode, SEXP timeout, SEXP cvar, SEXP bytes, SEX
raio->type = signal ? IOV_RECVAIOS : IOV_RECVAIO;
raio->mode = mod;
raio->data = calloc(xlen, sizeof(unsigned char));
NANO_ENSURE_ALLOC_FREE(raio->data, raio);
NANO_ENSURE_ALLOC(raio->data);
iov.iov_len = xlen;
iov.iov_buf = raio->data;

if ((xc = nng_aio_alloc(&raio->aio, iraio_complete, raio)))
goto exitlevel2;

if ((xc = nng_aio_set_iov(raio->aio, 1u, &iov)))
goto exitlevel3;
if ((xc = nng_aio_alloc(&raio->aio, iraio_complete, raio)) ||
(xc = nng_aio_set_iov(raio->aio, 1u, &iov)))
goto fail;

nng_aio_set_timeout(raio->aio, dur);
nng_stream_recv(*sp, raio->aio);
Expand All @@ -683,11 +680,10 @@ SEXP rnng_recv_aio(SEXP con, SEXP mode, SEXP timeout, SEXP cvar, SEXP bytes, SEX
UNPROTECT(3);
return env;

exitlevel3:
fail:
nng_aio_free(raio->aio);
exitlevel2:
free(raio->data);
exitlevel1:
failmem:
free(raio);
return mk_error_data(xc);

Expand Down
Loading
Loading