Re: How to create Persistent zval?

From: Date: Sat, 18 Jan 2014 21:04:01 +0000
Subject: Re: How to create Persistent zval?
References: 1 2 3  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
On 01/18/2014 08:01 PM, Lin Yo-An wrote:
> By the way, Is this the reason of date ext always check the global
> HashTable and re-initialize the tzdata in every request?
> 
> Lin Yo-An <[email protected]> 於 2014年1月19日星期日寫道:
> 
>>
>>
>> Daniel Lowrey <[email protected] <javascript:_e({}, 'cvml',
>> '[email protected]');>> 於 2014年1月19日星期日寫道:
>>
>>>>> Hello,
>>>>>
>>>>> I am trying to store a zval object into the persistent list in zend VM.
>>>>> (Using EG(persistent_list) and zend_rscd_list_entry)
>>>>>
>>>>> Which works fine if I store/fetch the zval in the same request context.
>>>>>
>>>>> But it seems that zend engine cleans up the zval object after the
>>> request,
>>>>> when the next request comes, the fetched list entry points to a freed
>>> zval
>>>>> address and it makes php segmentationfault. I guess zval is allocated
>>> by
>>>>> emalloc, so I cant keep it cross requests?
>>>
>>>> For persistent alloc, you should use pemalloc() , which is just a
>>>> wrapper leading to libc's malloc.
>>>> If you use emalloc() , the Zend Memory Manager will free the storage
>>>> at the end of the request, thus leading to use-after-free crash if you
>>>> reuse your pointer on a next request.
>>>
>>> --- Disclaimer ---
>>> I'm passing this along; Joe is having technical difficulties and asked for
>>> help sending this to the list. I provide no warranties or refunds ;)
>>> ---
>>>
>>> All zvals passed into the engine must be allocated by the mm, you cannot
>>> pemalloc anything and pass it into the engine safely.
>>>
>>> You don't want to store a persistent zval, you want to store a persistent
>>> resource entry, which should be allocated with pemalloc(size, 1)
>>>
>>> The reason for this is when cleaning up, the engine has no means by which
>>> to tell if a zval has been pemalloc or emalloc'd, zval_ptr_dtor works the
>>> same for everything.
>>
>>
>>
>> Thank you so much! That is what i was guessing..  - ref cnt and pemalloc
>> does not work for persistent zval.
>>
>> And zend engine cleans up zvals at the end of request no matter the ref
>> cnt is?
>>
>> so zval is not persistent, then is HashTable persistent?
>>
>> It's because I need to store a zval object which has several properties.
>>   Is there a way to do make the object persistent? Or do i need to serialize
>> it just like apc?
>>
>>
>>
>>> Cheers
>>> Joe
>>>
>>
>>
>> --
>> Best Regards,
>>
>> Yo-An Lin
>>
>>
> 

A HashTable can be persistent:

 define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)

 HashTable *ht = pemalloc(sizeof(HashTable), 1);

 zend_hash_init(ht, 8, NULL, NULL, 1);

 When you write the table with zend_hash_update/add/insert the buckets
it creates are also persistently allocated.

 You don't need to serialize the data, or not necessarily anyway, a
hashtable can be copied bitwise - which in actual fact is what APC does
do. APC only serializes objects, normal arrays - HashTables are copied
bitwise, bucket by bucket.

 Of course, if the persistent table contains references to objects (as
in PHP objects in object_store or anything else emalloc'd) you will have
difficulties.

 Probably best to design the tables in such a way that they only need
ever store persistent data.

 Hope you're getting somewhere :)

Cheers
Joe


Thread (14 messages)

« previous php.internals (#71254) next »