From: Andrey Hristov Date: Fri, 8 Jan 2010 17:35:20 +0000 (+0000) Subject: improve the stats subsystem. Reduce the number of macro definitions X-Git-Tag: php-5.4.0alpha1~466 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d20fdd603bc01ba3910839a6f3b7d4094eba6a67;p=php improve the stats subsystem. Reduce the number of macro definitions in half by smartly introducing 2 new macros. Make MYSQLND::stats a pointer from being aggregated and add triggers. --- diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index b253b64907..55c147b366 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -228,6 +228,10 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_conn, dtor)(MYSQLND *conn TSRMLS_DC) conn->protocol = NULL; } + if (conn->stats) { + mysqlnd_stats_end(conn->stats); + } + mnd_pefree(conn, conn->persistent); DBG_VOID_RETURN; @@ -371,7 +375,7 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command)(MYSQLND *conn, enum php_mysqlnd_ser cmd_packet->arg_len = arg_len; } - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_COM_QUIT + command - 1 /* because of COM_SLEEP */ ); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_COM_QUIT + command - 1 /* because of COM_SLEEP */ ); if (! PACKET_WRITE(cmd_packet, conn)) { if (!silent) { @@ -431,7 +435,7 @@ static enum_func_status MYSQLND_METHOD(mysqlnd_conn, restart_psession)(MYSQLND * conn TSRMLS_DC) { DBG_ENTER("mysqlnd_conn::restart_psession"); - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_CONNECT_REUSED); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_CONNECT_REUSED); /* Free here what should not be seen by the next script */ if (conn->last_message) { mnd_pefree(conn->last_message, conn->persistent); @@ -486,15 +490,15 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, DBG_INF("Connecting on a connected handle."); if (CONN_GET_STATE(conn) < CONN_QUIT_SENT) { - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_CLOSE_IMPLICIT); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_CLOSE_IMPLICIT); reconnect = TRUE; mysqlnd_send_close(conn TSRMLS_CC); } conn->m->free_contents(conn TSRMLS_CC); - MYSQLND_DEC_CONN_STATISTIC(&conn->stats, STAT_OPENED_CONNECTIONS); + MYSQLND_DEC_CONN_STATISTIC(conn->stats, STAT_OPENED_CONNECTIONS); if (conn->persistent) { - MYSQLND_DEC_CONN_STATISTIC(&conn->stats, STAT_OPENED_PERSISTENT_CONNECTIONS); + MYSQLND_DEC_CONN_STATISTIC(conn->stats, STAT_OPENED_PERSISTENT_CONNECTIONS); } /* Now reconnect using the same handle */ if (conn->net->compressed) { @@ -690,12 +694,12 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, conn->m->set_client_option(conn, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *)&buf_size TSRMLS_CC); } - MYSQLND_INC_CONN_STATISTIC_W_VALUE2(&conn->stats, STAT_CONNECT_SUCCESS, 1, STAT_OPENED_CONNECTIONS, 1); + MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn->stats, STAT_CONNECT_SUCCESS, 1, STAT_OPENED_CONNECTIONS, 1); if (reconnect) { MYSQLND_INC_GLOBAL_STATISTIC(STAT_RECONNECT); } if (conn->persistent) { - MYSQLND_INC_CONN_STATISTIC_W_VALUE2(&conn->stats, STAT_PCONNECT_SUCCESS, 1, STAT_OPENED_PERSISTENT_CONNECTIONS, 1); + MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn->stats, STAT_PCONNECT_SUCCESS, 1, STAT_OPENED_PERSISTENT_CONNECTIONS, 1); } DBG_INF_FMT("connection_id=%llu", conn->thread_id); @@ -712,9 +716,9 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, int current_command = 0; for (; current_command < conn->options.num_commands; ++current_command) { const char * const command = conn->options.init_commands[current_command]; - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_INIT_COMMAND_EXECUTED_COUNT); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_EXECUTED_COUNT); if (PASS != conn->m->query(conn, command, strlen(command) TSRMLS_CC)) { - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_INIT_COMMAND_FAILED_COUNT); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_FAILED_COUNT); goto err; } if (conn->last_query_type == QUERY_SELECT) { @@ -748,7 +752,7 @@ err: conn->scheme = NULL; } - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_CONNECT_FAILURE); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_CONNECT_FAILURE); DBG_RETURN(FAIL); } @@ -820,7 +824,7 @@ MYSQLND_METHOD(mysqlnd_conn, query)(MYSQLND *conn, const char *query, unsigned i */ ret = conn->m->query_read_result_set_header(conn, NULL TSRMLS_CC); if (ret == PASS && conn->last_query_type == QUERY_UPSERT && conn->upsert_status.affected_rows) { - MYSQLND_INC_CONN_STATISTIC_W_VALUE(&conn->stats, STAT_ROWS_AFFECTED_NORMAL, conn->upsert_status.affected_rows); + MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_NORMAL, conn->upsert_status.affected_rows); } DBG_RETURN(ret); @@ -1448,10 +1452,10 @@ MYSQLND_METHOD(mysqlnd_conn, close)(MYSQLND * conn, enum_connection_close_type c DBG_INF_FMT("conn=%llu", conn->thread_id); if (conn->state >= CONN_READY) { - MYSQLND_INC_CONN_STATISTIC(&conn->stats, stat); - MYSQLND_DEC_CONN_STATISTIC(&conn->stats, STAT_OPENED_CONNECTIONS); + MYSQLND_INC_CONN_STATISTIC(conn->stats, stat); + MYSQLND_DEC_CONN_STATISTIC(conn->stats, STAT_OPENED_CONNECTIONS); if (conn->persistent) { - MYSQLND_DEC_CONN_STATISTIC(&conn->stats, STAT_OPENED_PERSISTENT_CONNECTIONS); + MYSQLND_DEC_CONN_STATISTIC(conn->stats, STAT_OPENED_PERSISTENT_CONNECTIONS); } } @@ -1973,7 +1977,7 @@ MYSQLND_METHOD(mysqlnd_conn, use_result)(MYSQLND * const conn TSRMLS_DC) DBG_RETURN(NULL); } - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_UNBUFFERED_SETS); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_UNBUFFERED_SETS); result = conn->current_result; conn->current_result = NULL; @@ -2006,7 +2010,7 @@ MYSQLND_METHOD(mysqlnd_conn, store_result)(MYSQLND * const conn TSRMLS_DC) DBG_RETURN(NULL); } - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_BUFFERED_SETS); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS); result = conn->current_result; conn->current_result = NULL; @@ -2025,7 +2029,7 @@ MYSQLND_METHOD(mysqlnd_conn, get_connection_stats)(const MYSQLND * const conn, { DBG_ENTER("mysqlnd_conn::get_connection_stats"); DBG_INF_FMT("conn=%llu", conn->thread_id); - mysqlnd_fill_stats_hash(&(conn->stats), return_value TSRMLS_CC ZEND_FILE_LINE_CC); + mysqlnd_fill_stats_hash(conn->stats, return_value TSRMLS_CC ZEND_FILE_LINE_CC); DBG_VOID_RETURN; } /* }}} */ @@ -2111,6 +2115,7 @@ MYSQLND_METHOD(mysqlnd_conn, init)(MYSQLND * conn TSRMLS_DC) DBG_ENTER("mysqlnd_conn::init"); conn->net = mysqlnd_net_init(conn->persistent TSRMLS_CC); conn->protocol = mysqlnd_protocol_init(conn->persistent TSRMLS_CC); + mysqlnd_stats_init(&conn->stats); SET_ERROR_AFF_ROWS(conn); diff --git a/ext/mysqlnd/mysqlnd_net.c b/ext/mysqlnd/mysqlnd_net.c index 63bd263fc9..23d75052a0 100644 --- a/ext/mysqlnd/mysqlnd_net.c +++ b/ext/mysqlnd/mysqlnd_net.c @@ -78,7 +78,7 @@ MYSQLND_METHOD(mysqlnd_net, network_read)(MYSQLND * conn, zend_uchar * buffer, s buffer += ret; to_read -= ret; } - MYSQLND_INC_CONN_STATISTIC_W_VALUE(&conn->stats, STAT_BYTES_RECEIVED, count); + MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_BYTES_RECEIVED, count); conn->net->stream->chunk_size = old_chunk_size; DBG_RETURN(PASS); } @@ -307,7 +307,7 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); } - MYSQLND_INC_CONN_STATISTIC_W_VALUE3(&conn->stats, + MYSQLND_INC_CONN_STATISTIC_W_VALUE3(conn->stats, STAT_BYTES_SENT, count + packets_sent * MYSQLND_HEADER_SIZE, STAT_PROTOCOL_OVERHEAD_OUT, packets_sent * MYSQLND_HEADER_SIZE, STAT_PACKETS_SENT, packets_sent); diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index a90c4a6358..627fdd22cb 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -94,7 +94,7 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const stmt TSRMLS_DC) SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(stmt->conn->error_info); - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_PS_BUFFERED_SETS); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_PS_BUFFERED_SETS); result = stmt->result; result->type = MYSQLND_RES_PS_BUF; @@ -152,7 +152,7 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const stmt TSRMLS_DC) SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(stmt->conn->error_info); - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_BUFFERED_SETS); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS); result = mysqlnd_result_init(stmt->result->field_count TSRMLS_CC); @@ -616,7 +616,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const stmt TSRMLS_DC) ret = mysqlnd_stmt_execute_parse_response(stmt TSRMLS_CC); if (ret == PASS && conn->last_query_type == QUERY_UPSERT && stmt->upsert_status.affected_rows) { - MYSQLND_INC_CONN_STATISTIC_W_VALUE(&conn->stats, STAT_ROWS_AFFECTED_PS, stmt->upsert_status.affected_rows); + MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_PS, stmt->upsert_status.affected_rows); } DBG_RETURN(ret); } @@ -655,7 +655,7 @@ mysqlnd_fetch_stmt_row_buffered(MYSQLND_RES *result, void *param, unsigned int f result->stored_data->persistent, result->conn->options.numeric_and_datetime_as_unicode, result->conn->options.int_and_float_native, - &result->conn->stats TSRMLS_CC); + result->conn->stats TSRMLS_CC); if (stmt->update_max_length) { for (i = 0; i < result->field_count; i++) { /* @@ -770,7 +770,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int FALSE, result->conn->options.numeric_and_datetime_as_unicode, result->conn->options.int_and_float_native, - &result->conn->stats TSRMLS_CC); + result->conn->stats TSRMLS_CC); for (i = 0; i < field_count; i++) { if (stmt->result_bind[i].bound == TRUE) { @@ -799,7 +799,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int } } } - MYSQLND_INC_CONN_STATISTIC(&stmt->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_PS_UNBUF); + MYSQLND_INC_CONN_STATISTIC(stmt->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_PS_UNBUF); } else { DBG_INF("skipping extraction"); /* @@ -866,7 +866,7 @@ MYSQLND_METHOD(mysqlnd_stmt, use_result)(MYSQLND_STMT *stmt TSRMLS_DC) SET_EMPTY_ERROR(stmt->error_info); - MYSQLND_INC_CONN_STATISTIC(&stmt->conn->stats, STAT_PS_UNBUFFERED_SETS); + MYSQLND_INC_CONN_STATISTIC(stmt->conn->stats, STAT_PS_UNBUFFERED_SETS); result = stmt->result; DBG_INF_FMT("%scursor exists", stmt->cursor_exists? "":"no "); @@ -947,7 +947,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla FALSE, result->conn->options.numeric_and_datetime_as_unicode, result->conn->options.int_and_float_native, - &result->conn->stats TSRMLS_CC); + result->conn->stats TSRMLS_CC); /* If no result bind, do nothing. We consumed the data */ for (i = 0; i < field_count; i++) { @@ -995,7 +995,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla row_packet->row_buffer->free_chunk(row_packet->row_buffer, TRUE TSRMLS_CC); row_packet->row_buffer = NULL; } - MYSQLND_INC_CONN_STATISTIC(&stmt->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_PS_CURSOR); + MYSQLND_INC_CONN_STATISTIC(stmt->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_PS_CURSOR); } else { *fetched_anything = FALSE; @@ -1987,7 +1987,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const stmt, zend_ break; } if (stat != STAT_LAST) { - MYSQLND_INC_CONN_STATISTIC(&conn->stats, stat); + MYSQLND_INC_CONN_STATISTIC(conn->stats, stat); } if (stmt->execute_cmd_buffer.buffer) { diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index c0fefaa093..5242321f37 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -59,7 +59,7 @@ MYSQLND_METHOD(mysqlnd_res, initialize_result_set_rest)(MYSQLND_RES * const resu result->stored_data->persistent, result->conn->options.numeric_and_datetime_as_unicode, result->conn->options.int_and_float_native, - &result->conn->stats TSRMLS_CC); + result->conn->stats TSRMLS_CC); for (i = 0; i < result->field_count; i++) { /* NULL fields are 0 length, 0 is not more than 0 @@ -144,7 +144,7 @@ MYSQLND_METHOD(mysqlnd_res, unbuffered_free_last_data)(MYSQLND_RES * result TSRM if (unbuf->last_row_data) { unsigned int i, ctor_called_count = 0; zend_bool copy_ctor_called; - MYSQLND_STATS *global_stats = result->conn? &result->conn->stats:NULL; + MYSQLND_STATS *global_stats = result->conn? result->conn->stats:NULL; DBG_INF_FMT("%u columns to free", result->field_count); for (i = 0; i < result->field_count; i++) { @@ -399,7 +399,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC CONN_SET_STATE(conn, CONN_SENDING_LOAD_DATA); ret = mysqlnd_handle_local_infile(conn, rset_header->info_or_local_file, &is_warning TSRMLS_CC); CONN_SET_STATE(conn, (ret == PASS || is_warning == TRUE)? CONN_READY:CONN_QUIT_SENT); - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_NON_RSET_QUERY); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_NON_RSET_QUERY); break; } case 0: /* UPSERT */ @@ -420,7 +420,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC CONN_SET_STATE(conn, CONN_READY); } ret = PASS; - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_NON_RSET_QUERY); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_NON_RSET_QUERY); break; default:{ /* Result set */ php_mysql_packet_eof * fields_eof; @@ -430,7 +430,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC DBG_INF("Result set pending"); SET_EMPTY_MESSAGE(conn->last_message, conn->last_message_len, conn->persistent); - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_RSET_QUERY); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_RSET_QUERY); memset(&conn->upsert_status, 0, sizeof(conn->upsert_status)); /* restore after zeroing */ SET_ERROR_AFF_ROWS(conn); @@ -517,7 +517,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC efree(backtrace); #endif } - MYSQLND_INC_CONN_STATISTIC(&conn->stats, stat); + MYSQLND_INC_CONN_STATISTIC(conn->stats, stat); } PACKET_FREE(fields_eof); @@ -627,7 +627,7 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES *result TSRMLS_DC) row_packet->fields = NULL; row_packet->row_buffer = NULL; - MYSQLND_INC_CONN_STATISTIC(&result->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_UNBUF); + MYSQLND_INC_CONN_STATISTIC(result->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_UNBUF); if (!row_packet->skip_extraction) { MYSQLND_FIELD *field = result->meta->fields; @@ -640,7 +640,7 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES *result TSRMLS_DC) FALSE, result->conn->options.numeric_and_datetime_as_unicode, result->conn->options.int_and_float_native, - &result->conn->stats TSRMLS_CC); + result->conn->stats TSRMLS_CC); retrow = mnd_malloc(result->field_count * sizeof(char *)); @@ -737,7 +737,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag row_packet->row_buffer = NULL; - MYSQLND_INC_CONN_STATISTIC(&result->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_UNBUF); + MYSQLND_INC_CONN_STATISTIC(result->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_UNBUF); if (!row_packet->skip_extraction) { HashTable *row_ht = Z_ARRVAL_P(row); @@ -753,7 +753,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag FALSE, result->conn->options.numeric_and_datetime_as_unicode, result->conn->options.int_and_float_native, - &result->conn->stats TSRMLS_CC); + result->conn->stats TSRMLS_CC); for (i = 0; i < field_count; i++, field++, zend_hash_key++) { zval *data = result->unbuf->last_row_data[i]; @@ -907,7 +907,7 @@ mysqlnd_fetch_row_buffered_c(MYSQLND_RES *result TSRMLS_DC) FALSE, result->conn->options.numeric_and_datetime_as_unicode, result->conn->options.int_and_float_native, - &result->conn->stats TSRMLS_CC); + result->conn->stats TSRMLS_CC); for (i = 0; i < result->field_count; i++) { /* NULL fields are 0 length, 0 is not more than 0 @@ -976,7 +976,7 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags, result->stored_data->persistent, result->conn->options.numeric_and_datetime_as_unicode, result->conn->options.int_and_float_native, - &result->conn->stats TSRMLS_CC); + result->conn->stats TSRMLS_CC); for (i = 0; i < result->field_count; i++) { /* NULL fields are 0 length, 0 is not more than 0 @@ -1113,7 +1113,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL memset(set->data, 0, set->row_count * meta->field_count * sizeof(zval *)); } - MYSQLND_INC_CONN_STATISTIC_W_VALUE(&conn->stats, + MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, binary_protocol? STAT_ROWS_BUFFERED_FROM_CLIENT_PS: STAT_ROWS_BUFFERED_FROM_CLIENT_NORMAL, set->row_count); @@ -1209,7 +1209,7 @@ MYSQLND_METHOD(mysqlnd_res, skip_result)(MYSQLND_RES * const result TSRMLS_DC) { DBG_INF("skipping result"); /* We have to fetch all data to clean the line */ - MYSQLND_INC_CONN_STATISTIC(&result->conn->stats, + MYSQLND_INC_CONN_STATISTIC(result->conn->stats, result->type == MYSQLND_RES_NORMAL? STAT_FLUSHED_NORMAL_SETS: STAT_FLUSHED_PS_SETS); @@ -1232,7 +1232,7 @@ MYSQLND_METHOD(mysqlnd_res, free_result)(MYSQLND_RES *result, zend_bool implicit DBG_INF_FMT("implicit=%d", implicit); result->m.skip_result(result TSRMLS_CC); - MYSQLND_INC_CONN_STATISTIC(result->conn? &result->conn->stats : NULL, + MYSQLND_INC_CONN_STATISTIC(result->conn? result->conn->stats : NULL, implicit == TRUE? STAT_FREE_RESULT_IMPLICIT: STAT_FREE_RESULT_EXPLICIT); diff --git a/ext/mysqlnd/mysqlnd_statistics.c b/ext/mysqlnd/mysqlnd_statistics.c index ca3967e215..0f83e93324 100644 --- a/ext/mysqlnd/mysqlnd_statistics.c +++ b/ext/mysqlnd/mysqlnd_statistics.c @@ -240,6 +240,7 @@ void mysqlnd_stats_init(MYSQLND_STATS ** stats) { *stats = calloc(1, sizeof(MYSQLND_STATS)); + (*stats)->handlers = calloc(STAT_LAST, sizeof(mysqlnd_stat_handler)); #ifdef ZTS (*stats)->LOCK_access = tsrm_mutex_alloc(); #endif @@ -255,6 +256,7 @@ mysqlnd_stats_end(MYSQLND_STATS * stats) #ifdef ZTS tsrm_mutex_free(stats->LOCK_access); #endif + free(stats->handlers); /* mnd_free will reference LOCK_access and crash...*/ free(stats); } diff --git a/ext/mysqlnd/mysqlnd_statistics.h b/ext/mysqlnd/mysqlnd_statistics.h index eb9bdb3190..80aca9d6c1 100644 --- a/ext/mysqlnd/mysqlnd_statistics.h +++ b/ext/mysqlnd/mysqlnd_statistics.h @@ -35,15 +35,31 @@ typedef struct st_mysqlnd_string extern const MYSQLND_STRING mysqlnd_stats_values_names[]; #ifdef ZTS +#define MYSQLND_STATS_LOCK(stats) tsrm_mutex_lock((stats)->LOCK_access) +#define MYSQLND_STATS_UNLOCK(stats) tsrm_mutex_unlock((stats)->LOCK_access) +#else +#define MYSQLND_STATS_LOCK(stats) +#define MYSQLND_STATS_UNLOCK(stats) +#endif + +#define MYSQLND_CHECK_AND_CALL_HANDLER(stats, statistic, value) \ + if ((stats)->handlers[(statistic)] && (stats)->in_handler == FALSE) { \ + (stats)->in_handler = TRUE; \ + (stats)->handlers[(statistic)]((stats), (statistic), (value) TSRMLS_CC); \ + (stats)->in_handler = FALSE; \ + } \ + + #define MYSQLND_INC_GLOBAL_STATISTIC(statistic) \ { \ if (MYSQLND_G(collect_statistics) && (statistic) != STAT_LAST) { \ DBG_INF_FMT("Global stat increase [%s]", mysqlnd_stats_values_names[(statistic)].s); \ \ - tsrm_mutex_lock(mysqlnd_global_stats->LOCK_access); \ + MYSQLND_STATS_LOCK(mysqlnd_global_stats); \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, (statistic), 1); \ mysqlnd_global_stats->values[(statistic)]++; \ - tsrm_mutex_unlock(mysqlnd_global_stats->LOCK_access); \ + MYSQLND_STATS_UNLOCK(mysqlnd_global_stats); \ }\ } @@ -52,11 +68,12 @@ extern const MYSQLND_STRING mysqlnd_stats_values_names[]; if (MYSQLND_G(collect_statistics) && (statistic) != STAT_LAST) { \ DBG_INF_FMT("Global&conn stat decrease [%s]", mysqlnd_stats_values_names[(statistic)].s); \ \ - tsrm_mutex_lock(mysqlnd_global_stats->LOCK_access); \ + MYSQLND_STATS_LOCK(mysqlnd_global_stats); \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, (statistic), -1); \ mysqlnd_global_stats->values[(statistic)]--; \ - tsrm_mutex_unlock(mysqlnd_global_stats->LOCK_access); \ - if ((conn_stats)) { \ - ((MYSQLND_STATS *) conn_stats)->values[(statistic)]--; \ + MYSQLND_STATS_UNLOCK(mysqlnd_global_stats); \ + if ((conn_stats)) { \ + MYSQLND_CHECK_AND_CALL_HANDLER((conn_stats), (statistic), -1); \ } \ }\ } @@ -72,10 +89,16 @@ extern const MYSQLND_STRING mysqlnd_stats_values_names[]; if (_s1 != STAT_LAST) DBG_INF_FMT("Global stat increase1 [%s]", mysqlnd_stats_values_names[_s1].s); \ if (_s2 != STAT_LAST) DBG_INF_FMT("Global stat increase2 [%s]", mysqlnd_stats_values_names[_s2].s); \ \ - tsrm_mutex_lock(mysqlnd_global_stats->LOCK_access); \ - if (_s1 != STAT_LAST) mysqlnd_global_stats->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) mysqlnd_global_stats->values[_s2]+= v2; \ - tsrm_mutex_unlock(mysqlnd_global_stats->LOCK_access); \ + MYSQLND_STATS_LOCK(mysqlnd_global_stats); \ + if (_s1 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, _s1, v1); \ + mysqlnd_global_stats->values[_s1]+= v1; \ + } \ + if (_s2 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, _s2, v2); \ + mysqlnd_global_stats->values[_s2]+= v2; \ + } \ + MYSQLND_STATS_UNLOCK(mysqlnd_global_stats); \ }\ } @@ -84,11 +107,13 @@ extern const MYSQLND_STRING mysqlnd_stats_values_names[]; if (MYSQLND_G(collect_statistics) && (statistic) != STAT_LAST) { \ DBG_INF_FMT("Global&Conn stat increase [%s]", mysqlnd_stats_values_names[(statistic)].s); \ \ - tsrm_mutex_lock(mysqlnd_global_stats->LOCK_access); \ + MYSQLND_STATS_LOCK(mysqlnd_global_stats); \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, (statistic), 1); \ mysqlnd_global_stats->values[(statistic)]++; \ - tsrm_mutex_unlock(mysqlnd_global_stats->LOCK_access); \ - if ((conn_stats)) { \ - ((MYSQLND_STATS *) conn_stats)->values[(statistic)]++; \ + MYSQLND_STATS_UNLOCK(mysqlnd_global_stats); \ + if (conn_stats) { \ + MYSQLND_CHECK_AND_CALL_HANDLER((conn_stats), (statistic), 1); \ + (conn_stats)->values[(statistic)]++; \ } \ }\ } @@ -99,11 +124,13 @@ extern const MYSQLND_STRING mysqlnd_stats_values_names[]; uint64_t v = (uint64_t) (value); \ DBG_INF_FMT("Global&Conn stat increase w value [%s]", mysqlnd_stats_values_names[(statistic)].s); \ \ - tsrm_mutex_lock(mysqlnd_global_stats->LOCK_access); \ + MYSQLND_STATS_LOCK(mysqlnd_global_stats); \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, (statistic), v); \ mysqlnd_global_stats->values[(statistic)] += v; \ - tsrm_mutex_unlock(mysqlnd_global_stats->LOCK_access); \ - if ((conn_stats)) { \ - ((MYSQLND_STATS *) conn_stats)->values[(statistic)]+= v; \ + MYSQLND_STATS_UNLOCK(mysqlnd_global_stats); \ + if (conn_stats) { \ + MYSQLND_CHECK_AND_CALL_HANDLER((conn_stats), (statistic), v); \ + (conn_stats)->values[(statistic)]+= v; \ } \ }\ } @@ -119,13 +146,25 @@ extern const MYSQLND_STRING mysqlnd_stats_values_names[]; if (_s1 != STAT_LAST) DBG_INF_FMT("Global stat increase1 [%s]", mysqlnd_stats_values_names[_s1].s); \ if (_s2 != STAT_LAST) DBG_INF_FMT("Global stat increase2 [%s]", mysqlnd_stats_values_names[_s2].s); \ \ - tsrm_mutex_lock(mysqlnd_global_stats->LOCK_access); \ - if (_s1 != STAT_LAST) mysqlnd_global_stats->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) mysqlnd_global_stats->values[_s2]+= v2; \ - tsrm_mutex_unlock(mysqlnd_global_stats->LOCK_access); \ - if ((conn_stats)) { \ - if (_s1 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s2]+= v2; \ + MYSQLND_STATS_LOCK(mysqlnd_global_stats); \ + if (_s1 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, _s1, v1); \ + mysqlnd_global_stats->values[_s1]+= v1; \ + } \ + if (_s2 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, _s2, v2); \ + mysqlnd_global_stats->values[_s2]+= v2; \ + } \ + MYSQLND_STATS_UNLOCK(mysqlnd_global_stats); \ + if (conn_stats) { \ + if (_s1 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER((conn_stats), _s1, v1); \ + (conn_stats)->values[_s1]+= v1; \ + } \ + if (_s2 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER((conn_stats), _s2, v2); \ + (conn_stats)->values[_s2]+= v2; \ + } \ } \ } \ } @@ -145,126 +184,37 @@ extern const MYSQLND_STRING mysqlnd_stats_values_names[]; if (_s2 != STAT_LAST) DBG_INF_FMT("Global stat increase2 [%s]", mysqlnd_stats_values_names[_s2].s); \ if (_s3 != STAT_LAST) DBG_INF_FMT("Global stat increase3 [%s]", mysqlnd_stats_values_names[_s3].s); \ \ - tsrm_mutex_lock(mysqlnd_global_stats->LOCK_access); \ - if (_s1 != STAT_LAST) mysqlnd_global_stats->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) mysqlnd_global_stats->values[_s2]+= v2; \ - if (_s3 != STAT_LAST) mysqlnd_global_stats->values[_s3]+= v3; \ - tsrm_mutex_unlock(mysqlnd_global_stats->LOCK_access); \ - if ((conn_stats)) { \ - if (_s1 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s2]+= v2; \ - if (_s3 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s3]+= v3; \ + MYSQLND_STATS_LOCK(mysqlnd_global_stats); \ + if (_s1 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, _s1, v1); \ + mysqlnd_global_stats->values[_s1]+= v1; \ } \ - } \ - } - - -#else /* NON-ZTS */ - -#define MYSQLND_INC_GLOBAL_STATISTIC(statistic) \ - { \ - if (MYSQLND_G(collect_statistics) && (statistic) != STAT_LAST) { \ - DBG_INF_FMT("Global stat increase [%s]", mysqlnd_stats_values_names[(statistic)].s); \ - mysqlnd_global_stats->values[(statistic)]++; \ - } \ - } - - -#define MYSQLND_DEC_CONN_STATISTIC(conn_stats, statistic) \ - { \ - if (MYSQLND_G(collect_statistics) && (statistic) != STAT_LAST) { \ - DBG_INF_FMT("Global&Conn stat decrease [%s]", mysqlnd_stats_values_names[(statistic)].s); \ - mysqlnd_global_stats->values[(statistic)]--; \ - if ((conn_stats)) { \ - ((MYSQLND_STATS *) conn_stats)->values[(statistic)]--; \ + if (_s2 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, _s2, v2); \ + mysqlnd_global_stats->values[_s2]+= v2; \ } \ - } \ - } - -#define MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(statistic1, value1, statistic2, value2) \ - { \ - if (MYSQLND_G(collect_statistics)) { \ - uint64_t v1 = (uint64_t) (value1); \ - uint64_t v2 = (uint64_t) (value2); \ - enum_mysqlnd_collected_stats _s1 = (statistic1);\ - enum_mysqlnd_collected_stats _s2 = (statistic2);\ - \ - if (_s1 != STAT_LAST) DBG_INF_FMT("Global stat increase1 [%s]", mysqlnd_stats_values_names[_s1].s); \ - if (_s2 != STAT_LAST) DBG_INF_FMT("Global stat increase2 [%s]", mysqlnd_stats_values_names[_s2].s); \ - \ - if (_s1 != STAT_LAST) mysqlnd_global_stats->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) mysqlnd_global_stats->values[_s2]+= v2; \ - }\ - } - -#define MYSQLND_INC_CONN_STATISTIC(conn_stats, statistic) \ - { \ - if (MYSQLND_G(collect_statistics) && (statistic) != STAT_LAST) { \ - DBG_INF_FMT("Global&Conn stat increase [%s]", mysqlnd_stats_values_names[(statistic)].s); \ - mysqlnd_global_stats->values[(statistic)]++; \ - if ((conn_stats)) { \ - ((MYSQLND_STATS *) conn_stats)->values[(statistic)]++; \ + if (_s3 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER(mysqlnd_global_stats, _s3, v3); \ + mysqlnd_global_stats->values[_s3]+= v3; \ } \ - } \ - } - -#define MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn_stats, statistic, value) \ - { \ - if (MYSQLND_G(collect_statistics) && (statistic) != STAT_LAST) { \ - uint64_t v = (uint64_t) (value); \ - DBG_INF_FMT("Global&Conn stats increase w value [%s]", mysqlnd_stats_values_names[(statistic)].s); \ - mysqlnd_global_stats->values[(statistic)] += v; \ - if ((conn_stats)) { \ - ((MYSQLND_STATS *) conn_stats)->values[(statistic)] += v; \ - } \ - } \ - } - -#define MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn_stats, statistic1, value1, statistic2, value2) \ - { \ - if (MYSQLND_G(collect_statistics)) { \ - uint64_t v1 = (uint64_t) (value1); \ - uint64_t v2 = (uint64_t) (value2); \ - enum_mysqlnd_collected_stats _s1 = (statistic1);\ - enum_mysqlnd_collected_stats _s2 = (statistic2);\ - if (_s1 != STAT_LAST) DBG_INF_FMT("Global stat increase1 [%s]", mysqlnd_stats_values_names[_s1].s); \ - if (_s2 != STAT_LAST) DBG_INF_FMT("Global stat increase2 [%s]", mysqlnd_stats_values_names[_s2].s); \ - \ - if (_s1 != STAT_LAST) mysqlnd_global_stats->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) mysqlnd_global_stats->values[_s2]+= v2; \ - if ((conn_stats)) { \ - if (_s1 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s2]+= v2; \ + MYSQLND_STATS_UNLOCK(mysqlnd_global_stats); \ + if (conn_stats) { \ + if (_s1 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER((conn_stats), _s1, v1); \ + (conn_stats)->values[_s1]+= v1; \ + } \ + if (_s2 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER((conn_stats), _s2, v2); \ + (conn_stats)->values[_s2]+= v2; \ + } \ + if (_s3 != STAT_LAST) { \ + MYSQLND_CHECK_AND_CALL_HANDLER((conn_stats), _s3, v3); \ + (conn_stats)->values[_s3]+= v3; \ + } \ } \ } \ } -#define MYSQLND_INC_CONN_STATISTIC_W_VALUE3(conn_stats, statistic1, value1, statistic2, value2, statistic3, value3) \ - { \ - if (MYSQLND_G(collect_statistics)) { \ - uint64_t v1 = (uint64_t) (value1); \ - uint64_t v2 = (uint64_t) (value2); \ - uint64_t v3 = (uint64_t) (value3); \ - enum_mysqlnd_collected_stats _s1 = (statistic1); \ - enum_mysqlnd_collected_stats _s2 = (statistic2); \ - enum_mysqlnd_collected_stats _s3 = (statistic3); \ - \ - if (_s1 != STAT_LAST) DBG_INF_FMT("Global stat increase1 [%s]", mysqlnd_stats_values_names[_s1].s); \ - if (_s2 != STAT_LAST) DBG_INF_FMT("Global stat increase2 [%s]", mysqlnd_stats_values_names[_s2].s); \ - if (_s3 != STAT_LAST) DBG_INF_FMT("Global stat increase3 [%s]", mysqlnd_stats_values_names[_s3].s); \ - \ - if (_s1 != STAT_LAST) mysqlnd_global_stats->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) mysqlnd_global_stats->values[_s2]+= v2; \ - if (_s3 != STAT_LAST) mysqlnd_global_stats->values[_s3]+= v3; \ - if ((conn_stats)) { \ - if (_s1 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s1]+= v1; \ - if (_s2 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s2]+= v2; \ - if (_s3 != STAT_LAST) ((MYSQLND_STATS *) conn_stats)->values[_s3]+= v3; \ - } \ - } \ - } - -#endif void mysqlnd_fill_stats_hash(const MYSQLND_STATS * const stats, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC); diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index a186861b61..c7bd51297e 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -208,13 +208,19 @@ typedef enum_func_status (*mysqlnd_fetch_row_func)(MYSQLND_RES *result, zend_bool *fetched_anything TSRMLS_DC); -typedef struct st_mysqlnd_stats +typedef struct st_mysqlnd_stats MYSQLND_STATS; + +typedef void (*mysqlnd_stat_handler)(MYSQLND_STATS * stats, enum_mysqlnd_collected_stats stat, int64_t change TSRMLS_DC); + +struct st_mysqlnd_stats { - uint64_t values[STAT_LAST]; + uint64_t values[STAT_LAST]; + mysqlnd_stat_handler *handlers; + zend_bool in_handler; #ifdef ZTS MUTEX_T LOCK_access; #endif -} MYSQLND_STATS; +}; typedef struct st_mysqlnd_read_buffer { @@ -542,7 +548,7 @@ struct st_mysqlnd_connection MYSQLND_OPTIONS options; /* stats */ - MYSQLND_STATS stats; + MYSQLND_STATS * stats; struct st_mysqlnd_conn_methods *m; }; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 7ec96dc866..849518ac97 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -54,7 +54,7 @@ DBG_ERR_FMT("Empty '%s' packet body", (packet_type_as_text)); \ DBG_RETURN(FAIL);\ } \ - MYSQLND_INC_CONN_STATISTIC_W_VALUE2(&conn->stats, packet_type_to_statistic_byte_count[packet_type], \ + MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn->stats, packet_type_to_statistic_byte_count[packet_type], \ MYSQLND_HEADER_SIZE + (packet)->header.size, \ packet_type_to_statistic_packet_count[packet_type], \ 1); \ @@ -257,7 +257,7 @@ mysqlnd_read_header(MYSQLND * conn, mysqlnd_packet_header * header TSRMLS_DC) #ifdef MYSQLND_DUMP_HEADER_N_BODY DBG_INF_FMT("HEADER: prot_packet_no=%d size=%3d", header->packet_no, header->size); #endif - MYSQLND_INC_CONN_STATISTIC_W_VALUE2(&conn->stats, + MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn->stats, STAT_PROTOCOL_OVERHEAD_IN, MYSQLND_HEADER_SIZE, STAT_PACKETS_RECEIVED, 1); @@ -672,7 +672,7 @@ size_t php_mysqlnd_cmd_write(void *_packet, MYSQLND *conn TSRMLS_DC) EG(error_reporting) = 0; } - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_PACKETS_SENT_CMD); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_PACKETS_SENT_CMD); #ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND net->m.consume_uneaten_data(net, packet->command TSRMLS_CC); @@ -696,7 +696,7 @@ size_t php_mysqlnd_cmd_write(void *_packet, MYSQLND *conn TSRMLS_DC) ret = conn->net->m.send(conn, (char *)tmp, tmp_len - MYSQLND_HEADER_SIZE TSRMLS_CC); if (tmp != net->cmd_buffer.buffer) { - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_CMD_BUFFER_TOO_SMALL); + MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_CMD_BUFFER_TOO_SMALL); mnd_efree(tmp); } written = ret; @@ -1431,7 +1431,7 @@ php_mysqlnd_rowp_read(void *_packet, MYSQLND *conn TSRMLS_DC) if (FAIL == ret) { goto end; } - MYSQLND_INC_CONN_STATISTIC_W_VALUE2(&conn->stats, packet_type_to_statistic_byte_count[PROT_ROW_PACKET], + MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn->stats, packet_type_to_statistic_byte_count[PROT_ROW_PACKET], MYSQLND_HEADER_SIZE + packet->header.size, packet_type_to_statistic_packet_count[PROT_ROW_PACKET], 1); @@ -1465,7 +1465,7 @@ php_mysqlnd_rowp_read(void *_packet, MYSQLND *conn TSRMLS_DC) packet->server_status, packet->warning_count); } } else { - MYSQLND_INC_CONN_STATISTIC(&conn->stats, + MYSQLND_INC_CONN_STATISTIC(conn->stats, packet->binary_protocol? STAT_ROWS_FETCHED_FROM_SERVER_PS: STAT_ROWS_FETCHED_FROM_SERVER_NORMAL); @@ -1489,7 +1489,7 @@ php_mysqlnd_rowp_read(void *_packet, MYSQLND *conn TSRMLS_DC) packet->persistent_alloc); } } else { - MYSQLND_INC_CONN_STATISTIC(&conn->stats, + MYSQLND_INC_CONN_STATISTIC(conn->stats, packet->binary_protocol? STAT_ROWS_SKIPPED_PS: STAT_ROWS_SKIPPED_NORMAL); }