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.
@@ -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;
