List:Commits« Previous MessageNext Message »
From:ahristov Date:February 14 2008 12:41pm
Subject:PHP mysqlnd svn commit: r1279 - trunk/mysqlnd
View as plain text  
Author: ahristov
Date: 2008-02-14 13:41:41 +0100 (Thu, 14 Feb 2008)
New Revision: 1279

Modified:
   trunk/mysqlnd/mysqlnd.c
   trunk/mysqlnd/mysqlnd.h
   trunk/mysqlnd/mysqlnd_debug.c
   trunk/mysqlnd/mysqlnd_debug.h
   trunk/mysqlnd/mysqlnd_ps.c
   trunk/mysqlnd/mysqlnd_result.c
   trunk/mysqlnd/mysqlnd_wireprotocol.c
   trunk/mysqlnd/mysqlnd_wireprotocol.h
   trunk/mysqlnd/php_mysqlnd.c
Log:
Fixes for bg_store - actually working now, and no crashes


Modified: trunk/mysqlnd/mysqlnd.c
===================================================================
--- trunk/mysqlnd/mysqlnd.c	2008-02-13 17:11:47 UTC (rev 1278)
+++ trunk/mysqlnd/mysqlnd.c	2008-02-14 12:41:41 UTC (rev 1279)
@@ -546,7 +546,7 @@
 
 
 	PACKET_INIT_ALLOCA(greet_packet, PROT_GREET_PACKET);
-	PACKET_INIT(auth_packet, PROT_AUTH_PACKET, php_mysql_packet_auth *);
+	PACKET_INIT(auth_packet, PROT_AUTH_PACKET, php_mysql_packet_auth *, FALSE);
 	PACKET_INIT_ALLOCA(ok_packet, PROT_OK_PACKET);
 
 	if (!conn) {
@@ -770,7 +770,7 @@
 		}
 
 		DBG_INF_FMT("connection_id=%llu", conn->thread_id);
-		conn->result_set_memory_pool = mysqlnd_mempool_create(16000 TSRMLS_CC);
+		conn->result_set_memory_pool = mysqlnd_mempool_create(100 TSRMLS_CC);
 #if PHP_MAJOR_VERSION >= 6
 		{
 			uint as_unicode = 1;
@@ -851,7 +851,7 @@
 									   FALSE TSRMLS_CC)) {
 		DBG_RETURN(FAIL);
 	}
-
+	CONN_SET_STATE(conn, CONN_QUERY_SENT);
 	/*
 	  Here read the result set. We don't do it in simple_command because it need
 	  information from the ok packet. We will fetch it ourselves.
@@ -866,12 +866,15 @@
 static enum_func_status
 MYSQLND_METHOD(mysqlnd_conn, send_query)(MYSQLND *conn, const char *query, unsigned int
query_len TSRMLS_DC)
 {
+	enum_func_status ret;
 	DBG_ENTER("mysqlnd_conn::send_query");
 	DBG_INF_FMT("conn=%llu query=%s", conn->thread_id, query);
 
-	DBG_RETURN(mysqlnd_simple_command(conn, COM_QUERY, query, query_len,
-									  PROT_LAST /* we will handle the OK packet*/,
-									  FALSE TSRMLS_CC));
+	ret = mysqlnd_simple_command(conn, COM_QUERY, query, query_len,
+								 PROT_LAST /* we will handle the OK packet*/,
+								 FALSE TSRMLS_CC);
+	CONN_SET_STATE(conn, CONN_QUERY_SENT);
+	DBG_RETURN(ret);
 }
 /* }}} */
 
@@ -1531,6 +1534,7 @@
 #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);

Modified: trunk/mysqlnd/mysqlnd.h
===================================================================
--- trunk/mysqlnd/mysqlnd.h	2008-02-13 17:11:47 UTC (rev 1278)
+++ trunk/mysqlnd/mysqlnd.h	2008-02-14 12:41:41 UTC (rev 1279)
@@ -350,6 +350,9 @@
 	MYSQLND_DEBUG	*dbg;	/* The DBG object */
 	long			net_cmd_buffer_size;
 	long			net_read_buffer_size;
