Пример #1
0
static void *zend_file_cache_serialize_interned(zend_string              *str,
                                                zend_file_cache_metainfo *info)
{
	size_t len;
	void *ret;

	/* check if the same interned string was already stored */
	ret = zend_shared_alloc_get_xlat_entry(str);
	if (ret) {
		return ret;
	}

	len = ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(ZSTR_LEN(str)));
	ret = (void*)(info->str_size | Z_UL(1));
	zend_shared_alloc_register_xlat_entry(str, ret);
	if (info->str_size + len > ZSTR_LEN((zend_string*)ZCG(mem))) {
		size_t new_len = info->str_size + len;
		ZCG(mem) = (void*)zend_string_realloc(
			(zend_string*)ZCG(mem),
			((_ZSTR_HEADER_SIZE + 1 + new_len + 4095) & ~0xfff) - (_ZSTR_HEADER_SIZE + 1),
			0);
	}
	memcpy(ZSTR_VAL((zend_string*)ZCG(mem)) + info->str_size, str, len);
	info->str_size += len;
	return ret;
}
Пример #2
0
/* {{{ */
zend_string* pthreads_globals_string(zend_string *str) {
	/*
	 This is sourcery of the darkest kind ...
	
	 We don't need all threads to have a copy of every string used as the name for a threaded objects property.
	 
	 In addition, Zend has troubles with persistent strings in non-persistent hashes and vice versa, to avoid these
	 we have a global table of strings that is used when writing to threaded objects properties, this table is detroyed
	 on shutdown of the process, so will show as leaked, but we don't care, we want stable !
	*/
	zend_string* p = NULL;
	if (pthreads_globals_lock()) {
		if (!(p = zend_hash_find_ptr(&PTHREADS_G(gstrings), str)) && 
			(p = (zend_string*) malloc(ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(ZSTR_LEN(str)))))) {
			memset(p, 0, sizeof(zend_string));

			GC_REFCOUNT(p) = 2;
			GC_TYPE_INFO(p) = IS_STR_PERSISTENT;

			memcpy(ZSTR_VAL(p), ZSTR_VAL(str), ZSTR_LEN(str));
			p->len = ZSTR_LEN(str);
			ZSTR_VAL(p)[ZSTR_LEN(p)] = '\0';
			zend_string_forget_hash_val(p);
			zend_hash_update_ptr(
				&PTHREADS_G(gstrings), p, p);
		}

		pthreads_globals_unlock();
	}

	return p;
} /* }}} */