diff options
Diffstat (limited to 'ext/mysqlnd/mysqlnd_palloc.c')
| -rw-r--r-- | ext/mysqlnd/mysqlnd_palloc.c | 85 | 
1 files changed, 34 insertions, 51 deletions
diff --git a/ext/mysqlnd/mysqlnd_palloc.c b/ext/mysqlnd/mysqlnd_palloc.c index f429af49f5..da6e2b07a6 100644 --- a/ext/mysqlnd/mysqlnd_palloc.c +++ b/ext/mysqlnd/mysqlnd_palloc.c @@ -189,13 +189,43 @@ MYSQLND_THD_ZVAL_PCACHE* _mysqlnd_palloc_get_thd_cache_reference(MYSQLND_THD_ZVA    constructor of the cache.  */  static -void mysqlnd_palloc_free_thd_cache(MYSQLND_THD_ZVAL_PCACHE *cache TSRMLS_DC) +void mysqlnd_palloc_free_thd_cache(MYSQLND_THD_ZVAL_PCACHE *thd_cache TSRMLS_DC)  { +	MYSQLND_ZVAL_PCACHE *global_cache; +	mysqlnd_zval **p; +  	DBG_ENTER("mysqlnd_palloc_free_thd_cache"); -	DBG_INF_FMT("cache=%p", cache); +	DBG_INF_FMT("thd_cache=%p", thd_cache); -	mnd_free(cache->gc_list.ptr_line); -	mnd_free(cache); +	if ((global_cache = thd_cache->parent)) { +		/* +		  Keep in mind that for pthreads pthread_equal() should be used to be +		  fully standard compliant. However, the PHP code all-around, incl. the +		  the Zend MM uses direct comparison. +		*/ +		p = thd_cache->gc_list.ptr_line; +		while (p < thd_cache->gc_list.last_added) { +			zval_dtor(&(*p)->zv); +			p++; +		} + +		p = thd_cache->gc_list.ptr_line; + +		LOCK_PCACHE(global_cache); +		while (p < thd_cache->gc_list.last_added) { +			(*p)->point_type = MYSQLND_POINTS_FREE; +			*(--global_cache->free_list.last_added) = *p; +			++global_cache->free_items; +#ifdef ZTS +			memset(&((*p)->thread_id), 0, sizeof(THREAD_T)); +#endif +			p++; +		} +		UNLOCK_PCACHE(global_cache); + +	} +	mnd_free(thd_cache->gc_list.ptr_line); +	mnd_free(thd_cache);  	DBG_VOID_RETURN;  } @@ -508,56 +538,9 @@ PHPAPI MYSQLND_THD_ZVAL_PCACHE * _mysqlnd_palloc_rinit(MYSQLND_ZVAL_PCACHE * cac  /* {{{ _mysqlnd_palloc_rshutdown */  PHPAPI void _mysqlnd_palloc_rshutdown(MYSQLND_THD_ZVAL_PCACHE * thd_cache TSRMLS_DC)  { -	MYSQLND_ZVAL_PCACHE *cache; -	mysqlnd_zval **p; -  	DBG_ENTER("_mysqlnd_palloc_rshutdown");  	DBG_INF_FMT("cache=%p", thd_cache); - -	if (!thd_cache || !(cache = thd_cache->parent)) { -		return; -	} - -	/* -	  !!! 080624 !!! -	  If the user has used Persistent Connections the reference counter -	  of the cache is not 1 but > 1 . Because the Pconns don't are not signalised -	  during RSHUT, then we need to take care here to decrease the counter. -	  A more proper fix will be to array_walk our pconns in RSHUT and ask them to -	  free their thd reference. This should be implemented sooner or later! -	*/ -	 -	/* -	  Keep in mind that for pthreads pthread_equal() should be used to be -	  fully standard compliant. However, the PHP code all-around, incl. the -	  the Zend MM uses direct comparison. -	*/ -	p = thd_cache->gc_list.ptr_line; -	while (p < thd_cache->gc_list.last_added) { -		zval_dtor(&(*p)->zv); -		p++; -	} - -	p = thd_cache->gc_list.ptr_line; - -	LOCK_PCACHE(cache); -	/* We need to decrease Main cache's references as pconns don't clean correctly */ -	cache->references -= (thd_cache->references - 1); /* we start with 1 initial reference */ -	while (p < thd_cache->gc_list.last_added) { -		(*p)->point_type = MYSQLND_POINTS_FREE; -		*(--cache->free_list.last_added) = *p; -		++cache->free_items; -#ifdef ZTS -		memset(&((*p)->thread_id), 0, sizeof(THREAD_T)); -#endif -		p++; -	} -	UNLOCK_PCACHE(cache); - -	/* We need to decrease thd cache's references as pconns don't clean correctly. See above! */ -	thd_cache->references = 1;  	mysqlnd_palloc_free_thd_cache_reference(&thd_cache); -  	DBG_VOID_RETURN;  }  /* }}} */  | 
