+ zend_hash_destroy(&list->free);
+}
+
+static inline void http_persistent_handle_list_free(http_persistent_handle_list **list, http_persistent_handle_dtor dtor)
+{
+ http_persistent_handle_list_dtor(*list, dtor);
+ pefree(*list, 1);
+ *list = NULL;
+}
+
+static inline http_persistent_handle_list *http_persistent_handle_list_find(http_persistent_handle_provider *provider TSRMLS_DC)
+{
+ http_persistent_handle_list **list, *new_list;
+
+ if (SUCCESS == zend_hash_quick_find(&provider->list.free, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &list)) {
+ return *list;
+ }
+
+ if ((new_list = http_persistent_handle_list_init(NULL))) {
+ if (SUCCESS == zend_hash_quick_add(&provider->list.free, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &new_list, sizeof(http_persistent_handle_list *), (void *) &list)) {
+ return *list;
+ }
+ http_persistent_handle_list_free(&new_list, provider->dtor);
+ }
+
+ return NULL;
+}
+
+static inline STATUS http_persistent_handle_do_acquire(http_persistent_handle_provider *provider, void **handle_ptr TSRMLS_DC)
+{
+ ulong index;
+ http_persistent_handle *handle;
+ http_persistent_handle_list *list;
+
+ if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) {
+ zend_hash_internal_pointer_end(&list->free);
+ if (HASH_KEY_NON_EXISTANT != zend_hash_get_current_key(&list->free, NULL, &index, 0) && SUCCESS == zend_hash_get_current_data(&list->free, (void *) &handle)) {
+ *handle_ptr = handle->ptr;
+ zend_hash_index_del(&list->free, index);
+ } else {
+ *handle_ptr = provider->ctor();
+ }
+
+ if (*handle_ptr) {
+ ++provider->list.used;
+ ++list->used;
+ return SUCCESS;
+ }
+ }
+
+ return FAILURE;
+}
+
+static inline STATUS http_persistent_handle_do_release(http_persistent_handle_provider *provider, void **handle_ptr TSRMLS_DC)
+{
+ http_persistent_handle_list *list;
+
+ if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) {
+ if (provider->list.used >= HTTP_G->persistent.handles.limit) {
+ provider->dtor(*handle_ptr);
+ } else {
+ http_persistent_handle handle = {*handle_ptr};
+
+ if (SUCCESS != zend_hash_next_index_insert(&list->free, (void *) &handle, sizeof(http_persistent_handle), NULL)) {
+ return FAILURE;
+ }
+ }
+
+ *handle_ptr = NULL;
+ --provider->list.used;
+ --list->used;
+ return SUCCESS;
+ }
+
+ return FAILURE;
+}
+
+static inline STATUS http_persistent_handle_do_accrete(http_persistent_handle_provider *provider, void *old_handle, void **new_handle TSRMLS_DC)
+{
+ http_persistent_handle_list *list;
+
+ if (provider->copy && (*new_handle = provider->copy(old_handle))) {
+ if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) {
+ ++list->used;
+ }
+ ++provider->list.used;
+ return SUCCESS;
+ }
+ return FAILURE;