Skip to content

Commit

Permalink
Retain QUIT_SEND connection state
Browse files Browse the repository at this point in the history
If the server goes away while reading a packet, don't go back into
the READY state. This will just cause broken pipe errors down the
line.
  • Loading branch information
nikic committed Oct 29, 2020
1 parent a66d73d commit 24537a7
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 4 deletions.
4 changes: 3 additions & 1 deletion ext/mysqlnd/mysqlnd_ps.c
Expand Up @@ -888,7 +888,9 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi
COPY_CLIENT_ERROR(stmt->error_info, row_packet->error_info);
}
}
SET_CONNECTION_STATE(&conn->state, CONN_READY);
if (GET_CONNECTION_STATE(&conn->state) != CONN_QUIT_SENT) {
SET_CONNECTION_STATE(&conn->state, CONN_READY);
}
result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */
} else if (row_packet->eof) {
DBG_INF("EOF");
Expand Down
8 changes: 6 additions & 2 deletions ext/mysqlnd/mysqlnd_result.c
Expand Up @@ -743,7 +743,9 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
COPY_CLIENT_ERROR(conn->error_info, row_packet->error_info);
DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
}
SET_CONNECTION_STATE(&conn->state, CONN_READY);
if (GET_CONNECTION_STATE(&conn->state) != CONN_QUIT_SENT) {
SET_CONNECTION_STATE(&conn->state, CONN_READY);
}
result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */
} else if (row_packet->eof) {
/* Mark the connection as usable again */
Expand Down Expand Up @@ -881,7 +883,9 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void
COPY_CLIENT_ERROR(conn->error_info, row_packet->error_info);
DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
}
SET_CONNECTION_STATE(&conn->state, CONN_READY);
if (GET_CONNECTION_STATE(&conn->state) != CONN_QUIT_SENT) {
SET_CONNECTION_STATE(&conn->state, CONN_READY);
}
result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */
} else if (row_packet->eof) {
/* Mark the connection as usable again */
Expand Down
5 changes: 4 additions & 1 deletion ext/mysqlnd/mysqlnd_wireprotocol.c
Expand Up @@ -1370,6 +1370,7 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,
MYSQLND_VIO * vio,
MYSQLND_STATS * stats,
MYSQLND_ERROR_INFO * error_info,
MYSQLND_CONNECTION_STATE * connection_state,
MYSQLND_MEMORY_POOL * pool,
MYSQLND_ROW_BUFFER * buffer,
size_t * const data_size)
Expand Down Expand Up @@ -1405,6 +1406,7 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,

if (UNEXPECTED(PASS != (ret = pfc->data->m.receive(pfc, vio, p, header.size, stats, error_info)))) {
DBG_ERR("Empty row packet body");
SET_CONNECTION_STATE(connection_state, CONN_QUIT_SENT);
set_packet_error(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
} else {
while (header.size >= MYSQLND_MAX_PACKET_SIZE) {
Expand Down Expand Up @@ -1434,6 +1436,7 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,

if (PASS != (ret = pfc->data->m.receive(pfc, vio, p, header.size, stats, error_info))) {
DBG_ERR("Empty row packet body");
SET_CONNECTION_STATE(connection_state, CONN_QUIT_SENT);
set_packet_error(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
break;
}
Expand Down Expand Up @@ -1740,7 +1743,7 @@ php_mysqlnd_rowp_read(MYSQLND_CONN_DATA * conn, void * _packet)

DBG_ENTER("php_mysqlnd_rowp_read");

ret = php_mysqlnd_read_row_ex(pfc, vio, stats, error_info,
ret = php_mysqlnd_read_row_ex(pfc, vio, stats, error_info, &conn->state,
packet->result_set_memory_pool, &packet->row_buffer, &data_size);
if (FAIL == ret) {
goto end;
Expand Down

0 comments on commit 24537a7

Please sign in to comment.