From 4314aad7e505c45d1fb7cdd01c9a6e1d766d29fc Mon Sep 17 00:00:00 2001
From: Joe Watkins <krakjoe@php.net>
Date: Thu, 29 Sep 2016 13:40:53 +0100
Subject: [PATCH] more on #19

---
 apc_cache.c    | 130 ++++++++++++++++++++++++++-----------------------
 apc_iterator.c |  97 ++++++++++++++++++++----------------
 2 files changed, 122 insertions(+), 105 deletions(-)

diff --git a/apc_cache.c b/apc_cache.c
index b32607e5..4ae57935 100644
--- a/apc_cache.c
+++ b/apc_cache.c
@@ -747,7 +747,9 @@ PHP_APCU_API zend_bool apc_cache_insert(apc_cache_t* cache,
 
 	/* lock header */
 	APC_LOCK(cache->header);
-	
+
+	/* @TODO(krakjoe) this code using goto means we can't use zend_try here */
+
 	/* process deleted list  */
     apc_cache_gc(cache TSRMLS_CC);
 
@@ -1006,47 +1008,49 @@ PHP_APCU_API zend_bool apc_cache_update(apc_cache_t* cache, char *strkey, zend_u
 	/* lock header */
 	APC_LOCK(cache->header);
 
-	/* find head */
-    slot = &cache->slots[s];
+	zend_try {
+		/* find head */
+		slot = &cache->slots[s];
 
-    while (*slot) {
-		/* check for a match by hash and identifier */
-        if ((h == (*slot)->key.h) &&
-            !memcmp((*slot)->key.str, strkey, keylen)) {
-			/* attempt to perform update */
-            switch(Z_TYPE_P((*slot)->value->val) & ~IS_CONSTANT_TYPE_MASK) {
-                case IS_ARRAY:
-                case IS_OBJECT:
-                {
-                    if(cache->serializer) {
-                        retval = 0;
-                        break;
-                    } else {
-                        /* fall through */
-                    }
-                }
-                /* fall through */
-                default:
-                {
-					/* executing update */
-                    retval = updater(
-						cache, (*slot)->value, data);
-
-					/* set modified time */
-                    (*slot)->key.mtime = apc_time();
-                }
-                break;
-            }
-			/* unlock header */
-			APC_UNLOCK(cache->header);
+		while (*slot) {
+			/* check for a match by hash and identifier */
+		    if ((h == (*slot)->key.h) &&
+		        !memcmp((*slot)->key.str, strkey, keylen)) {
+				/* attempt to perform update */
+		        switch(Z_TYPE_P((*slot)->value->val) & ~IS_CONSTANT_TYPE_MASK) {
+		            case IS_ARRAY:
+		            case IS_OBJECT:
+		            {
+		                if(cache->serializer) {
+		                    retval = 0;
+		                    break;
+		                } else {
+		                    /* fall through */
+		                }
+		            }
+		            /* fall through */
+		            default:
+		            {
+						/* executing update */
+		                retval = updater(
+							cache, (*slot)->value, data);
+
+						/* set modified time */
+		                (*slot)->key.mtime = apc_time();
+		            }
+		            break;
+		        }
+				/* unlock header */
+				APC_UNLOCK(cache->header);
 
-            return retval;
-        }
+		        return retval;
+		    }
+
+			/* set next slot */
+		    slot = &(*slot)->next;
+		}
+	} zend_end_try();
 
-		/* set next slot */
-        slot = &(*slot)->next;
-	}
-	
 	/* unlock header */
 	APC_UNLOCK(cache->header);
 
@@ -1623,29 +1627,31 @@ PHP_APCU_API zval* apc_cache_stat(apc_cache_t* cache,
     /* read lock header */
 	APC_RLOCK(cache->header);
 
-	/* find head */
-	slot = &cache->slots[s];
-
-	while (*slot) {
-		/* check for a matching key by has and identifier */
-	    if ((h == (*slot)->key.h) && !memcmp((*slot)->key.str, strkey, keylen)) {
-            array_init(stat);
-            
-            add_assoc_long(stat, "hits",  (*slot)->nhits);
-            add_assoc_long(stat, "access_time", (*slot)->atime);
-            add_assoc_long(stat, "mtime", (*slot)->key.mtime);
-            add_assoc_long(stat, "creation_time", (*slot)->ctime);
-            add_assoc_long(stat, "deletion_time", (*slot)->dtime);
-	        add_assoc_long(stat, "ttl",   (*slot)->value->ttl);
-	        add_assoc_long(stat, "refs",  (*slot)->value->ref_count);
-	        
-	        break;
-	    }
-
-		/* next */
-	    slot = &(*slot)->next;		
-	}
-    
+	zend_try {
+		/* find head */
+		slot = &cache->slots[s];
+
+		while (*slot) {
+			/* check for a matching key by has and identifier */
+			if ((h == (*slot)->key.h) && !memcmp((*slot)->key.str, strkey, keylen)) {
+		        array_init(stat);
+		        
+		        add_assoc_long(stat, "hits",  (*slot)->nhits);
+		        add_assoc_long(stat, "access_time", (*slot)->atime);
+		        add_assoc_long(stat, "mtime", (*slot)->key.mtime);
+		        add_assoc_long(stat, "creation_time", (*slot)->ctime);
+		        add_assoc_long(stat, "deletion_time", (*slot)->dtime);
+			    add_assoc_long(stat, "ttl",   (*slot)->value->ttl);
+			    add_assoc_long(stat, "refs",  (*slot)->value->ref_count);
+			    
+			    break;
+			}
+
+			/* next */
+			slot = &(*slot)->next;		
+		}
+	} zend_end_try();
+
     APC_RUNLOCK(cache->header);
     
     return stat;
diff --git a/apc_iterator.c b/apc_iterator.c
index 49886ccb..95d13e78 100644
--- a/apc_iterator.c
+++ b/apc_iterator.c
@@ -235,22 +235,26 @@ static int apc_iterator_fetch_active(apc_iterator_t *iterator TSRMLS_DC) {
     }
 
 	APC_RLOCK(apc_user_cache->header);
-    while(count <= iterator->chunk_size && iterator->slot_idx < apc_user_cache->nslots) {
-        slot = &apc_user_cache->slots[iterator->slot_idx];
-        while(*slot) {
-            if (apc_iterator_check_expiry(apc_user_cache, slot, t)) {
-                if (apc_iterator_search_match(iterator, slot)) {
-                    count++;
-                    item = apc_iterator_item_ctor(iterator, slot TSRMLS_CC);
-                    if (item) {
-                        apc_stack_push(iterator->stack, item TSRMLS_CC);
-                    }
-                }
-            }
-            slot = &(*slot)->next;
-        }
-        iterator->slot_idx++;
-    }
+
+    zend_try {
+		while(count <= iterator->chunk_size && iterator->slot_idx < apc_user_cache->nslots) {
+		    slot = &apc_user_cache->slots[iterator->slot_idx];
+		    while(*slot) {
+		        if (apc_iterator_check_expiry(apc_user_cache, slot, t)) {
+		            if (apc_iterator_search_match(iterator, slot)) {
+		                count++;
+		                item = apc_iterator_item_ctor(iterator, slot TSRMLS_CC);
+		                if (item) {
+		                    apc_stack_push(iterator->stack, item TSRMLS_CC);
+		                }
+		            }
+		        }
+		        slot = &(*slot)->next;
+		    }
+		    iterator->slot_idx++;
+		}
+	} zend_end_try();
+
 	APC_RUNLOCK(apc_user_cache->header);
 
     iterator->stack_idx = 0;
@@ -265,22 +269,25 @@ static int apc_iterator_fetch_deleted(apc_iterator_t *iterator TSRMLS_DC) {
     apc_iterator_item_t *item;
 
 	APC_RLOCK(apc_user_cache->header);
-    slot = &apc_user_cache->header->gc;
-    while ((*slot) && count <= iterator->slot_idx) {
-        count++;
-        slot = &(*slot)->next;
-    }
-    count = 0;
-    while ((*slot) && count < iterator->chunk_size) {
-        if (apc_iterator_search_match(iterator, slot)) {
-            count++;
-            item = apc_iterator_item_ctor(iterator, slot TSRMLS_CC);
-            if (item) {
-                apc_stack_push(iterator->stack, item TSRMLS_CC);
-            }
-        }
-        slot = &(*slot)->next;
-    }
+    
+	zend_try {
+		slot = &apc_user_cache->header->gc;
+		while ((*slot) && count <= iterator->slot_idx) {
+		    count++;
+		    slot = &(*slot)->next;
+		}
+		count = 0;
+		while ((*slot) && count < iterator->chunk_size) {
+		    if (apc_iterator_search_match(iterator, slot)) {
+		        count++;
+		        item = apc_iterator_item_ctor(iterator, slot TSRMLS_CC);
+		        if (item) {
+		            apc_stack_push(iterator->stack, item TSRMLS_CC);
+		        }
+		    }
+		    slot = &(*slot)->next;
+		}
+	} zend_end_try();
 
     iterator->slot_idx += count;
     iterator->stack_idx = 0;
@@ -296,17 +303,21 @@ static void apc_iterator_totals(apc_iterator_t *iterator TSRMLS_DC) {
     int i;
 	
 	APC_RLOCK(apc_user_cache->header);
-    for (i=0; i < apc_user_cache->nslots; i++) {
-        slot = &apc_user_cache->slots[i];
-        while((*slot)) {
-            if (apc_iterator_search_match(iterator, slot)) {
-                iterator->size += (*slot)->value->mem_size;
-                iterator->hits += (*slot)->nhits;
-                iterator->count++;
-            }
-            slot = &(*slot)->next;
-        }
-    }
+
+    zend_try {
+		for (i=0; i < apc_user_cache->nslots; i++) {
+		    slot = &apc_user_cache->slots[i];
+		    while((*slot)) {
+		        if (apc_iterator_search_match(iterator, slot)) {
+		            iterator->size += (*slot)->value->mem_size;
+		            iterator->hits += (*slot)->nhits;
+		            iterator->count++;
+		        }
+		        slot = &(*slot)->next;
+		    }
+		}
+	} zend_end_try();
+
 	APC_RUNLOCK(apc_user_cache->header);
 
     iterator->totals_flag = 1;
