@@ -91,7 +91,11 @@ static
91
91
void mysqlnd_palloc_zval_ptr_dtor (zval * * zv , enum_mysqlnd_res_type type , zend_bool * copy_ctor_called TSRMLS_DC )
92
92
{
93
93
DBG_ENTER ("mysqlnd_palloc_zval_ptr_dtor" );
94
-
94
+ if (!zv || !* zv ) {
95
+ * copy_ctor_called = FALSE;
96
+ DBG_ERR_FMT ("zv was NULL" );
97
+ DBG_VOID_RETURN ;
98
+ }
95
99
/*
96
100
This zval is not from the cache block.
97
101
Thus the refcount is -1 than of a zval from the cache,
@@ -158,17 +162,16 @@ MYSQLND_METHOD(mysqlnd_res, unbuffered_free_last_data)(MYSQLND_RES * result TSRM
158
162
for (i = 0 ; i < result -> field_count ; i ++ ) {
159
163
mysqlnd_palloc_zval_ptr_dtor (& (unbuf -> last_row_data [i ]), result -> type , & copy_ctor_called TSRMLS_CC );
160
164
if (copy_ctor_called ) {
161
- ctor_called_count ++ ;
165
+ ++ ctor_called_count ;
162
166
}
163
167
}
164
168
DBG_INF_FMT ("copy_ctor_called_count=%u" , ctor_called_count );
165
169
/* By using value3 macros we hold a mutex only once, there is no value2 */
166
- MYSQLND_INC_CONN_STATISTIC_W_VALUE3 (global_stats ,
170
+ MYSQLND_INC_CONN_STATISTIC_W_VALUE2 (global_stats ,
167
171
STAT_COPY_ON_WRITE_PERFORMED ,
168
172
ctor_called_count ,
169
173
STAT_COPY_ON_WRITE_SAVED ,
170
- result -> field_count - ctor_called_count ,
171
- STAT_COPY_ON_WRITE_PERFORMED , 0 );
174
+ result -> field_count - ctor_called_count );
172
175
173
176
/* Free last row's zvals */
174
177
mnd_efree (unbuf -> last_row_data );
@@ -199,30 +202,39 @@ MYSQLND_METHOD(mysqlnd_res, free_buffered_data)(MYSQLND_RES * result TSRMLS_DC)
199
202
200
203
DBG_INF ("Freeing data & row_buffer" );
201
204
if (set -> data ) {
205
+ unsigned int copy_on_write_performed = 0 ;
206
+ unsigned int copy_on_write_saved = 0 ;
202
207
203
208
DBG_INF_FMT ("before: real_usage=%lu usage=%lu" , zend_memory_usage (TRUE TSRMLS_CC ), zend_memory_usage (FALSE TSRMLS_CC ));
204
209
for (row = set -> row_count - 1 ; row >= 0 ; row -- ) {
205
210
zval * * current_row = set -> data + row * field_count ;
206
211
MYSQLND_MEMORY_POOL_CHUNK * current_buffer = set -> row_buffers [row ];
207
212
int col ;
208
213
209
- for (col = field_count - 1 ; col >= 0 ; -- col ) {
210
- zend_bool copy_ctor_called ;
211
- if (current_row == NULL || current_row [0 ] == NULL ) {
212
- break ;/* row that was never initialized */
213
- }
214
- mysqlnd_palloc_zval_ptr_dtor (& (current_row [col ]), result -> type , & copy_ctor_called TSRMLS_CC );
214
+ if (current_row != NULL ) {
215
+ for (col = field_count - 1 ; col >= 0 ; -- col ) {
216
+ if (current_row [col ]) {
217
+ zend_bool copy_ctor_called ;
218
+ mysqlnd_palloc_zval_ptr_dtor (& (current_row [col ]), result -> type , & copy_ctor_called TSRMLS_CC );
215
219
#if MYSQLND_DEBUG_MEMORY
216
- DBG_INF_FMT ("Copy_ctor_called=%u" , copy_ctor_called );
220
+ DBG_INF_FMT ("Copy_ctor_called=%u" , copy_ctor_called );
217
221
#endif
218
- MYSQLND_INC_GLOBAL_STATISTIC (copy_ctor_called ? STAT_COPY_ON_WRITE_PERFORMED : STAT_COPY_ON_WRITE_SAVED );
222
+ if (copy_ctor_called ) {
223
+ ++ copy_on_write_performed ;
224
+ } else {
225
+ ++ copy_on_write_saved ;
226
+ }
227
+ }
228
+ }
219
229
}
220
230
#if MYSQLND_DEBUG_MEMORY
221
231
DBG_INF ("Freeing current_row & current_buffer" );
222
232
#endif
223
233
current_buffer -> free_chunk (current_buffer TSRMLS_CC );
224
234
}
225
235
236
+ MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2 (STAT_COPY_ON_WRITE_PERFORMED , copy_on_write_performed ,
237
+ STAT_COPY_ON_WRITE_SAVED , copy_on_write_saved );
226
238
mnd_pefree (set -> data , set -> persistent );
227
239
set -> data = NULL ;
228
240
}
0 commit comments