+#ifdef ZTS
+	THREAD_T		thread_id;
+#endif
 ZEND_END_MODULE_GLOBALS(mysqlnd)
 
 ZEND_EXTERN_MODULE_GLOBALS(mysqlnd);

Modified: trunk/mysqlnd/mysqlnd_debug.c
===================================================================
--- trunk/mysqlnd/mysqlnd_debug.c	2008-02-13 17:11:47 UTC (rev 1278)
+++ trunk/mysqlnd/mysqlnd_debug.c	2008-02-14 12:41:41 UTC (rev 1279)
@@ -95,6 +95,12 @@
 		 line_buffer[6], level_buffer[7];
 	MYSQLND_ZTS(self);
 
+#ifdef ZTS
+	if (MYSQLND_G(thread_id) != tsrm_thread_id()) {
+		return PASS; /* don't trace background threads */
+	}
+#endif
+
 	if (!self->stream) {
 		if (FAIL == self->m->open(self, FALSE)) {
 			return FAIL;
@@ -195,6 +201,12 @@
 		 line_buffer[6], level_buffer[7];
 	MYSQLND_ZTS(self);
 
+#ifdef ZTS
+	if (MYSQLND_G(thread_id) != tsrm_thread_id()) {
+		return PASS; /* don't trace background threads */
+	}
+#endif
+
 	if (!self->stream) {
 		if (FAIL == self->m->open(self, FALSE)) {
 			return FAIL;
@@ -291,9 +303,15 @@
 										  unsigned int line, const char * const file,
 										  char * func_name, uint func_name_len)
 {
+	MYSQLND_ZTS(self);
 	if ((self->flags & MYSQLND_DEBUG_DUMP_TRACE) == 0 || self->file_name == NULL)
{
 		return FALSE;
 	}
+#ifdef ZTS
+	if (MYSQLND_G(thread_id) != tsrm_thread_id()) {
+		return FALSE; /* don't trace background threads */
+	}
+#endif
 	if (zend_stack_count(&self->call_stack) >= self->nest_level_limit) {
 		return FALSE;
 	}
@@ -303,7 +321,6 @@
 		 func_name == mysqlnd_ecalloc_name	|| func_name == mysqlnd_pecalloc_name	||
 		 func_name == mysqlnd_erealloc_name || func_name == mysqlnd_perealloc_name	||
 		 func_name == mysqlnd_efree_name	|| func_name == mysqlnd_pefree_name		|| 
-		 func_name == mysqlnd_efree_name	|| func_name == mysqlnd_pefree_name		|| 
 		 func_name == mysqlnd_malloc_name	|| func_name == mysqlnd_calloc_name		|| 
 		 func_name == mysqlnd_realloc_name	|| func_name == mysqlnd_free_name		||
 		 func_name == mysqlnd_palloc_zval_ptr_dtor_name	|| func_name ==
mysqlnd_palloc_get_zval_name ||
@@ -332,10 +349,16 @@
 										  const char * const file)
 {
 	char *func_name;
+	MYSQLND_ZTS(self);
 
 	if ((self->flags & MYSQLND_DEBUG_DUMP_TRACE) == 0 || self->file_name == NULL)
{
 		return PASS;
 	}
+#ifdef ZTS
+	if (MYSQLND_G(thread_id) != tsrm_thread_id()) {
+		return PASS; /* don't trace background threads */
+	}
+#endif
 	if (zend_stack_count(&self->call_stack) >= self->nest_level_limit) {
 		return PASS;
 	}
@@ -644,6 +667,12 @@
 {
 	void *ret;
 	DBG_ENTER(mysqlnd_emalloc_name);
+#ifdef ZTS
+	if (MYSQLND_G(thread_id) != tsrm_thread_id()) {
+		DBG_RETURN(_mysqlnd_pemalloc(size, 1 TSRMLS_CC ZEND_FILE_LINE_CC
ZEND_FILE_LINE_EMPTY_CC));
+	}
+#endif
+
 	DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1,
__zend_lineno);
 	DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC));
 	ret = emalloc(size);
@@ -691,6 +720,11 @@
 {
 	void *ret;
 	DBG_ENTER(mysqlnd_ecalloc_name);
+#ifdef ZTS
+	if (MYSQLND_G(thread_id) != tsrm_thread_id()) {
+		DBG_RETURN(_mysqlnd_pecalloc(nmemb, size, 1 TSRMLS_CC ZEND_FILE_LINE_CC
ZEND_FILE_LINE_EMPTY_CC));
+	}
+#endif
 	DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1,
__zend_lineno);
 	DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC));
 
