123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- #include "php.h"
- #include "mysqlnd.h"
- #include "mysqlnd_block_alloc.h"
- #include "mysqlnd_debug.h"
- #include "mysqlnd_priv.h"
- static void
- mysqlnd_mempool_free_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk TSRMLS_DC)
- {
- MYSQLND_MEMORY_POOL * pool = chunk->pool;
- DBG_ENTER("mysqlnd_mempool_free_chunk");
- if (chunk->from_pool) {
-
- if (chunk->ptr == (pool->arena + (pool->arena_size - pool->free_size - chunk->size))) {
-
- pool->free_size += chunk->size;
- }
- pool->refcount--;
- } else {
- mnd_free(chunk->ptr);
- }
- mnd_free(chunk);
- DBG_VOID_RETURN;
- }
- static enum_func_status
- mysqlnd_mempool_resize_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int size TSRMLS_DC)
- {
- DBG_ENTER("mysqlnd_mempool_resize_chunk");
- if (chunk->from_pool) {
- MYSQLND_MEMORY_POOL * pool = chunk->pool;
-
- if (chunk->ptr == (pool->arena + (pool->arena_size - pool->free_size - chunk->size))) {
-
- if ((chunk->size + pool->free_size) < size) {
- zend_uchar *new_ptr;
- new_ptr = mnd_malloc(size);
- if (!new_ptr) {
- DBG_RETURN(FAIL);
- }
- memcpy(new_ptr, chunk->ptr, chunk->size);
- chunk->ptr = new_ptr;
- pool->free_size += chunk->size;
- chunk->size = size;
- chunk->pool = NULL;
- pool->refcount--;
- } else {
-
- pool->free_size += (chunk->size - size);
- }
- } else {
-
- if (chunk->size >= size) {
- ;
- } else {
- zend_uchar *new_ptr;
- new_ptr = mnd_malloc(size);
- if (!new_ptr) {
- DBG_RETURN(FAIL);
- }
- memcpy(new_ptr, chunk->ptr, chunk->size);
- chunk->ptr = new_ptr;
- chunk->size = size;
- chunk->pool = NULL;
- pool->refcount--;
- }
- }
- } else {
- zend_uchar *new_ptr = mnd_realloc(chunk->ptr, size);
- if (!new_ptr) {
- DBG_RETURN(FAIL);
- }
- chunk->ptr = new_ptr;
- }
- DBG_RETURN(PASS);
- }
- static
- MYSQLND_MEMORY_POOL_CHUNK * mysqlnd_mempool_get_chunk(MYSQLND_MEMORY_POOL * pool, unsigned int size TSRMLS_DC)
- {
- MYSQLND_MEMORY_POOL_CHUNK *chunk = NULL;
- DBG_ENTER("mysqlnd_mempool_get_chunk");
- chunk = mnd_malloc(sizeof(MYSQLND_MEMORY_POOL_CHUNK));
- if (chunk) {
- chunk->free_chunk = mysqlnd_mempool_free_chunk;
- chunk->resize_chunk = mysqlnd_mempool_resize_chunk;
- chunk->size = size;
-
- chunk->pool = pool;
- if (size > pool->free_size) {
- chunk->from_pool = FALSE;
- chunk->ptr = mnd_malloc(size);
- if (!chunk->ptr) {
- chunk->free_chunk(chunk TSRMLS_CC);
- chunk = NULL;
- }
- } else {
- chunk->from_pool = TRUE;
- ++pool->refcount;
- chunk->ptr = pool->arena + (pool->arena_size - pool->free_size);
-
- pool->free_size -= size;
- }
- }
- DBG_RETURN(chunk);
- }
- PHPAPI MYSQLND_MEMORY_POOL *
- mysqlnd_mempool_create(size_t arena_size TSRMLS_DC)
- {
-
- MYSQLND_MEMORY_POOL * ret = mnd_calloc(1, sizeof(MYSQLND_MEMORY_POOL));
- DBG_ENTER("mysqlnd_mempool_create");
- if (ret) {
- ret->get_chunk = mysqlnd_mempool_get_chunk;
- ret->free_size = ret->arena_size = arena_size ? arena_size : 0;
- ret->refcount = 0;
-
- ret->arena = mnd_malloc(ret->arena_size);
- if (!ret->arena) {
- mysqlnd_mempool_destroy(ret TSRMLS_CC);
- ret = NULL;
- }
- }
- DBG_RETURN(ret);
- }
- PHPAPI void
- mysqlnd_mempool_destroy(MYSQLND_MEMORY_POOL * pool TSRMLS_DC)
- {
- DBG_ENTER("mysqlnd_mempool_destroy");
-
- mnd_free(pool->arena);
- mnd_free(pool);
- DBG_VOID_RETURN;
- }
|