Author: ahristov
Date: 2007-04-26 14:15:23 +0200 (Thu, 26 Apr 2007)
New Revision: 353
Modified:
branches/qcache/mysqlnd/mysqlnd.c
branches/qcache/mysqlnd/mysqlnd_palloc.c
branches/qcache/mysqlnd/mysqlnd_palloc.h
Log:
merge from trunk
Modified: branches/qcache/mysqlnd/mysqlnd.c
===================================================================
--- branches/qcache/mysqlnd/mysqlnd.c 2007-04-26 12:13:03 UTC (rev 352)
+++ branches/qcache/mysqlnd/mysqlnd.c 2007-04-26 12:15:23 UTC (rev 353)
@@ -49,10 +49,6 @@
sent to the network like writev() and this can save at least for
mysqlnd_stmt_send_long_data() new malloc. This change will probably make the
code in few other places cleaner.
-
- - We have to thread_id, given back from tsrm_thread_id() in ZTS
- to `mysqlnd_zval` so a thread will clean only its variables, and not
- verything, which will lead to a crash in a MT environment.
*/
extern MYSQLND_CHARSET *mysqlnd_charsets;
Modified: branches/qcache/mysqlnd/mysqlnd_palloc.c
===================================================================
--- branches/qcache/mysqlnd/mysqlnd_palloc.c 2007-04-26 12:13:03 UTC (rev 352)
+++ branches/qcache/mysqlnd/mysqlnd_palloc.c 2007-04-26 12:15:23 UTC (rev 353)
@@ -70,7 +70,7 @@
/* 2. Initialize the GC list */
ret->gc_list = calloc(1, sizeof(mysqlnd_ndzval_list));
ret->gc_list->ptr_line = calloc(ret->max_items, sizeof(mysqlnd_zval *));
- /* Backward and forward looping is possible */
+ /* Backward and forward looping is possible */
ret->gc_list->last_added = ret->gc_list->ptr_line;
/* 3. Allocate and initialize our zvals and initialize the free list */
@@ -151,7 +151,7 @@
mysqlnd_palloc_free_cache(*cache);
}
*cache = NULL;
- }
+ }
}
/* }}} */
@@ -178,7 +178,7 @@
empty_position, always 0x0 <-- last_added
5. free_zval -> if (free_items++ != max_items) {// we can add more
- *(--last_added) = zval_ptr;
+ *(--last_added) = zval_ptr;
}
(memory addresses increase downwards)
0x0
@@ -190,7 +190,7 @@
0x0
6. free_zval -> if (free_items++ != max_items) {// we can add more
- *(--last_added) = zval_ptr;
+ *(--last_added) = zval_ptr;
}
0x0
0x0
@@ -201,7 +201,7 @@
0x0
7. free_zval -> if (free_items++ != max_items) {// we can add more
- *(--last_added) = zval_ptr;
+ *(--last_added) = zval_ptr;
}
0x0
0x0
@@ -255,8 +255,11 @@
LOCK_PCACHE(cache);
if ((ret = *cache->free_list->last_added)) {
*cache->free_list->last_added++ = NULL;
+ *allocated = FALSE;
+#ifdef ZTS
+ ((mysqlnd_zval *) ret)->thread_id = tsrm_thread_id();
+#endif
--cache->free_items;
- *allocated = FALSE;
++cache->get_hits;
} else {
++cache->get_misses;
@@ -310,10 +313,10 @@
I suppose we can use UG(unicode) in mysqlnd.c when freeing a result set
to check if we need to call copy_ctor().
- If the type is IS_UNICODE, which can happen with PHP6, then we don't
- need to copy_ctor, as the data doesn't point to our internal buffers.
- If it's string (in PHP5 always) and in PHP6 if data is binary, then
- it still points to internal buffers and has to be copied.
+ If the type is IS_UNICODE, which can happen with PHP6, then we don't
+ need to copy_ctor, as the data doesn't point to our internal buffers.
+ If it's string (in PHP5 always) and in PHP6 if data is binary, then
+ it still points to internal buffers and has to be copied.
*/
if (Z_TYPE_PP(zv) == IS_STRING) {
zval_copy_ctor(*zv);
@@ -376,20 +379,23 @@
*/
LOCK_PCACHE(cache);
++cache->put_misses;
+ *(cache->gc_list->last_added++) = (mysqlnd_zval *)*zv;
UNLOCK_PCACHE(cache);
} else {
/* No user reference */
- LOCK_PCACHE(cache);
-
- ++cache->put_hits;
- ++cache->free_items;
if (((mysqlnd_zval *)*zv)->point_type == MYSQLND_POINTS_EXT_BUFFER) {
/* PS are here and also in Unicode mode, for non-binary */
zval_dtor(*zv);
}
- ((mysqlnd_zval *)*zv)->point_type = MYSQLND_POINTS_FREE;
+ LOCK_PCACHE(cache);
+ ++cache->put_hits;
+ ++cache->free_items;
+ ((mysqlnd_zval *)*zv)->point_type = MYSQLND_POINTS_FREE;
ZVAL_DELREF(*zv); /* Make it 1 */
ZVAL_NULL(*zv);
+#ifdef ZTS
+ memset(&((mysqlnd_zval *)*zv)->thread_id, 0, sizeof(THREAD_T));
+#endif
*(--cache->free_list->last_added) = (mysqlnd_zval *)*zv;
UNLOCK_PCACHE(cache);
@@ -410,6 +416,9 @@
PHPAPI void mysqlnd_palloc_rshutdown(MYSQLND_ZVAL_PCACHE * const cache)
{
unsigned int i;
+#ifdef ZTS
+ THREAD_T thread_id;
+#endif
#ifndef MYSQLND_SILENT
php_printf("[mysqlnd_palloc_rshutdown %p]\n", cache);
#endif
@@ -417,19 +426,32 @@
return;
}
+ thread_id = tsrm_thread_id();
/*
- XXX: We have to thread_id, given back from tsrm_thread_id() in ZTS
- to `mysqlnd_zval` so a thread will clean only its variables, and not
- everything, which will lead to a crash in a MT environment.
-
+ 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.
*/
LOCK_PCACHE(cache);
for (i = 0; i < cache->max_items; i++) {
- if (cache->block[i].point_type == MYSQLND_POINTS_EXT_BUFFER) {
+ if (
+ cache->block[i].point_type == MYSQLND_POINTS_EXT_BUFFER
+#ifdef ZTS
+#if defined(PTHREADS)
+ && pthread_equal(cache->block[i].thread_id, thread_id)
+#else
+ && cache->block[i].thread_id == thread_id
+#endif
+#endif
+ )
+ {
zval_dtor(&(cache->block[i].zv));
cache->block[i].point_type = MYSQLND_POINTS_FREE;
*(--cache->free_list->last_added) = &(cache->block[i]);
++cache->free_items;
+#ifdef ZTS
+ memset(&cache->block[i].thread_id, 0, sizeof(THREAD_T));
+#endif
}
}
UNLOCK_PCACHE(cache);
Modified: branches/qcache/mysqlnd/mysqlnd_palloc.h
===================================================================
--- branches/qcache/mysqlnd/mysqlnd_palloc.h 2007-04-26 12:13:03 UTC (rev 352)
+++ branches/qcache/mysqlnd/mysqlnd_palloc.h 2007-04-26 12:15:23 UTC (rev 353)
@@ -55,6 +55,9 @@
/* Should be first */
zval zv;
enum mysqlnd_zval_ptr_type point_type;
+#ifdef ZTS
+ THREAD_T thread_id;
+#endif
} mysqlnd_zval;
| Thread |
|---|
| • PHP mysqlnd svn commit: r353 - branches/qcache/mysqlnd | ahristov | 26 Apr |