conn->m->free_contents(conn TSRMLS_CC);
conn->m->free_options(conn TSRMLS_CC);
-#ifdef MYSQLND_THREADED
- if (conn->thread_is_running) {
- pthread_mutex_lock(&conn->LOCK_work);
- conn->thread_killed = TRUE;
- pthread_cond_signal(&conn->COND_work);
- pthread_cond_wait(&conn->COND_thread_ended, &conn->LOCK_work);
- pthread_mutex_unlock(&conn->LOCK_work);
- }
-
- tsrm_mutex_free(conn->LOCK_state);
-
- pthread_cond_destroy(&conn->COND_work);
- pthread_cond_destroy(&conn->COND_work_done);
- pthread_mutex_destroy(&conn->LOCK_work);
-#endif
-
mnd_pefree(conn, conn->persistent);
DBG_VOID_RETURN;
DBG_INF("unicode set");
}
#endif
-#ifdef MYSQLND_THREADED
- {
- pthread_t th;
- pthread_attr_t connection_attrib;
- conn->tsrm_ls = tsrm_ls;
-
- pthread_attr_init(&connection_attrib);
- pthread_attr_setdetachstate(&connection_attrib, PTHREAD_CREATE_DETACHED);
-
- conn->thread_is_running = TRUE;
- if (pthread_create(&th, &connection_attrib, mysqlnd_fetch_thread, (void*)conn)) {
- conn->thread_is_running = FALSE;
- }
- }
-#endif
if (conn->options.init_commands) {
int current_command = 0;
/* {{{ mysqlnd_conn::get_state */
-#ifdef MYSQLND_THREADED
-static enum mysqlnd_connection_state
-MYSQLND_METHOD_PRIVATE(mysqlnd_conn, get_state)(MYSQLND * const conn TSRMLS_DC)
-{
- enum mysqlnd_connection_state state;
- DBG_ENTER("mysqlnd_conn::get_state");
- tsrm_mutex_lock(conn->LOCK_state);
- state = conn->state;
- tsrm_mutex_unlock(conn->LOCK_state);
- DBG_RETURN(state);
-}
-#else
static enum mysqlnd_connection_state
MYSQLND_METHOD_PRIVATE(mysqlnd_conn, get_state)(MYSQLND * const conn TSRMLS_DC)
{
DBG_ENTER("mysqlnd_conn::get_state");
DBG_RETURN(conn->state);
}
-#endif
/* }}} */
MYSQLND_METHOD_PRIVATE(mysqlnd_conn, set_state)(MYSQLND * const conn, enum mysqlnd_connection_state new_state TSRMLS_DC)
{
DBG_ENTER("mysqlnd_conn::set_state");
-#ifdef MYSQLND_THREADED
- tsrm_mutex_lock(conn->LOCK_state);
-#endif
DBG_INF_FMT("New state=%d", new_state);
conn->state = new_state;
-#ifdef MYSQLND_THREADED
- tsrm_mutex_unlock(conn->LOCK_state);
-#endif
DBG_VOID_RETURN;
}
/* }}} */
/* }}} */
-/* {{{ mysqlnd_conn::background_store_result */
-MYSQLND_RES *
-MYSQLND_METHOD(mysqlnd_conn, background_store_result)(MYSQLND * const conn TSRMLS_DC)
-{
- MYSQLND_RES *result;
-
- DBG_ENTER("mysqlnd_conn::store_result");
- DBG_INF_FMT("conn=%llu", conn->thread_id);
-
- if (!conn->current_result) {
- DBG_RETURN(NULL);
- }
-
- /* Nothing to store for UPSERT/LOAD DATA*/
- if (conn->last_query_type != QUERY_SELECT || CONN_GET_STATE(conn) != CONN_FETCHING_DATA) {
- SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE,
- mysqlnd_out_of_sync);
- DBG_ERR("Command out of sync");
- DBG_RETURN(NULL);
- }
-
- MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_BUFFERED_SETS);
-
- result = conn->current_result;
-
- result = result->m.background_store_result(result, conn, FALSE TSRMLS_CC);
-
- /*
- Should be here, because current_result is used by the fetching thread to get data info
- The thread is contacted in mysqlnd_res::background_store_result().
- */
- conn->current_result = NULL;
-
- DBG_RETURN(result);
-}
-/* }}} */
-
-
/* {{{ mysqlnd_conn::get_connection_stats */
static void
MYSQLND_METHOD(mysqlnd_conn, get_connection_stats)(const MYSQLND * const conn,
MYSQLND_METHOD(mysqlnd_conn, reap_query),
MYSQLND_METHOD(mysqlnd_conn, use_result),
MYSQLND_METHOD(mysqlnd_conn, store_result),
- MYSQLND_METHOD(mysqlnd_conn, background_store_result),
MYSQLND_METHOD(mysqlnd_conn, next_result),
MYSQLND_METHOD(mysqlnd_conn, more_results),
ret->net.stream_read = mysqlnd_read_from_stream;
ret->net.stream_write = mysqlnd_stream_write;
-#ifdef MYSQLND_THREADED
- ret->LOCK_state = tsrm_mutex_alloc();
-
- pthread_mutex_init(&ret->LOCK_work, NULL);
- pthread_cond_init(&ret->COND_work, NULL);
- pthread_cond_init(&ret->COND_work_done, NULL);
- pthread_cond_init(&ret->COND_thread_ended, NULL);
-#endif
-
DBG_RETURN(ret);
}
/* }}} */
#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
/* }}} */
-#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)
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);
/* }}} */
-#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)
/* }}} */
-#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)
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);