Move try-read logic to relay_start

Previously we tried to avoid attaching to server connection
by read-testing client before attach. This does not work well
when client wants to disconnect: we read from client twice,
and it happens after Term(X,88) message from client.
To avoid this problem we move read-tesing to start of relay.
This commit is contained in:
Andrey 2020-01-21 12:01:55 +05:00 committed by kirill reshke
parent 8496cde80a
commit ec0882609c
1 changed files with 23 additions and 14 deletions

View File

@ -30,6 +30,8 @@ struct od_relay
void *on_read_arg;
};
static inline od_status_t od_relay_read(od_relay_t *relay);
static inline void
od_relay_init(od_relay_t *relay, od_io_t *io)
{
@ -58,6 +60,14 @@ od_relay_free(od_relay_t *relay)
machine_iov_free(relay->iov);
}
static inline bool
od_relay_data_pending(od_relay_t *relay)
{
char *current = od_readahead_pos_read(&relay->src->readahead);
char *end = od_readahead_pos(&relay->src->readahead);
return current < end;
}
static inline od_status_t
od_relay_start(od_relay_t *relay,
machine_cond_t *base,
@ -89,6 +99,19 @@ od_relay_start(od_relay_t *relay,
if (rc == -1)
return relay->error_read;
// If there is no new data from client we must reset read condition
// to avoid attaching to a new server connection
if (machine_cond_try(relay->src->on_read)) {
rc = od_relay_read(relay);
if (rc != OD_OK)
return rc;
if (od_relay_data_pending(relay)) {
// Seems like some data arrived
machine_cond_signal(relay->src->on_read);
}
}
return OD_OK;
}
@ -246,14 +269,6 @@ od_relay_process(od_relay_t *relay, int *progress, char *data, int size)
return OD_OK;
}
static inline bool
od_relay_data_pending(od_relay_t *relay)
{
char *current = od_readahead_pos_read(&relay->src->readahead);
char *end = od_readahead_pos(&relay->src->readahead);
return current < end;
}
static inline od_status_t
od_relay_pipeline(od_relay_t *relay)
{
@ -334,12 +349,6 @@ od_relay_step(od_relay_t *relay)
if (machine_cond_try(relay->src->on_read))
{
if (relay->dst == NULL) {
rc = od_relay_read(relay);
if (rc != OD_OK)
return rc;
if (!od_relay_data_pending(relay))
return OD_OK;
/* signal to retry on read logic */
machine_cond_signal(relay->src->on_read);
return OD_ATTACH;