]> granicus.if.org Git - php/commitdiff
Retain QUIT_SEND connection state
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 29 Oct 2020 09:17:35 +0000 (10:17 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 29 Oct 2020 09:36:03 +0000 (10:36 +0100)
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.

ext/mysqlnd/mysqlnd_ps.c
ext/mysqlnd/mysqlnd_result.c
ext/mysqlnd/mysqlnd_wireprotocol.c

index 010a7bbb4139fb5276c1f1215d04321b94c1a0af..27028ee6f593a994c5c74c126a2ce2a82171d40b 100644 (file)
@@ -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");
index f25330632779d912490445a6dc01f5020a9cc9f6..46d308d1f9bfd5d69af9995605a3b694676f950f 100644 (file)
@@ -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 */
@@ -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 */
index 786ba2a2e9c3937c920cb58f6eaea44718b9da43..b9c8079421a07967be5f62669a4824447f6fea31 100644 (file)
@@ -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)
@@ -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) {
@@ -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;
                                }
@@ -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;