bdd_io_read_pending
This commit is contained in:
parent
3421533b73
commit
09889c1055
|
@ -21,6 +21,12 @@ __attribute__((warn_unused_result)) ssize_t bdd_io_read(
|
|||
void *buf,
|
||||
ssize_t sz
|
||||
);
|
||||
__attribute__((warn_unused_result)) ssize_t bdd_io_read_pending(
|
||||
struct bdd_conversation *conversation,
|
||||
bdd_io_id io_id,
|
||||
void *buf,
|
||||
ssize_t sz
|
||||
);
|
||||
__attribute__((warn_unused_result)) ssize_t bdd_io_write(
|
||||
struct bdd_conversation *conversation,
|
||||
bdd_io_id io_id,
|
||||
|
|
61
bdd/src/io.c
61
bdd/src/io.c
|
@ -281,6 +281,67 @@ __attribute__((warn_unused_result)) ssize_t bdd_io_read(
|
|||
}
|
||||
}
|
||||
return r;
|
||||
|
||||
conversation_discard:;
|
||||
conversation->remove = true;
|
||||
return -3;
|
||||
}
|
||||
|
||||
__attribute__((warn_unused_result)) ssize_t bdd_io_read_pending(
|
||||
struct bdd_conversation *conversation,
|
||||
bdd_io_id io_id,
|
||||
void *buf,
|
||||
ssize_t sz
|
||||
) {
|
||||
if (conversation->remove) {
|
||||
fputs("programming error: bdd_io_read_pending called with an io_id of a discarded conversation\n", stderr);
|
||||
abort();
|
||||
return -1;
|
||||
}
|
||||
struct bdd_io *io = bdd_io(conversation, io_id);
|
||||
if (io == NULL || buf == NULL || sz <= 0 || conversation->n_blocking > 0) {
|
||||
fputs("programming error: bdd_io_read_pending called with invalid arguments\n", stderr);
|
||||
abort();
|
||||
return -1;
|
||||
}
|
||||
if (io->state < bdd_io_est || io->rdhup) {
|
||||
fputs("programming error: bdd_io_read_pending called with an io_id which is in an invalid state\n", stderr);
|
||||
abort();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!io->ssl) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pending = SSL_pending(io->io.ssl);
|
||||
if (!pending) {
|
||||
return 0;
|
||||
}
|
||||
if (pending < sz) {
|
||||
sz = pending;
|
||||
}
|
||||
ssize_t r = SSL_read(io->io.ssl, buf, sz);
|
||||
if (r <= 0) {
|
||||
int err = SSL_get_error(io->io.ssl, r);
|
||||
if (err == SSL_ERROR_WANT_WRITE) {
|
||||
abort(); // fuck re-negotiation
|
||||
} else if (err == SSL_ERROR_ZERO_RETURN /* received close_notify */) {
|
||||
if (bdd_io_hup(io, true)) {
|
||||
if (!bdd_io_discard(io)) {
|
||||
goto conversation_discard;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
bdd_io_epoll_mod(io, bdd_epoll_in, 0, false);
|
||||
return -4;
|
||||
} else if (err == SSL_ERROR_WANT_READ) {
|
||||
abort();
|
||||
}
|
||||
goto conversation_discard;
|
||||
}
|
||||
return r;
|
||||
|
||||
conversation_discard:;
|
||||
conversation->remove = true;
|
||||
return -3;
|
||||
|
|
|
@ -21,7 +21,13 @@ struct associated {
|
|||
static inline uint8_t serve(struct bdd_conversation *conversation, bdd_io_id from, bdd_io_id to) {
|
||||
struct associated *associated = bdd_get_associated(conversation);
|
||||
for (size_t it = 0;; ++it) {
|
||||
ssize_t r = associated->n[to] = bdd_io_read(conversation, from, &(associated->buf[clsvb(to)]), buf_sz_each);
|
||||
ssize_t r;
|
||||
if (it < 10) {
|
||||
r = bdd_io_read(conversation, from, &(associated->buf[clsvb(to)]), buf_sz_each);
|
||||
} else {
|
||||
r = bdd_io_read_pending(conversation, from, &(associated->buf[clsvb(to)]), buf_sz_each);
|
||||
}
|
||||
associated->n[to] = r;
|
||||
if (r <= 0) {
|
||||
return r * -1;
|
||||
}
|
||||
|
@ -99,8 +105,7 @@ void general_service__handle_events(struct bdd_conversation *conversation) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return;
|
||||
|
||||
err:;
|
||||
|
|
Loading…
Reference in New Issue