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 internals+get-71254@lists.php.net 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 <cornelius.howl@gmail.com> 於 2014年1月19日星期日寫道: > >> >> >> Daniel Lowrey <rdlowrey@php.net <javascript:_e({}, 'cvml', >> 'rdlowrey@php.net');>> 於 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

« previous php.internals (#71254) next »