@@ -739,6 +773,11 @@
 {
 	void *ret;
 	DBG_ENTER(mysqlnd_erealloc_name);
+#ifdef ZTS
+	if (MYSQLND_G(thread_id) != tsrm_thread_id()) {
+		DBG_RETURN(_mysqlnd_perealloc(ptr, new_size, 1 TSRMLS_CC ZEND_FILE_LINE_CC
ZEND_FILE_LINE_EMPTY_CC));
+	}
+#endif
 	DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1,
__zend_lineno);
 	DBG_INF_FMT("ptr=%p new_size=%lu", ptr, new_size); 
 	DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC));
@@ -788,6 +827,11 @@
 void _mysqlnd_efree(void *ptr MYSQLND_MEM_D)
 {
 	DBG_ENTER(mysqlnd_efree_name);
+#ifdef ZTS
+	if (MYSQLND_G(thread_id) != tsrm_thread_id()) {
+		DBG_RETURN(_mysqlnd_pefree(ptr, 1 TSRMLS_CC ZEND_FILE_LINE_CC
ZEND_FILE_LINE_EMPTY_CC));
+	}
+#endif
 	DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1,
__zend_lineno);
 	DBG_INF_FMT("ptr=%p", ptr); 
 	DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC));

Modified: trunk/mysqlnd/mysqlnd_debug.h
===================================================================
--- trunk/mysqlnd/mysqlnd_debug.h	2008-02-13 17:11:47 UTC (rev 1278)
+++ trunk/mysqlnd/mysqlnd_debug.h	2008-02-14 12:41:41 UTC (rev 1279)
@@ -25,7 +25,7 @@
 
 #include "zend_stack.h"
 
-#define MYSQLND_DEBUG_MEMORY 1
+#define MYSQLND_DEBUG_MEMORY 0
 
 struct st_mysqlnd_debug_methods
 {

Modified: trunk/mysqlnd/mysqlnd_ps.c
===================================================================
--- trunk/mysqlnd/mysqlnd_ps.c	2008-02-13 17:11:47 UTC (rev 1278)
+++ trunk/mysqlnd/mysqlnd_ps.c	2008-02-14 12:41:41 UTC (rev 1279)
@@ -513,6 +513,8 @@
 	}
 	stmt->execute_count++;
 
