diff options
author | Andrey Hristov <andrey@php.net> | 2009-12-09 16:57:03 +0000 |
---|---|---|
committer | Andrey Hristov <andrey@php.net> | 2009-12-09 16:57:03 +0000 |
commit | 157f1bddf1ff32af77bb47188e7fcc7f9425fbf8 (patch) | |
tree | b58ae49d0da20d89a881492446b5c41be335dac5 /ext/mysqlnd/mysqlnd_result.c | |
parent | 617398b51dfa02e9749c0158db150db2036cd817 (diff) | |
download | php-git-157f1bddf1ff32af77bb47188e7fcc7f9425fbf8.tar.gz |
Remove disabled code - threaded fetching. This can be implemented
on a upper level and by offloading it we reduce the complexity of
the core.
Diffstat (limited to 'ext/mysqlnd/mysqlnd_result.c')
-rw-r--r-- | ext/mysqlnd/mysqlnd_result.c | 507 |
1 files changed, 0 insertions, 507 deletions
diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index a1877e38cb..b997148f84 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -33,65 +33,6 @@ #define MYSQLND_SILENT -#ifdef MYSQLND_THREADED -/* {{{ mysqlnd_fetch_thread */ -void * mysqlnd_fetch_thread(void *arg) -{ - MYSQLND *conn = (MYSQLND *) arg; - MYSQLND_RES * result = NULL; - void ***tsrm_ls = conn->tsrm_ls; -#ifndef MYSQLND_SILENT - printf("THREAD] conn=%p tsrm_ls=%p\n", conn, conn->tsrm_ls); -#endif - do { - pthread_mutex_lock(&conn->LOCK_work); - while (conn->thread_killed == FALSE && !conn->current_result) { -#ifndef MYSQLND_SILENT - printf("THREAD] Waiting for work in %s\n", __FUNCTION__); -#endif - pthread_cond_wait(&conn->COND_work, &conn->LOCK_work); - } - if (conn->thread_killed == TRUE) { -#ifndef MYSQLND_SILENT - printf("THREAD] Thread killed in %s\n", __FUNCTION__); -#endif - pthread_cond_signal(&conn->COND_thread_ended); - pthread_mutex_unlock(&conn->LOCK_work); - break; - } -#ifndef MYSQLND_SILENT - printf("THREAD] Got work in %s\n", __FUNCTION__); -#endif - CONN_SET_STATE(conn, CONN_FETCHING_DATA); - result = conn->current_result; - conn->current_result = NULL; - pthread_cond_signal(&conn->COND_work); /* sent notification back */ - pthread_mutex_unlock(&conn->LOCK_work); - -#ifndef MYSQLND_SILENT - printf("THREAD] Starting fetch %s\n", __FUNCTION__); -#endif - mysqlnd_background_store_result_fetch_data(result TSRMLS_CC); - - /* do fetch the data from the wire */ - - pthread_mutex_lock(&conn->LOCK_work); - CONN_SET_STATE(conn, CONN_READY); - pthread_cond_signal(&conn->COND_work_done); -#ifndef MYSQLND_SILENT - printf("THREAD] Signaling work done in %s\n", __FUNCTION__); -#endif - pthread_mutex_unlock(&conn->LOCK_work); - } while (1); - -#ifndef MYSQLND_SILENT - printf("THREAD] Exiting worker thread in %s\n", __FUNCTION__); -#endif - return NULL; -} -/* }}} */ -#endif /* MYSQLND_THREADED */ - /* {{{ mysqlnd_res::initialize_result_set_rest */ static void @@ -253,85 +194,6 @@ MYSQLND_METHOD(mysqlnd_res, free_buffered_data)(MYSQLND_RES *result TSRMLS_DC) /* }}} */ -#ifdef MYSQLND_THREADED -/* {{{ mysqlnd_free_background_buffered_data */ -void mysqlnd_free_background_buffered_data(MYSQLND_RES *result TSRMLS_DC) -{ - MYSQLND_THD_ZVAL_PCACHE *zval_cache = result->zval_cache; - MYSQLND_RES_BG_BUFFERED *set = result->bg_stored_data; - unsigned int field_count = result->field_count; - int row; - - DBG_ENTER("mysqlnd_free_buffered_data"); - DBG_INF_FMT("Freeing "MYSQLND_LLU_SPEC" row(s)", set->row_count); - - do { - tsrm_mutex_lock(set->LOCK); - if (set->bg_fetch_finished) { - tsrm_mutex_unlock(set->LOCK); - break; - } - tsrm_mutex_unlock(set->LOCK); -#if HAVE_USLEEP - usleep(2000); -#else - { - volatile int i; - for (i = 0; i < 1000; i++); - } -#endif - } while (1); - - DBG_INF_FMT("before: real_usage=%lu usage=%lu", zend_memory_usage(TRUE TSRMLS_CC), zend_memory_usage(FALSE TSRMLS_CC)); - for (row = set->row_count - 1; row >= 0; row--) { - MYSQLND_MEMORY_POOL_CHUNK *current_buffer = set->row_buffers[row]; - /* It could be the case that the user fetched no rows - then no set->data */ - if (row < set->data_size && set->data[row]) { - zval **current_row = set->data[row]; - unsigned int col; - - for (col = 0; col < field_count; col++) { - zend_bool copy_ctor_called; - mysqlnd_palloc_zval_ptr_dtor(&(current_row[col]), zval_cache, - result->type, ©_ctor_called TSRMLS_CC); -#if MYSQLND_DEBUG_MEMORY - DBG_INF_FMT("Copy_ctor_called=%d", copy_ctor_called); -#endif - MYSQLND_INC_GLOBAL_STATISTIC(copy_ctor_called? STAT_COPY_ON_WRITE_PERFORMED: - STAT_COPY_ON_WRITE_SAVED); - } -#if MYSQLND_DEBUG_MEMORY - DBG_INF("Freeing current_row & current_buffer"); -#endif - mnd_pefree(current_row, set->persistent); - } - current_buffer->free_chunk(current_buffer, TRUE TSRMLS_CC); - } - DBG_INF("Freeing data & row_buffer"); - mnd_pefree(set->data, set->persistent); - mnd_pefree(set->row_buffers, set->persistent); - set->data = NULL; - set->row_buffers = NULL; - set->data_cursor = NULL; - set->row_count = 0; - if (set->qcache) { - mysqlnd_qcache_free_cache_reference(&set->qcache); - } - - if (set->LOCK) { - tsrm_mutex_free(set->LOCK); - } - - DBG_INF("Freeing set"); - mnd_pefree(set, set->persistent); - - DBG_INF_FMT("after: real_usage=%lu usage=%lu", zend_memory_usage(TRUE TSRMLS_CC), zend_memory_usage(FALSE TSRMLS_CC)); - DBG_VOID_RETURN; -} -/* }}} */ -#endif /* MYSQL_THREADING */ - - /* {{{ mysqlnd_res::free_result_buffers */ static void MYSQLND_METHOD(mysqlnd_res, free_result_buffers)(MYSQLND_RES *result TSRMLS_DC) @@ -347,12 +209,6 @@ MYSQLND_METHOD(mysqlnd_res, free_result_buffers)(MYSQLND_RES *result TSRMLS_DC) result->m.free_buffered_data(result TSRMLS_CC); result->stored_data = NULL; } -#ifdef MYSQLND_THREADED - else if (result->bg_stored_data) { - mysqlnd_free_background_buffered_data(result TSRMLS_CC); - result->bg_stored_data = NULL; - } -#endif if (result->lengths) { mnd_efree(result->lengths); @@ -690,45 +546,6 @@ unsigned long * mysqlnd_fetch_lengths_buffered(MYSQLND_RES * const result) /* }}} */ -#ifdef MYSQLND_THREADED -/* {{{ mysqlnd_fetch_lengths_async_buffered */ -/* - Do lazy initialization for buffered results. As PHP strings have - length inside, this function makes not much sense in the context - of PHP, to be called as separate function. But let's have it for - completeness. -*/ -static -unsigned long * mysqlnd_fetch_lengths_async_buffered(MYSQLND_RES * const result) -{ - int i; - zval **previous_row; - MYSQLND_RES_BG_BUFFERED *set = result->bg_stored_data; - - /* - If: - - unbuffered result - - first row has not been read - - last_row has been read - */ - if (set->data_cursor == NULL || - set->data_cursor == set->data || - ((set->data_cursor - set->data) > set->row_count)) - { - return NULL;/* No rows or no more rows */ - } - - previous_row = *(set->data_cursor - 1); - for (i = 0; i < result->meta->field_count; i++) { - result->lengths[i] = (Z_TYPE_P(previous_row[i]) == IS_NULL)? 0:Z_STRLEN_P(previous_row[i]); - } - - return result->lengths; -} -/* }}} */ -#endif - - /* {{{ mysqlnd_fetch_lengths_unbuffered */ static unsigned long * mysqlnd_fetch_lengths_unbuffered(MYSQLND_RES * const result) @@ -1355,329 +1172,6 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result, /* }}} */ -#ifdef MYSQLND_THREADED -/* {{{ mysqlnd_fetch_row_async_buffered */ -static enum_func_status -mysqlnd_fetch_row_async_buffered(MYSQLND_RES *result, void *param, unsigned int flags, - zend_bool *fetched_anything TSRMLS_DC) -{ - zval *row = (zval *) param; - MYSQLND_RES_BG_BUFFERED *set = result->bg_stored_data; - - DBG_ENTER("mysqlnd_fetch_row_async_buffered"); - DBG_INF_FMT("flags=%u row=%p", flags, row); - - do { - tsrm_mutex_lock(set->LOCK); - if (set->bg_fetch_finished == TRUE) { - /* Don't unlock here, will be done later */ - break; - } - if (!set->data_cursor || (set->data_cursor - set->data) < (set->row_count)) { - tsrm_mutex_unlock(set->LOCK); -#if HAVE_USLEEP - usleep(2000); -#else - volatile int i = 0; - for (int i = 0; i < 100; i++); -#endif - } else { - break; - } - } while (1); - - /* At the point we are still under LOCK */ - if (set->data_cursor && (set->data_cursor - set->data) < (set->row_count)) { - uint64_t row_num = set->data_cursor - set->data; - zval **current_row = *set->data_cursor++; - unsigned int i; - - set->initialized_rows++; - /* We don't forget to release the lock */ - tsrm_mutex_unlock(set->LOCK); - - /* If there was no decoding in background, we have to decode here */ - if (set->decode_in_foreground == TRUE) { - MYSQLND_MEMORY_POOL_CHUNK *current_buffer = set->row_buffers[row_num]; - result->m.row_decoder(current_buffer, - current_row, - result->meta->field_count, - result->meta->fields, - result->conn->options.numeric_and_datetime_as_unicode, - result->conn->options.int_and_float_native, - result->conn->zval_cache, - &result->conn->stats TSRMLS_CC); - - for (i = 0; i < result->field_count; i++) { - /* - NULL fields are 0 length, 0 is not more than 0 - String of zero size, definitely can't be the next max_length. - Thus for NULL and zero-length we are quite efficient. - */ - if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - unsigned long len = Z_STRLEN_P(current_row[i]); - if (result->meta->fields[i].max_length < len) { - result->meta->fields[i].max_length = len; - } - } - } - } - - - for (i = 0; i < result->field_count; i++) { - zval *data = current_row[i]; - - /* - Let us later know what to do with this zval. If ref_count > 1, we will just - decrease it, otherwise free it. zval_ptr_dtor() make this very easy job. - */ - Z_ADDREF_P(data); - - if ((flags & MYSQLND_FETCH_BOTH) == MYSQLND_FETCH_BOTH) { - Z_ADDREF_P(data); - } - if (flags & MYSQLND_FETCH_NUM) { - zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL); - } - if (flags & MYSQLND_FETCH_ASSOC) { - /* zend_hash_quick_update needs length + trailing zero */ - /* QQ: Error handling ? */ - /* - zend_hash_quick_update does not check, as add_assoc_zval_ex do, whether - the index is a numeric and convert it to it. This however means constant - hashing of the column name, which is not needed as it can be precomputed. - */ - if (result->meta->zend_hash_keys[i].is_numeric == FALSE) { -#if PHP_MAJOR_VERSION >= 6 - zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE, - result->meta->zend_hash_keys[i].ustr, - result->meta->zend_hash_keys[i].ulen + 1, - result->meta->zend_hash_keys[i].key, - (void *) &data, sizeof(zval *), NULL); -#else - zend_hash_quick_update(Z_ARRVAL_P(row), - result->meta->fields[i].name, - result->meta->fields[i].name_length + 1, - result->meta->zend_hash_keys[i].key, - (void *) &data, sizeof(zval *), NULL); -#endif - } else { - zend_hash_index_update(Z_ARRVAL_P(row), - result->meta->zend_hash_keys[i].key, - (void *) &data, sizeof(zval *), NULL); - } - } - } - *fetched_anything = TRUE; - MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF); - } else { - set->data_cursor = NULL; - /* We don't forget to release the lock */ - tsrm_mutex_unlock(set->LOCK); - *fetched_anything = FALSE; - DBG_INF("EOF reached"); - } - - DBG_INF_FMT("ret=PASS fetched=%d", *fetched_anything); - DBG_RETURN(PASS); -} -/* }}} */ - - -/* {{{ mysqlnd_background_store_result_fetch_data */ -enum_func_status -mysqlnd_background_store_result_fetch_data(MYSQLND_RES *result TSRMLS_DC) -{ - enum_func_status ret; - php_mysql_packet_row *row_packet; - unsigned int next_extend = STORE_RESULT_PREALLOCATED_SET_IF_NOT_EMPTY, free_rows; - MYSQLND_RES_BG_BUFFERED *set = result->bg_stored_data; - MYSQLND *conn = result->conn; - - DBG_ENTER("mysqlnd_background_store_result_fetch_data"); - - free_rows = next_extend; - - /* persistent */ - PACKET_INIT(row_packet, PROT_ROW_PACKET, php_mysql_packet_row *, TRUE); - row_packet->result_set_memory_pool = result->result_set_memory_pool; - row_packet->field_count = result->meta->field_count; - row_packet->binary_protocol = result->m.row_decoder == php_mysqlnd_rowp_read_binary_protocol; - row_packet->fields_metadata = result->meta->fields; - row_packet->bit_fields_count = result->meta->bit_fields_count; - row_packet->bit_fields_total_len= result->meta->bit_fields_total_len; - row_packet->persistent_alloc = TRUE; - - while (FAIL != (ret = PACKET_READ(row_packet, conn)) && !row_packet->eof) { - tsrm_mutex_lock(set->LOCK); - if (!free_rows) { - uint64_t total_rows = free_rows = next_extend = next_extend * 5 / 3; /* extend with 33% */ - uint64_t old_size; - total_rows += set->row_count; - - old_size = set->data_size; - set->data_size = total_rows; - set->data = mnd_perealloc(set->data, set->data_size * sizeof(zval **), set->persistent); -#if 0 - memset(set->data + old_size, 0, (set->data_size - old_size) * sizeof(zval **)); -#endif - set->row_buffers = mnd_perealloc(set->row_buffers, - total_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *), - set->persistent); - } - set->row_buffers[set->row_count] = row_packet->row_buffer; - set->data[set->row_count] = row_packet->fields; - - if (set->decode_in_foreground == FALSE) { - unsigned int i; - result->m.row_decoder(set->row_buffers[set->row_count], - set->data[set->row_count], - result->meta->field_count, - result->meta->fields, - result->conn->options.numeric_and_datetime_as_unicode, - result->conn->options.int_and_float_native, - result->conn->zval_cache, - &result->conn->stats TSRMLS_CC); - - for (i = 0; i < result->field_count; i++) { - /* - NULL fields are 0 length, 0 is not more than 0 - String of zero size, definitely can't be the next max_length. - Thus for NULL and zero-length we are quite efficient. - */ - if (Z_TYPE_P(set->data[set->row_count][i]) >= IS_STRING) { - unsigned long len = Z_STRLEN_P(set->data[set->row_count][i]); - if (result->meta->fields[i].max_length < len) { - result->meta->fields[i].max_length = len; - } - } - } - } - set->row_count++; - - tsrm_mutex_unlock(set->LOCK); - free_rows--; - - /* So row_packet's destructor function won't efree() it */ - row_packet->row_buffer = NULL; - row_packet->fields = NULL; - - /* - No need to FREE_ALLOCA as we can reuse the - 'lengths' and 'fields' arrays. For lengths its absolutely safe. - 'fields' is reused because the ownership of the strings has been - transfered above. - */ - } -#if 0 - 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); -#endif - tsrm_mutex_lock(set->LOCK); - /* Finally clean */ - if (row_packet->eof) { - set->upsert_status.warning_count = row_packet->warning_count; - set->upsert_status.server_status = row_packet->server_status; - } - /* save some memory */ - if (free_rows) { - set->data_size = set->row_count; - set->data = mnd_perealloc(set->data, - (size_t) set->data_size * sizeof(zval **), set->persistent); - set->row_buffers = mnd_perealloc(set->row_buffers, - set->row_count * sizeof(MYSQLND_MEMORY_POOL_CHUNK *), - set->persistent); - } - if (ret == FAIL) { - set->error_info = row_packet->error_info; - } else { - /* Position at the first row */ - set->data_cursor = set->data; - - /* libmysql's documentation says it should be so for SELECT statements */ - conn->upsert_status.affected_rows = set->row_count; - set->upsert_status.affected_rows = set->row_count; - } - set->bg_fetch_finished = TRUE; - tsrm_mutex_unlock(set->LOCK); - - PACKET_FREE(row_packet); - - if (conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) { - CONN_SET_STATE(conn, CONN_NEXT_RESULT_PENDING); - } else { - CONN_SET_STATE(conn, CONN_READY); - } - DBG_INF_FMT("ret=%s row_count=%u warnings=%u server_status=%u", ret == PASS? "PASS":"FAIL", - set->row_count, conn->upsert_status.warning_count, conn->upsert_status.server_status); - DBG_RETURN(ret); -} -/* }}} */ -#endif - - -/* {{{ mysqlnd_res::background_store_result */ -static MYSQLND_RES * -MYSQLND_METHOD(mysqlnd_res, background_store_result)(MYSQLND_RES * result, MYSQLND * const conn, zend_bool ps TSRMLS_DC) -{ -#ifndef MYSQLND_THREADED - return (result->m.store_result(result, conn, ps TSRMLS_CC)); -#else - enum_func_status ret; - zend_bool to_cache = TRUE; - - DBG_ENTER("mysqlnd_res::background_store_result"); - DBG_INF_FMT("conn=%d ps_protocol=%d", conn->thread_id, ps); - - /* We need the conn because we are doing lazy zval initialization in buffered_fetch_row */ - result->conn = conn->m->get_reference(conn TSRMLS_CC); - result->type = MYSQLND_RES_NORMAL; - result->m.fetch_row = mysqlnd_fetch_row_async_buffered; - result->m.fetch_lengths = mysqlnd_fetch_lengths_async_buffered; - - result->bg_stored_data = mnd_pecalloc(1, sizeof(MYSQLND_RES_BG_BUFFERED), to_cache); - result->bg_stored_data->data_size = STORE_RESULT_PREALLOCATED_SET_IF_NOT_EMPTY; - result->bg_stored_data->data = mnd_pecalloc(result->bg_stored_data->data_size, sizeof(zval **), to_cache); - result->bg_stored_data->row_buffers = mnd_pemalloc(STORE_RESULT_PREALLOCATED_SET_IF_NOT_EMPTY * sizeof(MYSQLND_MEMORY_POOL_CHUNK *), to_cache); - result->bg_stored_data->persistent = to_cache; - result->bg_stored_data->qcache = to_cache? mysqlnd_qcache_get_cache_reference(conn->qcache):NULL; - result->bg_stored_data->references = 1; - - result->bg_stored_data->LOCK = tsrm_mutex_alloc(); - - result->m.row_decoder = ps? php_mysqlnd_rowp_read_binary_protocol: - php_mysqlnd_rowp_read_text_protocol; - - CONN_SET_STATE(conn, CONN_FETCHING_DATA); - /* - This should be definitely TRUE. Decoding in background means creating zvals - which is not very safe for Zend MM, will complain in debug mode and more problems - also manifest themselves - unstable. - */ - result->bg_stored_data->decode_in_foreground = TRUE; - - result->lengths = mnd_ecalloc(result->field_count, sizeof(unsigned long)); - - pthread_mutex_lock(&conn->LOCK_work); - - pthread_cond_signal(&conn->COND_work); - do { - pthread_cond_wait(&conn->COND_work, &conn->LOCK_work); - } while (conn->current_result); /* this is our invariant */ - pthread_mutex_unlock(&conn->LOCK_work); - -#if 0 - ret = mysqlnd_background_store_result_fetch_data(result TSRMLS_CC); -#endif - - DBG_RETURN(result); -#endif -} -/* }}} */ - - /* {{{ mysqlnd_res::skip_result */ static enum_func_status MYSQLND_METHOD(mysqlnd_res, skip_result)(MYSQLND_RES * const result TSRMLS_DC) @@ -2030,7 +1524,6 @@ MYSQLND_RES *mysqlnd_result_init(unsigned int field_count, MYSQLND_THD_ZVAL_PCAC ret->m.use_result = MYSQLND_METHOD(mysqlnd_res, use_result); ret->m.store_result = MYSQLND_METHOD(mysqlnd_res, store_result); - ret->m.background_store_result = MYSQLND_METHOD(mysqlnd_res, background_store_result); ret->m.free_result = MYSQLND_METHOD(mysqlnd_res, free_result); ret->m.seek_data = MYSQLND_METHOD(mysqlnd_res, data_seek); ret->m.num_rows = MYSQLND_METHOD(mysqlnd_res, num_rows); |