diff options
-rw-r--r-- | apcu-php82.patch | 948 | ||||
-rw-r--r-- | php-pecl-apcu.spec | 30 |
2 files changed, 965 insertions, 13 deletions
diff --git a/apcu-php82.patch b/apcu-php82.patch new file mode 100644 index 0000000..285bbc7 --- /dev/null +++ b/apcu-php82.patch @@ -0,0 +1,948 @@ +diff --git a/apc.h b/apc.h +index 4a011ee..a00f560 100644 +--- a/apc.h ++++ b/apc.h +@@ -76,13 +76,6 @@ PHP_APCU_API void apc_debug(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(print + /* apc_flip_hash flips keys and values for faster searching */ + PHP_APCU_API HashTable* apc_flip_hash(HashTable *hash); + +-#define apc_time() \ +- (APCG(use_request_time) \ +- ? (APCG(request_time) \ +- ? APCG(request_time) \ +- : (APCG(request_time) = (time_t) sapi_get_request_time())) \ +- : time(0)) +- + #if defined(__GNUC__) + # define APC_UNUSED __attribute__((unused)) + # define APC_USED __attribute__((used)) +@@ -131,7 +124,7 @@ PHP_APCU_API int _apc_register_serializer( + + /* {{{ apc_get_serializers + fetches the list of serializers */ +-PHP_APCU_API apc_serializer_t* apc_get_serializers(); /* }}} */ ++PHP_APCU_API apc_serializer_t* apc_get_serializers(void); /* }}} */ + + /* {{{ apc_find_serializer + finds a previously registered serializer by name */ +diff --git a/apc.php b/apc.php +index 76c7a6b..dd143b3 100644 +--- a/apc.php ++++ b/apc.php +@@ -228,48 +228,53 @@ if (isset($MYREQUEST['IMG'])) + + function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) { + $r=$diameter/2; +- $w=deg2rad((360+$start+($end-$start)/2)%360); +- ++ $w=deg2rad(round(360+$start+($end-$start)/2)%360); + + if (function_exists("imagefilledarc")) { + // exists only if GD 2.0.1 is available +- imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE); +- imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE); +- imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED); ++ imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, round($start), round($end), $color1, IMG_ARC_PIE); ++ imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, round($start), round($end), $color2, IMG_ARC_PIE); ++ imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, round($start), round($end), $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED); + } else { +- imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2); +- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); +- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); +- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); +- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); +- imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2); ++ imagearc($im, $centerX, $centerY, $diameter, $diameter, round($start), round($end), $color2); ++ imageline($im, $centerX, $centerY, $centerX + round(cos(deg2rad($start)) * $r), $centerY + round(sin(deg2rad($start)) * $r), $color2); ++ imageline($im, $centerX, $centerY, $centerX + round(cos(deg2rad($start+1)) * $r), $centerY + round(sin(deg2rad($start)) * $r), $color2); ++ imageline($im, $centerX, $centerY, $centerX + round(cos(deg2rad($end-1)) * $r), $centerY + round(sin(deg2rad($end)) * $r), $color2); ++ imageline($im, $centerX, $centerY, $centerX + round(cos(deg2rad($end)) * $r), $centerY + round(sin(deg2rad($end)) * $r), $color2); ++ imagefill($im,$centerX + round($r*cos($w)/2), $centerY + round($r*sin($w)/2), $color2); + } + if ($text) { + if ($placeindex>0) { +- imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1); ++ imageline($im,$centerX + round($r*cos($w)/2), $centerY + round($r*sin($w)/2),$diameter, $placeindex*12,$color1); + imagestring($im,4,$diameter, $placeindex*12,$text,$color1); + + } else { +- imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1); ++ imagestring($im,4,$centerX + round($r*cos($w)/2), $centerY + round($r*sin($w)/2),$text,$color1); + } + } + } + + function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) { + $r=$diameter/2; +- $w=deg2rad((360+$start+($end-$start)/2)%360); ++ $w=deg2rad((360+round($start)+round(($end-$start)/2))%360); + + if ($placeindex>0) { +- imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1); ++ imageline($im,$centerX + round($r*cos($w)/2), $centerY + round($r*sin($w)/2),$diameter, $placeindex*12,$color1); + imagestring($im,4,$diameter, $placeindex*12,$text,$color1); + + } else { +- imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1); ++ imagestring($im,4,$centerX + round($r*cos($w)/2), $centerY + round($r*sin($w)/2),$text,$color1); + } + } + + function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') { + global $col_black; ++ ++ $x = round($x); ++ $y = round($y); ++ $w = round($w); ++ $h = round($h); ++ + $x1=$x+$w-1; + $y1=$y+$h-1; + +@@ -285,7 +290,7 @@ if (isset($MYREQUEST['IMG'])) + $px=5; + $py=$placeindex*12+6; + imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2); +- imageline($im,$x,$y+$h/2,$px+90,$py,$color2); ++ imageline($im,$x,$y+round($h/2),$px+90,$py,$color2); + imagestring($im,2,$px,$py-6,$text,$color1); + + } else { +@@ -297,7 +302,7 @@ if (isset($MYREQUEST['IMG'])) + $py=($placeindex%15)*12+6; + } + imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2); +- imageline($im,$x+$w,$y+$h/2,$px,$py,$color2); ++ imageline($im,$x+$w,$y+round($h/2),$px,$py,$color2); + imagestring($im,2,$px+2,$py-6,$text,$color1); + } + } else { +@@ -707,7 +712,7 @@ input { + <body> + <div class="head"> + <h1 class="apc"> +- <div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APCu">APCu</a></span></div> ++ <div class="logo"><span class="logo"><a href="https://pecl.php.net/package/APCu">APCu</a></span></div> + <div class="nameinfo">User Cache</div> + </h1> + <div class="login"> +@@ -807,7 +812,7 @@ EOB; + + $j = 0; + foreach (ini_get_all('apcu') as $k => $v) { +- echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value']),"</td></tr>\n"; ++ echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value'] ?? ''),"</td></tr>\n"; + $j = 1 - $j; + } + +@@ -1094,9 +1099,9 @@ case OB_VERSION_CHECK: + EOB; + if (defined('PROXY')) { + $ctxt = stream_context_create( array( 'http' => array( 'proxy' => PROXY, 'request_fulluri' => true ) ) ); +- $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apcu.rss", false, $ctxt); ++ $rss = @file_get_contents("https://pecl.php.net/feeds/pkg_apcu.rss", false, $ctxt); + } else { +- $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apcu.rss"); ++ $rss = @file_get_contents("https://pecl.php.net/feeds/pkg_apcu.rss"); + } + if (!$rss) { + echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>'; +@@ -1110,8 +1115,8 @@ EOB; + $i = 3; + } else { + echo '<div class="failed">You are running an older version of APCu ('.$apcversion.'), +- newer version '.$match[1].' is available at <a href="http://pecl.php.net/package/APCu/'.$match[1].'"> +- http://pecl.php.net/package/APCu/'.$match[1].'</a> ++ newer version '.$match[1].' is available at <a href="https://pecl.php.net/package/APCu/'.$match[1].'"> ++ https://pecl.php.net/package/APCu/'.$match[1].'</a> + </div>'; + $i = -1; + } +@@ -1130,7 +1135,7 @@ EOB; + break; + } + $changes = $changelog[$j + 1]; +- echo "<b><a href=\"http://pecl.php.net/package/APCu/$ver\">".htmlspecialchars($v, ENT_QUOTES, 'UTF-8')."</a></b><br><blockquote>"; ++ echo "<b><a href=\"https://pecl.php.net/package/APCu/$ver\">".htmlspecialchars($v, ENT_QUOTES, 'UTF-8')."</a></b><br><blockquote>"; + echo nl2br(htmlspecialchars($changes, ENT_QUOTES, 'UTF-8'))."</blockquote>"; + } + echo '</td></tr>'; +diff --git a/apc_cache.c b/apc_cache.c +index 480dd00..e5333f3 100644 +--- a/apc_cache.c ++++ b/apc_cache.c +@@ -32,6 +32,7 @@ + #include "apc_sma.h" + #include "apc_globals.h" + #include "apc_strings.h" ++#include "apc_time.h" + #include "php_scandir.h" + #include "SAPI.h" + #include "TSRM.h" +@@ -115,7 +116,7 @@ static inline void free_entry(apc_cache_t *cache, apc_cache_entry_t *entry) { + /* {{{ apc_cache_hash_slot + Note: These calculations can and should be done outside of a lock */ + static inline void apc_cache_hash_slot( +- apc_cache_t* cache, zend_string *key, zend_ulong* hash, zend_ulong* slot) { ++ apc_cache_t* cache, zend_string *key, zend_ulong* hash, size_t* slot) { + *hash = ZSTR_HASH(key); + *slot = *hash % cache->nslots; + } /* }}} */ +@@ -272,7 +273,7 @@ PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS) + PHP_APCU_API apc_cache_t* apc_cache_create(apc_sma_t* sma, apc_serializer_t* serializer, zend_long size_hint, zend_long gc_ttl, zend_long ttl, zend_long smart, zend_bool defend) { + apc_cache_t* cache; + zend_long cache_size; +- zend_long nslots; ++ size_t nslots; + + /* calculate number of slots */ + nslots = make_prime(size_hint > 0 ? size_hint : 2000); +@@ -332,7 +333,8 @@ static inline zend_bool apc_cache_wlocked_insert( + /* make the insertion */ + { + apc_cache_entry_t **entry; +- zend_ulong h, s; ++ zend_ulong h; ++ size_t s; + + /* calculate hash and entry */ + apc_cache_hash_slot(cache, key, &h, &s); +@@ -413,7 +415,8 @@ static inline zend_bool apc_cache_store_internal( + static inline apc_cache_entry_t *apc_cache_rlocked_find_nostat( + apc_cache_t *cache, zend_string *key, time_t t) { + apc_cache_entry_t *entry; +- zend_ulong h, s; ++ zend_ulong h; ++ size_t s; + + /* calculate hash and slot */ + apc_cache_hash_slot(cache, key, &h, &s); +@@ -440,7 +443,8 @@ static inline apc_cache_entry_t *apc_cache_rlocked_find_nostat( + static inline apc_cache_entry_t *apc_cache_rlocked_find( + apc_cache_t *cache, zend_string *key, time_t t) { + apc_cache_entry_t *entry; +- zend_ulong h, s; ++ zend_ulong h; ++ size_t s; + + /* calculate hash and slot */ + apc_cache_hash_slot(cache, key, &h, &s); +@@ -670,14 +674,10 @@ static void apc_cache_wlocked_real_expunge(apc_cache_t* cache) { + cache->header->nexpunges++; + + /* expunge */ +- { +- zend_ulong i; +- +- for (i = 0; i < cache->nslots; i++) { +- apc_cache_entry_t **entry = &cache->slots[i]; +- while (*entry) { +- apc_cache_wlocked_remove_entry(cache, entry); +- } ++ for (size_t i = 0; i < cache->nslots; i++) { ++ apc_cache_entry_t **entry = &cache->slots[i]; ++ while (*entry) { ++ apc_cache_wlocked_remove_entry(cache, entry); + } + } + +@@ -754,10 +754,8 @@ PHP_APCU_API void apc_cache_default_expunge(apc_cache_t* cache, size_t size) + } else { + /* check that expunge is necessary */ + if (available < suitable) { +- zend_ulong i; +- + /* look for junk */ +- for (i = 0; i < cache->nslots; i++) { ++ for (size_t i = 0; i < cache->nslots; i++) { + apc_cache_entry_t **entry = &cache->slots[i]; + while (*entry) { + if (apc_cache_entry_expired(cache, *entry, t)) { +@@ -959,7 +957,8 @@ retry_update: + PHP_APCU_API zend_bool apc_cache_delete(apc_cache_t *cache, zend_string *key) + { + apc_cache_entry_t **entry; +- zend_ulong h, s; ++ zend_ulong h; ++ size_t s; + + if (!cache) { + return 0; +@@ -1061,7 +1060,7 @@ PHP_APCU_API zend_bool apc_cache_info(zval *info, apc_cache_t *cache, zend_bool + zval gc; + zval slots; + apc_cache_entry_t *p; +- zend_ulong i, j; ++ zend_ulong j; + + ZVAL_NULL(info); + if (!cache) { +@@ -1095,7 +1094,7 @@ PHP_APCU_API zend_bool apc_cache_info(zval *info, apc_cache_t *cache, zend_bool + array_init(&list); + array_init(&slots); + +- for (i = 0; i < cache->nslots; i++) { ++ for (size_t i = 0; i < cache->nslots; i++) { + p = cache->slots[i]; + j = 0; + for (; p != NULL; p = p->next) { +@@ -1132,7 +1131,8 @@ PHP_APCU_API zend_bool apc_cache_info(zval *info, apc_cache_t *cache, zend_bool + fetches information about the key provided + */ + PHP_APCU_API void apc_cache_stat(apc_cache_t *cache, zend_string *key, zval *stat) { +- zend_ulong h, s; ++ zend_ulong h; ++ size_t s; + + ZVAL_NULL(stat); + if (!cache) { +diff --git a/apc_cache.h b/apc_cache.h +index c05e091..e987a54 100644 +--- a/apc_cache.h ++++ b/apc_cache.h +@@ -86,7 +86,7 @@ typedef struct _apc_cache_t { + apc_cache_entry_t** slots; /* array of cache slots (stored in SHM) */ + apc_sma_t* sma; /* shared memory allocator */ + apc_serializer_t* serializer; /* serializer */ +- zend_long nslots; /* number of slots in cache */ ++ size_t nslots; /* number of slots in cache */ + zend_long gc_ttl; /* maximum time on GC list for a entry */ + zend_long ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */ + zend_long smart; /* smart parameter for gc */ +diff --git a/apc_iterator.c b/apc_iterator.c +index a268718..23f4334 100644 +--- a/apc_iterator.c ++++ b/apc_iterator.c +@@ -21,6 +21,7 @@ + #include "apc_iterator.h" + #include "apc_cache.h" + #include "apc_strings.h" ++#include "apc_time.h" + #if PHP_VERSION_ID >= 80000 + # include "apc_iterator_arginfo.h" + #else +@@ -209,8 +210,8 @@ static int apc_iterator_check_expiry(apc_cache_t* cache, apc_cache_entry_t *entr + /* }}} */ + + /* {{{ apc_iterator_fetch_active */ +-static int apc_iterator_fetch_active(apc_iterator_t *iterator) { +- int count = 0; ++static size_t apc_iterator_fetch_active(apc_iterator_t *iterator) { ++ size_t count = 0; + apc_iterator_item_t *item; + time_t t = apc_time(); + +@@ -249,8 +250,8 @@ static int apc_iterator_fetch_active(apc_iterator_t *iterator) { + /* }}} */ + + /* {{{ apc_iterator_fetch_deleted */ +-static int apc_iterator_fetch_deleted(apc_iterator_t *iterator) { +- int count = 0; ++static size_t apc_iterator_fetch_deleted(apc_iterator_t *iterator) { ++ size_t count = 0; + apc_iterator_item_t *item; + + if (!apc_cache_rlock(apc_user_cache)) { +@@ -287,14 +288,13 @@ static int apc_iterator_fetch_deleted(apc_iterator_t *iterator) { + /* {{{ apc_iterator_totals */ + static void apc_iterator_totals(apc_iterator_t *iterator) { + time_t t = apc_time(); +- int i; + + if (!apc_cache_rlock(apc_user_cache)) { + return; + } + + php_apc_try { +- for (i=0; i < apc_user_cache->nslots; i++) { ++ for (size_t i=0; i < apc_user_cache->nslots; i++) { + apc_cache_entry_t *entry = apc_user_cache->slots[i]; + while (entry) { + if (apc_iterator_check_expiry(apc_user_cache, entry, t)) { +@@ -314,18 +314,13 @@ static void apc_iterator_totals(apc_iterator_t *iterator) { + } + /* }}} */ + +-void apc_iterator_obj_init(apc_iterator_t *iterator, zval *search, zend_long format, zend_long chunk_size, zend_long list) ++void apc_iterator_obj_init(apc_iterator_t *iterator, zval *search, zend_long format, size_t chunk_size, zend_long list) + { + if (!APCG(enabled)) { + zend_throw_error(NULL, "APC must be enabled to use APCUIterator"); + return; + } + +- if (chunk_size < 0) { +- apc_error("APCUIterator chunk size must be 0 or greater"); +- return; +- } +- + if (format > APC_ITER_ALL) { + apc_error("APCUIterator format is invalid"); + return; +@@ -383,6 +378,11 @@ PHP_METHOD(APCUIterator, __construct) { + return; + } + ++ if (chunk_size < 0) { ++ apc_error("APCUIterator chunk size must be 0 or greater"); ++ return; ++ } ++ + apc_iterator_obj_init(iterator, search, format, chunk_size, list); + } + +diff --git a/apc_iterator.h b/apc_iterator.h +index d9537b4..9feda38 100644 +--- a/apc_iterator.h ++++ b/apc_iterator.h +@@ -50,10 +50,10 @@ + typedef struct _apc_iterator_t { + short int initialized; /* sanity check in case __construct failed */ + zend_long format; /* format bitmask of the return values ie: key, value, info */ +- int (*fetch)(struct _apc_iterator_t *iterator); ++ size_t (*fetch)(struct _apc_iterator_t *iterator); + /* fetch callback to fetch items from cache slots or lists */ +- zend_long slot_idx; /* index to the slot array or linked list */ +- zend_long chunk_size; /* number of entries to pull down per fetch */ ++ size_t slot_idx; /* index to the slot array or linked list */ ++ size_t chunk_size; /* number of entries to pull down per fetch */ + apc_stack_t *stack; /* stack of entries pulled from cache */ + int stack_idx; /* index into the current stack */ + pcre_cache_entry *pce; /* regex filter on entry identifiers */ +@@ -85,7 +85,7 @@ PHP_APCU_API void apc_iterator_obj_init( + apc_iterator_t *iterator, + zval *search, + zend_long format, +- zend_long chunk_size, ++ size_t chunk_size, + zend_long list); + PHP_APCU_API zend_class_entry* apc_iterator_get_ce(void); + PHP_APCU_API int apc_iterator_init(int module_number); +diff --git a/apc_lock.h b/apc_lock.h +index 5b96755..7288cb9 100644 +--- a/apc_lock.h ++++ b/apc_lock.h +@@ -72,8 +72,8 @@ typedef apc_windows_cs_rwlock_t apc_lock_t; + apc_lock_cleanup destroys those attributes + This saves us from having to create and destroy attributes for + every lock we use at runtime */ +-PHP_APCU_API zend_bool apc_lock_init(); +-PHP_APCU_API void apc_lock_cleanup(); ++PHP_APCU_API zend_bool apc_lock_init(void); ++PHP_APCU_API void apc_lock_cleanup(void); + /* + The following functions should be self explanitory: + */ +diff --git a/apc_mmap.c b/apc_mmap.c +index b56658a..9337d45 100644 +--- a/apc_mmap.c ++++ b/apc_mmap.c +@@ -111,6 +111,12 @@ apc_segment_t apc_mmap(char *file_mask, size_t size) + zend_error_noreturn(E_CORE_ERROR, "apc_mmap: Failed to mmap %zu bytes. Is your apc.shm_size too large?", size); + } + ++#ifdef MADV_HUGEPAGE ++ /* enable transparent huge pages to reduce TLB misses (Linux ++ only) */ ++ madvise(segment.shmaddr, size, MADV_HUGEPAGE); ++#endif ++ + if (fd != -1) close(fd); + + return segment; +diff --git a/apc_mutex.h b/apc_mutex.h +index 1f3ee87..45983ea 100644 +--- a/apc_mutex.h ++++ b/apc_mutex.h +@@ -27,8 +27,8 @@ + + typedef pthread_mutex_t apc_mutex_t; + +-PHP_APCU_API zend_bool apc_mutex_init(); +-PHP_APCU_API void apc_mutex_cleanup(); ++PHP_APCU_API zend_bool apc_mutex_init(void); ++PHP_APCU_API void apc_mutex_cleanup(void); + PHP_APCU_API zend_bool apc_mutex_create(apc_mutex_t *lock); + PHP_APCU_API zend_bool apc_mutex_lock(apc_mutex_t *lock); + PHP_APCU_API zend_bool apc_mutex_unlock(apc_mutex_t *lock); +diff --git a/apc_persist.c b/apc_persist.c +index cc21f57..0f8ac53 100644 +--- a/apc_persist.c ++++ b/apc_persist.c +@@ -127,26 +127,39 @@ static zend_bool apc_persist_calc_ht(apc_persist_context_t *ctxt, const HashTabl + + /* TODO Too sparse hashtables could be compacted here */ + ADD_SIZE(HT_USED_SIZE(ht)); +- for (idx = 0; idx < ht->nNumUsed; idx++) { +- Bucket *p = ht->arData + idx; +- if (Z_TYPE(p->val) == IS_UNDEF) continue; +- +- /* This can only happen if $GLOBALS is placed in the cache. +- * Don't bother with this edge-case, fall back to serialization. */ +- if (Z_TYPE(p->val) == IS_INDIRECT) { +- ctxt->use_serialization = 1; +- return 0; ++#if PHP_VERSION_ID >= 80200 ++ if (HT_IS_PACKED(ht)) { ++ for (idx = 0; idx < ht->nNumUsed; idx++) { ++ zval *val = ht->arPacked + idx; ++ ZEND_ASSERT(Z_TYPE_P(val) != IS_INDIRECT && "INDIRECT in packed array?"); ++ if (!apc_persist_calc_zval(ctxt, val)) { ++ return 0; ++ } + } ++ } else ++#endif ++ { ++ for (idx = 0; idx < ht->nNumUsed; idx++) { ++ Bucket *p = ht->arData + idx; ++ if (Z_TYPE(p->val) == IS_UNDEF) continue; ++ ++ /* This can only happen if $GLOBALS is placed in the cache. ++ * Don't bother with this edge-case, fall back to serialization. */ ++ if (Z_TYPE(p->val) == IS_INDIRECT) { ++ ctxt->use_serialization = 1; ++ return 0; ++ } + +- /* TODO These strings can be reused +- if (p->key && !apc_persist_calc_is_handled(ctxt, (zend_refcounted *) p->key)) { +- ADD_SIZE_STR(ZSTR_LEN(p->key)); +- }*/ +- if (p->key) { +- ADD_SIZE_STR(ZSTR_LEN(p->key)); +- } +- if (!apc_persist_calc_zval(ctxt, &p->val)) { +- return 0; ++ /* TODO These strings can be reused ++ if (p->key && !apc_persist_calc_is_handled(ctxt, (zend_refcounted *) p->key)) { ++ ADD_SIZE_STR(ZSTR_LEN(p->key)); ++ }*/ ++ if (p->key) { ++ ADD_SIZE_STR(ZSTR_LEN(p->key)); ++ } ++ if (!apc_persist_calc_zval(ctxt, &p->val)) { ++ return 0; ++ } + } + } + +@@ -322,22 +335,42 @@ static zend_array *apc_persist_copy_ht(apc_persist_context_t *ctxt, const HashTa + ht->nNextFreeElement = 0; + ht->nInternalPointer = HT_INVALID_IDX; + HT_SET_DATA_ADDR(ht, COPY(HT_GET_DATA_ADDR(ht), HT_USED_SIZE(ht))); +- for (idx = 0; idx < ht->nNumUsed; idx++) { +- Bucket *p = ht->arData + idx; +- if (Z_TYPE(p->val) == IS_UNDEF) continue; ++#if PHP_VERSION_ID >= 80200 ++ if (HT_IS_PACKED(ht)) { ++ for (idx = 0; idx < ht->nNumUsed; idx++) { ++ zval *val = ht->arPacked + idx; ++ if (Z_TYPE_P(val) == IS_UNDEF) continue; ++ ++ if (ht->nInternalPointer == HT_INVALID_IDX) { ++ ht->nInternalPointer = idx; ++ } + +- if (ht->nInternalPointer == HT_INVALID_IDX) { +- ht->nInternalPointer = idx; +- } ++ if ((zend_long) idx >= (zend_long) ht->nNextFreeElement) { ++ ht->nNextFreeElement = idx + 1; ++ } + +- if (p->key) { +- p->key = apc_persist_copy_zstr_no_add(ctxt, p->key); +- ht->u.flags &= ~HASH_FLAG_STATIC_KEYS; +- } else if ((zend_long) p->h >= (zend_long) ht->nNextFreeElement) { +- ht->nNextFreeElement = p->h + 1; ++ apc_persist_copy_zval(ctxt, val); + } ++ } else ++#endif ++ { ++ for (idx = 0; idx < ht->nNumUsed; idx++) { ++ Bucket *p = ht->arData + idx; ++ if (Z_TYPE(p->val) == IS_UNDEF) continue; ++ ++ if (ht->nInternalPointer == HT_INVALID_IDX) { ++ ht->nInternalPointer = idx; ++ } ++ ++ if (p->key) { ++ p->key = apc_persist_copy_zstr_no_add(ctxt, p->key); ++ ht->u.flags &= ~HASH_FLAG_STATIC_KEYS; ++ } else if ((zend_long) p->h >= (zend_long) ht->nNextFreeElement) { ++ ht->nNextFreeElement = p->h + 1; ++ } + +- apc_persist_copy_zval(ctxt, &p->val); ++ apc_persist_copy_zval(ctxt, &p->val); ++ } + } + + return ht; +@@ -541,6 +574,15 @@ static zend_array *apc_unpersist_ht( + HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht))); + memcpy(HT_GET_DATA_ADDR(ht), HT_GET_DATA_ADDR(orig_ht), HT_HASH_SIZE(ht->nTableMask)); + ++#if PHP_VERSION_ID >= 80200 ++ if (HT_IS_PACKED(ht)) { ++ zval *p = ht->arPacked, *q = orig_ht->arPacked, *p_end = p + ht->nNumUsed; ++ for (; p < p_end; p++, q++) { ++ *p = *q; ++ apc_unpersist_zval(ctxt, p); ++ } ++ } else ++#endif + if (ht->u.flags & HASH_FLAG_STATIC_KEYS) { + Bucket *p = ht->arData, *q = orig_ht->arData, *p_end = p + ht->nNumUsed; + for (; p < p_end; p++, q++) { +diff --git a/apc_signal.h b/apc_signal.h +index aeace18..1f5f73f 100644 +--- a/apc_signal.h ++++ b/apc_signal.h +@@ -34,8 +34,8 @@ typedef struct apc_signal_info_t { + apc_signal_entry_t **prev; /* Previous signal handlers */ + } apc_signal_info_t; + +-void apc_set_signals(); +-void apc_shutdown_signals(); ++void apc_set_signals(void); ++void apc_shutdown_signals(void); + + #endif + +diff --git a/apc_sma.c b/apc_sma.c +index 3150d92..51a3198 100644 +--- a/apc_sma.c ++++ b/apc_sma.c +@@ -169,13 +169,13 @@ static APC_HOTSPOT size_t sma_allocate(sma_header_t *header, size_t size, size_t + shmaddr = header; + + if (header->avail < realsize) { +- return -1; ++ return SIZE_MAX; + } + + cur = find_block(header, realsize); + if (!cur) { + /* No suitable block found */ +- return -1; ++ return SIZE_MAX; + } + + if (cur->size == realsize || (cur->size > realsize && cur->size < (realsize + (MINBLOCKSIZE + fragment)))) { +@@ -414,7 +414,7 @@ restart: + + off = sma_allocate(SMA_HDR(sma, last), n, fragment, allocated); + +- if (off != -1) { ++ if (off != SIZE_MAX) { + void* p = (void *)(SMA_ADDR(sma, last) + off); + SMA_UNLOCK(sma, last); + #ifdef VALGRIND_MALLOCLIKE_BLOCK +@@ -435,7 +435,7 @@ restart: + } + + off = sma_allocate(SMA_HDR(sma, i), n, fragment, allocated); +- if (off != -1) { ++ if (off != SIZE_MAX) { + void* p = (void *)(SMA_ADDR(sma, i) + off); + sma->last = i; + SMA_UNLOCK(sma, i); +diff --git a/apc_stack.c b/apc_stack.c +index a0b6bfa..22d81b9 100644 +--- a/apc_stack.c ++++ b/apc_stack.c +@@ -30,11 +30,11 @@ + + struct apc_stack_t { + void** data; +- int capacity; +- int size; ++ size_t capacity; ++ size_t size; + }; + +-apc_stack_t* apc_stack_create(int size_hint) ++apc_stack_t* apc_stack_create(size_t size_hint) + { + apc_stack_t* stack = emalloc(sizeof(apc_stack_t)); + +@@ -81,7 +81,7 @@ void* apc_stack_top(apc_stack_t* stack) + return stack->data[stack->size-1]; + } + +-void* apc_stack_get(apc_stack_t* stack, int n) ++void* apc_stack_get(apc_stack_t* stack, size_t n) + { + assert(stack != NULL && stack->size > n); + return stack->data[n]; +diff --git a/apc_stack.h b/apc_stack.h +index 152136a..20fdd2a 100644 +--- a/apc_stack.h ++++ b/apc_stack.h +@@ -34,13 +34,13 @@ + #define T apc_stack_t* + typedef struct apc_stack_t apc_stack_t; /* opaque stack type */ + +-extern T apc_stack_create(int size_hint); ++extern T apc_stack_create(size_t size_hint); + extern void apc_stack_destroy(T stack); + extern void apc_stack_clear(T stack); + extern void apc_stack_push(T stack, void* item); + extern void* apc_stack_pop(T stack); + extern void* apc_stack_top(T stack); +-extern void* apc_stack_get(T stack, int n); ++extern void* apc_stack_get(T stack, size_t n); + extern int apc_stack_size(T stack); + + #undef T +diff --git a/apc_time.c b/apc_time.c +new file mode 100644 +index 0000000..2866929 +--- /dev/null ++++ b/apc_time.c +@@ -0,0 +1,54 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | APC | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2006-2011 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.01 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_01.txt | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ ++ This software was contributed to PHP by Community Connect Inc. in 2002 ++ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1. ++ Future revisions and derivatives of this source code must acknowledge ++ Community Connect Inc. as the original contributor of this module by ++ leaving this note intact in the source code. ++ ++ All other licensing and usage conditions are those of the PHP Group. ++ ++ */ ++ ++#include "apc_time.h" ++#include "apc_globals.h" ++#include "SAPI.h" ++ ++time_t apc_time(void) ++{ ++ if (APCG(use_request_time)) { ++ if (!APCG(request_time)) ++ APCG(request_time) = (time_t) sapi_get_request_time(); ++ return APCG(request_time); ++ } else { ++#ifdef HAVE_CLOCK_GETTIME ++ struct timespec ts; ++ clock_gettime(CLOCK_MONOTONIC, &ts); ++ return ts.tv_sec; ++#else ++ return time(0); ++#endif ++ } ++} ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker ++ * vim<600: noexpandtab sw=4 ts=4 sts=4 ++ */ +diff --git a/apc_time.h b/apc_time.h +new file mode 100644 +index 0000000..3e26403 +--- /dev/null ++++ b/apc_time.h +@@ -0,0 +1,42 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | APC | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2006-2011 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.01 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_01.txt | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ ++ This software was contributed to PHP by Community Connect Inc. in 2002 ++ and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1. ++ Future revisions and derivatives of this source code must acknowledge ++ Community Connect Inc. as the original contributor of this module by ++ leaving this note intact in the source code. ++ ++ All other licensing and usage conditions are those of the PHP Group. ++ ++ */ ++ ++#ifndef APC_TIME_H ++#define APC_TIME_H ++ ++#include <time.h> ++ ++time_t apc_time(void); ++ ++#endif ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker ++ * vim<600: noexpandtab sw=4 ts=4 sts=4 ++ */ +diff --git a/config.m4 b/config.m4 +index 9d320ec..d991186 100644 +--- a/config.m4 ++++ b/config.m4 +@@ -5,8 +5,8 @@ AC_MSG_CHECKING(if APCu should be allowed to use rwlocks) + AC_ARG_ENABLE(apcu-rwlocks, + [ --disable-apcu-rwlocks Disable rwlocks in APCu], + [ +- PHP_APCU_RWLOCKS=no +- AC_MSG_RESULT(no) ++ PHP_APCU_RWLOCKS=$enableval ++ AC_MSG_RESULT($enableval) + ], + [ + PHP_APCU_RWLOCKS=yes +@@ -200,6 +200,7 @@ if test "$PHP_APCU" != "no"; then + fi + fi + ++ AC_CHECK_FUNCS(clock_gettime) + AC_CHECK_FUNCS(sigaction) + AC_CACHE_CHECK(for union semun, php_cv_semun, + [ +@@ -230,6 +231,10 @@ if test "$PHP_APCU" != "no"; then + [AC_DEFINE([HAVE_VALGRIND_MEMCHECK_H],1, [enable valgrind memchecks])]) + ]) + ++ for i in -Wall -Wextra -Wno-unused-parameter; do ++ AX_CHECK_COMPILE_FLAG([$i], [APCU_CFLAGS="$APCU_CFLAGS $i"]) ++ done ++ + apc_sources="apc.c apc_lock.c apc_mutex.c php_apc.c \ + apc_cache.c \ + apc_mmap.c \ +@@ -237,6 +242,7 @@ if test "$PHP_APCU" != "no"; then + apc_sma.c \ + apc_stack.c \ + apc_signal.c \ ++ apc_time.c \ + apc_iterator.c \ + apc_persist.c" + +diff --git a/php_apc.c b/php_apc.c +index 27139cc..211dd33 100644 +--- a/php_apc.c ++++ b/php_apc.c +@@ -36,6 +36,7 @@ + #include "apc_lock.h" + #include "apc_mutex.h" + #include "apc_strings.h" ++#include "apc_time.h" + #include "php_globals.h" + #include "php_ini.h" + #include "ext/standard/info.h" +@@ -92,13 +93,14 @@ static void php_apc_init_globals(zend_apcu_globals* apcu_globals) + + static PHP_INI_MH(OnUpdateShmSegments) /* {{{ */ + { ++ zend_long shm_segments = ZEND_STRTOL(new_value->val, NULL, 10); + #if APC_MMAP +- if (zend_atoi(new_value->val, new_value->len)!=1) { ++ if (shm_segments != 1) { + php_error_docref(NULL, E_WARNING, "apc.shm_segments setting ignored in MMAP mode"); + } + APCG(shm_segments) = 1; + #else +- APCG(shm_segments) = zend_atoi(new_value->val, new_value->len); ++ APCG(shm_segments) = shm_segments; + #endif + return SUCCESS; + } +@@ -106,7 +108,11 @@ static PHP_INI_MH(OnUpdateShmSegments) /* {{{ */ + + static PHP_INI_MH(OnUpdateShmSize) /* {{{ */ + { ++#if PHP_VERSION_ID >= 80200 ++ zend_long s = zend_ini_parse_quantity_warn(new_value, entry->name); ++#else + zend_long s = zend_atol(new_value->val, new_value->len); ++#endif + + if (s <= 0) { + return FAILURE; +diff --git a/tests/apc_002.phpt b/tests/apc_002.phpt +index a395707..37e0927 100644 +--- a/tests/apc_002.phpt ++++ b/tests/apc_002.phpt +@@ -8,6 +8,7 @@ apc.enable_cli=1 + --FILE-- + <?php + ++#[AllowDynamicProperties] + class foo { } + $foo = new foo; + var_dump($foo); +diff --git a/tests/apc_003b.phpt b/tests/apc_003b.phpt +index d7a18cc..08fb62c 100644 +--- a/tests/apc_003b.phpt ++++ b/tests/apc_003b.phpt +@@ -11,6 +11,7 @@ apc.enable_cli=1 + --FILE-- + <?php + ++#[AllowDynamicProperties] + class foo { } + $foo = new foo; + var_dump($foo); +@@ -21,6 +22,7 @@ var_dump($bar); + $bar->a = true; + var_dump($bar); + ++#[AllowDynamicProperties] + class bar extends foo + { + public $pub = 'bar'; +diff --git a/tests/apc_entry_002.phpt b/tests/apc_entry_002.phpt +index c207d45..61f833a 100644 +--- a/tests/apc_entry_002.phpt ++++ b/tests/apc_entry_002.phpt +@@ -15,6 +15,6 @@ $value = apcu_entry("test", function($key){ + Fatal error: Uncaught Exception: test in %s:3 + Stack trace: + #0 [internal function]: {closure}('test') +-#1 %s(4): apcu_entry('test', Object(Closure)) ++#1 %s(%d): apcu_entry('test', Object(Closure)) + #2 {main} + thrown in %s on line 3 +diff --git a/tests/bug63224.phpt b/tests/bug63224.phpt +index d711f8f..92ea3c9 100644 +--- a/tests/bug63224.phpt ++++ b/tests/bug63224.phpt +@@ -57,6 +57,7 @@ $args = array( + 'apc.enabled=1', + 'apc.cache_by_default=1', + 'apc.enable_cli=1', ++ 'session.gc_probability=0', + ); + + server_start($file, $args); diff --git a/php-pecl-apcu.spec b/php-pecl-apcu.spec index f914506..cad6462 100644 --- a/php-pecl-apcu.spec +++ b/php-pecl-apcu.spec @@ -3,7 +3,7 @@ # # Fedora spec file for php-pecl-apcu # -# Copyright (c) 2013-2021 Remi Collet +# Copyright (c) 2013-2022 Remi Collet # License: CC-BY-SA # http://creativecommons.org/licenses/by-sa/4.0/ # @@ -14,7 +14,6 @@ %undefine _strict_symbol_defs_build %if 0%{?scl:1} -%global sub_prefix %{scl_prefix} %scl_package php-pecl-apcu %endif @@ -27,7 +26,7 @@ %global with_zts 0%{!?_without_zts:%{?__ztsphp:1}} %global ini_name 40-%{pecl_name}.ini -Name: %{?sub_prefix}php-pecl-apcu +Name: %{?scl_prefix}php-pecl-apcu Summary: APC User Cache Version: 5.1.21 License: PHP @@ -36,13 +35,16 @@ URL: https://pecl.php.net/package/APCu Release: 0.9.%{gh_date}git%{gh_short}%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}} Source0: https://github.com/%{gh_owner}/%{gh_project}/archive/%{gh_commit}/%{pecl_name}-%{version}-%{gh_short}.tar.gz %else -Release: 1%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}} +Release: 3%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}} Source0: https://pecl.php.net/get/%{pecl_name}-%{version}.tgz %endif Source1: %{pecl_name}-5.1.19.ini Source2: %{pecl_name}-panel.conf Source3: %{pecl_name}.conf.php +# git diff v5.1.21 -- *.c *.h *.php tests +Patch0: %{pecl_name}-php82.patch + BuildRequires: make BuildRequires: %{?dtsprefix}gcc BuildRequires: %{?scl_prefix}php-devel >= 7.0 @@ -57,10 +59,6 @@ Provides: %{?scl_prefix}php-apcu = %{version} Provides: %{?scl_prefix}php-apcu%{?_isa} = %{version} Provides: %{?scl_prefix}php-pecl(apcu) = %{version} Provides: %{?scl_prefix}php-pecl(apcu)%{?_isa} = %{version} -%if "%{?scl_prefix}" != "%{?sub_prefix}" -Provides: %{?scl_prefix}php-pecl-apcu = %{version}-%{release} -Provides: %{?scl_prefix}php-pecl-apcu%{?_isa} = %{version}-%{release} -%endif %if "%{?packager}" == "Remi Collet" && 0%{!?scl:1} && 0%{?rhel} # Other third party repo stuff @@ -104,7 +102,7 @@ APCu is userland caching: APC stripped of opcode caching. APCu only supports userland caching of variables. -The %{?sub_prefix}php-pecl-apcu-bc package provides a drop +The %{?scl_prefix}php-pecl-apcu-bc package provides a drop in replacement for APC. Package built for PHP %(%{__php} -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')%{?scl: as Software Collection (%{scl} by %{?scl_vendor}%{!?scl_vendor:rh})}. @@ -118,10 +116,6 @@ Requires: %{?scl_prefix}php-devel%{?_isa} Obsoletes: %{?scl_prefix}php-pecl-apc-devel < 4 Provides: %{?scl_prefix}php-pecl-apc-devel = %{version}-%{release} Provides: %{?scl_prefix}php-pecl-apc-devel%{?_isa} = %{version}-%{release} -%if "%{?scl_prefix}" != "%{?sub_prefix}" -Provides: %{?scl_prefix}php-pecl-apcu-devel = %{version}-%{release} -Provides: %{?scl_prefix}php-pecl-apcu-devel%{?_isa} = %{version}-%{release} -%endif %description devel These are the files needed to compile programs using APCu. @@ -157,6 +151,10 @@ mv %{pecl_name}-%{version} NTS %{?_licensedir:sed -e '/LICENSE/s/role="doc"/role="src"/' -i package.xml} cd NTS +%if "%{php_version}" > "8.2" +%patch0 -p1 -b .php82 +%endif + # Sanity check, really often broken extver=$(sed -n '/#define PHP_APCU_VERSION/{s/.* "//;s/".*$//;p}' php_apc.h) if test "x${extver}" != "x%{version}%{?prever}%{?gh_date:-dev}"; then @@ -322,6 +320,12 @@ fi %changelog +* Thu Sep 1 2022 Remi Collet <remi@remirepo.net> - 5.1.21-3 +- rebuild for PHP 8.2.0RC1 + +* Thu Aug 18 2022 Remi Collet <remi@remirepo.net> - 5.1.21-2 +- add upstream patches for PHP 8.2 + * Thu Oct 7 2021 Remi Collet <remi@remirepo.net> - 5.1.21-1 - update to 5.1.21 |