+	CONN_SET_STATE(conn, CONN_QUERY_SENT);
+
 	ret = mysqlnd_query_read_result_set_header(stmt->conn, stmt TSRMLS_CC);
 	if (ret == FAIL) {
 		stmt->error_info = conn->error_info;

Modified: trunk/mysqlnd/mysqlnd_result.c
===================================================================
--- trunk/mysqlnd/mysqlnd_result.c	2008-02-13 17:11:47 UTC (rev 1278)
+++ trunk/mysqlnd/mysqlnd_result.c	2008-02-14 12:41:41 UTC (rev 1279)
@@ -40,32 +40,36 @@
 	MYSQLND_RES * result = NULL;
 	void ***tsrm_ls = conn->tsrm_ls;
 #ifndef MYSQLND_SILENT
-	printf("conn=%p tsrm_ls=%p\n", conn, conn->tsrm_ls);
+	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 /* && there is work */) {
+		while (conn->thread_killed == FALSE && !conn->current_result) {
 #ifndef MYSQLND_SILENT
-			printf("Waiting for work in %s\n", __FUNCTION__);
+			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 killed in %s\n", __FUNCTION__);
+			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("Got work in %s\n", __FUNCTION__);
+		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 */
@@ -74,13 +78,13 @@
 		CONN_SET_STATE(conn, CONN_READY);
 		pthread_cond_signal(&conn->COND_work_done);
 #ifndef MYSQLND_SILENT
-		printf("Signaling work done in %s\n", __FUNCTION__);
+		printf("THREAD] Signaling work done in %s\n", __FUNCTION__);
 #endif
 		pthread_mutex_unlock(&conn->LOCK_work);
 	} while (1);
 
 #ifndef MYSQLND_SILENT
-	printf("Exiting worker thread in %s\n", __FUNCTION__);
+	printf("THREAD] Exiting worker thread in %s\n", __FUNCTION__);
 #endif
 	return NULL;
 }
@@ -461,6 +465,8 @@
 			*/
 			conn->error_info = rset_header.error_info;
 			ret = FAIL;
+			/* Return back from CONN_QUERY_SENT */
+			CONN_SET_STATE(conn, CONN_READY);
 			break;
 		}
 		conn->error_info.error_no = 0;
@@ -976,7 +982,8 @@
 	  by the resource destructor. mysqlnd_fetch_row_unbuffered() expects
 	  this to be not NULL.
 	*/
-	PACKET_INIT(result->row_packet, PROT_ROW_PACKET, php_mysql_packet_row *);
+	/* FALSE = non-persistent */
+	PACKET_INIT(result->row_packet, PROT_ROW_PACKET, php_mysql_packet_row *, FALSE);
 	result->row_packet->field_count = result->field_count;
 	result->row_packet->binary_protocol = ps;
 	result->row_packet->fields_metadata = result->meta->fields;
@@ -1182,7 +1189,8 @@
 	set->qcache		= to_cache? mysqlnd_qcache_get_cache_reference(conn->qcache):NULL;
 	set->references	= 1;
 
-	PACKET_INIT(row_packet, PROT_ROW_PACKET, php_mysql_packet_row *);
+	/* non-persistent */
+	PACKET_INIT(row_packet, PROT_ROW_PACKET, php_mysql_packet_row *, FALSE);
 	row_packet->field_count = meta->field_count;
 	row_packet->binary_protocol = binary_protocol;
 	row_packet->fields_metadata = meta->fields;
@@ -1315,6 +1323,7 @@
 	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)) {
@@ -1439,15 +1448,15 @@
 
 	free_rows = next_extend;
 
-	PACKET_INIT(row_packet, PROT_ROW_PACKET, php_mysql_packet_row *);
+	/* persistent */
+	PACKET_INIT(row_packet, PROT_ROW_PACKET, php_mysql_packet_row *, TRUE);
 	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;
 
-//	row_packet->skip_extraction = TRUE; /* let php_mysqlnd_rowp_read() not allocate
row_packet->fields, we will do it */
-
 	while (FAIL != (ret = PACKET_READ(row_packet, conn)) && !row_packet->eof) {
 		tsrm_mutex_lock(set->LOCK);
 		if (!free_rows) {
@@ -1560,7 +1569,7 @@
 	return (result->m.store_result(result, conn, ps TSRMLS_CC));
 #else
 	enum_func_status ret;
-	zend_bool to_cache = FALSE;
+	zend_bool to_cache = TRUE;
 
 	DBG_ENTER("mysqlnd_res::background_store_result");
 	DBG_INF_FMT("conn=%d ps_protocol=%d", conn->thread_id, ps);
@@ -1585,11 +1594,26 @@
 								php_mysqlnd_rowp_read_text_protocol;
 
 	CONN_SET_STATE(conn, CONN_FETCHING_DATA);
-	result->bg_stored_data->decode_in_foreground = FALSE;
+	/*
+	  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

Modified: trunk/mysqlnd/mysqlnd_wireprotocol.c
===================================================================
--- trunk/mysqlnd/mysqlnd_wireprotocol.c	2008-02-13 17:11:47 UTC (rev 1278)
+++ trunk/mysqlnd/mysqlnd_wireprotocol.c	2008-02-14 12:41:41 UTC (rev 1279)
@@ -1685,7 +1685,7 @@
 		not free the array. As it is passed to us, we should not clean it ourselves.
 	*/
 	if (!alloca) {
-		mnd_efree(p);
+		mnd_pefree(p, p->header.persistent);
 	}
 }
 /* }}} */
@@ -1723,7 +1723,7 @@
 		p->message = NULL;
 	}
 	if (!alloca) {
-		mnd_efree(p);
+		mnd_pefree(p, p->header.persistent);
 	}
 }
 /* }}} */
@@ -1807,7 +1807,7 @@
 {
 	php_mysql_packet_prepare_response *p= (php_mysql_packet_prepare_response *) _packet;
 	if (!alloca) {
-		mnd_efree(p);
+		mnd_pefree(p, p->header.persistent);
 	}
 }
 /* }}} */
@@ -1866,7 +1866,7 @@
 void php_mysqlnd_chg_user_free_mem(void *_packet, zend_bool alloca TSRMLS_DC)
 {
 	if (!alloca) {
-		mnd_efree(_packet);
+		mnd_pefree(_packet, ((php_mysql_packet_chg_user_resp *)_packet)->header.persistent);
 	}
 }
 /* }}} */

Modified: trunk/mysqlnd/mysqlnd_wireprotocol.h
===================================================================
--- trunk/mysqlnd/mysqlnd_wireprotocol.h	2008-02-13 17:11:47 UTC (rev 1278)
+++ trunk/mysqlnd/mysqlnd_wireprotocol.h	2008-02-14 12:41:41 UTC (rev 1279)
@@ -37,10 +37,11 @@
 
 
 /* Packet handling */
-#define PACKET_INIT(packet, enum_type, c_type)  \
+#define PACKET_INIT(packet, enum_type, c_type, pers)  \
 	{ \
-		packet = (c_type) ecalloc(1, packet_methods[enum_type].struct_size); \
-		((c_type) (packet))->header.m = &packet_methods[enum_type]; \
+		packet = (c_type) pecalloc(1, packet_methods[(enum_type)].struct_size, (pers)); \
+		((c_type) (packet))->header.m = &packet_methods[(enum_type)]; \
+		((c_type) (packet))->header.persistent = (pers); \
 	}
 #define PACKET_WRITE(packet, conn)	((packet)->header.m->write_to_net((packet),
(conn) TSRMLS_CC))
 #define PACKET_READ(packet, conn)	((packet)->header.m->read_from_net((packet),
(conn) TSRMLS_CC))
@@ -126,8 +127,9 @@
 
 typedef struct st_mysqlnd_packet_header {
 	size_t		size;
+	mysqlnd_packet_methods *m;
 	zend_uchar	packet_no;
-	mysqlnd_packet_methods *m;
+	zend_bool	persistent;
 } mysqlnd_packet_header;
 
 /* Server greets the client */

Modified: trunk/mysqlnd/php_mysqlnd.c
===================================================================
--- trunk/mysqlnd/php_mysqlnd.c	2008-02-13 17:11:47 UTC (rev 1278)
+++ trunk/mysqlnd/php_mysqlnd.c	2008-02-14 12:41:41 UTC (rev 1279)
@@ -189,7 +189,8 @@
 			return FAILURE;
 		}
 		dbg->m->set_mode(dbg, MYSQLND_G(debug));
-		MYSQLND_G(dbg) = dbg;	
+		MYSQLND_G(dbg) = dbg;
+		MYSQLND_G(thread_id) = tsrm_thread_id();
 	}
 	return SUCCESS;
 }

Thread
PHP mysqlnd svn commit: r1279 - trunk/mysqlndahristov14 Feb