- proper request pool cleanup
authorMichael Wallner <mike@php.net>
Wed, 8 Jun 2005 10:01:09 +0000 (10:01 +0000)
committerMichael Wallner <mike@php.net>
Wed, 8 Jun 2005 10:01:09 +0000 (10:01 +0000)
http_methods.c
http_request_api.c
http_request_object.c
http_requestpool_object.c
php_http_request_api.h
php_http_request_object.h
php_http_requestpool_object.h

index cf8f25dd371807f818f86f264b739034694c4aeb..053fce7b232ee97845beb5a62b98d7bcbbbd38ff 100644 (file)
@@ -2119,7 +2119,7 @@ PHP_METHOD(HttpRequest, send)
 
        SET_EH_THROW_HTTP();
 
-       if (obj->attached) {
+       if (obj->pool) {
                http_error(E_WARNING, HTTP_E_CURL, "You cannot call HttpRequest::send() while attached to an HttpRequestPool");
                RETURN_FALSE;
        }
@@ -2153,6 +2153,15 @@ PHP_METHOD(HttpRequestPool, __construct)
 }
 /* }}} */
 
+PHP_METHOD(HttpRequestPool, __destruct)
+{
+       getObject(http_requestpool_object, obj);
+       
+       NO_ARGS;
+       
+       http_requestpool_object_ondestruct(&obj->pool);
+}
+
 /* {{{ proto bool HttpRequestPool::attach(HttpRequest request)
  *
  * Attach an HttpRequest object to this HttpRequestPool.
index 934bc87f5e58737523c8f4a9d25d4c59a1785c22..5a9093690b4e32384e0b73f8188d09d5ca0b97ec 100644 (file)
@@ -124,6 +124,7 @@ typedef struct {
 static http_curl_callback_ctx *_http_curl_callback_data(void *data TSRMLS_DC);
 
 static void http_request_pool_freebody(http_request_body **body);
+static void http_request_pool_freehandle(zval **request);
 static void http_request_pool_responsehandler(zval **req TSRMLS_DC);
 static inline STATUS http_request_pool_select(http_request_pool *pool);
 static inline void http_request_pool_perform(http_request_pool *pool);
@@ -168,13 +169,13 @@ void *_http_request_data_copy(int type, void *data TSRMLS_DC)
                        zend_llist_add_element(&HTTP_G(request).copies.strings, &new_str);
                        return new_str;
                }
-               
+
                case COPY_SLIST:
                {
                        zend_llist_add_element(&HTTP_G(request).copies.slists, &data);
                        return data;
                }
-               
+
                default:
                {
                        return data;
@@ -831,7 +832,7 @@ PHP_HTTP_API STATUS _http_request_pool_attach(http_request_pool *pool, zval *req
 {
        getObjectEx(http_request_object, req, request);
 
-       if (req->attached) {
+       if (req->pool) {
                http_error(E_WARNING, HTTP_E_CURL, "HttpRequest object is already member of an HttpRequestPool");
        } else {
                CURLMcode code;
@@ -844,7 +845,7 @@ PHP_HTTP_API STATUS _http_request_pool_attach(http_request_pool *pool, zval *req
                } else if (CURLM_OK != (code = curl_multi_add_handle(pool->ch, req->ch))) {
                        http_error_ex(E_WARNING, HTTP_E_CURL, "Could not attach HttpRequest object to the HttpRequestPool: %s", curl_multi_strerror(code));
                } else {
-                       req->attached = 1;
+                       req->pool = pool;
                        zval_add_ref(&request);
                        zend_llist_add_element(&pool->handles, &request);
                        zend_llist_add_element(&pool->bodies, &body);
@@ -860,15 +861,15 @@ PHP_HTTP_API STATUS _http_request_pool_detach(http_request_pool *pool, zval *req
 {
        getObjectEx(http_request_object, req, request);
 
-       if (!req->attached) {
-               http_error(E_WARNING, HTTP_E_CURL, "HttpRequest object is not attached to an HttpRequestPool");
+       if (req->pool != pool) {
+               http_error(E_WARNING, HTTP_E_CURL, "HttpRequest object is not attached to this HttpRequestPool");
        } else {
                CURLMcode code;
 
                if (CURLM_OK != (code = curl_multi_remove_handle(pool->ch, req->ch))) {
                        http_error_ex(E_WARNING, HTTP_E_CURL, "Could not detach HttpRequest object from the HttpRequestPool: %s", curl_multi_strerror(code));
                } else {
-                       req->attached = 0;
+                       req->pool = NULL;
                        zval_ptr_dtor(&request);
                        return SUCCESS;
                }
@@ -893,9 +894,19 @@ PHP_HTTP_API STATUS _http_request_pool_send(http_request_pool *pool TSRMLS_DC)
 }
 /* }}} */
 
+/* {{{ void http_request_pool_dtor(http_request_pool *) */
+PHP_HTTP_API void _http_request_pool_dtor(http_request_pool *pool TSRMLS_DC)
+{
+       pool->unfinished = 0;
+       zend_llist_clean(&pool->handles);
+       zend_llist_clean(&pool->bodies);
+       curl_multi_cleanup(pool->ch);
+}
+/* }}} */
+
 /*#*/
 
-/* {{{ static void http_request_pool_free_body(http_request_body *) */
+/* {{{ static void http_request_pool_freebody(http_request_body **) */
 static void http_request_pool_freebody(http_request_body **body)
 {
        TSRMLS_FETCH();
index 1cc8df566c0589f5d386b57dd7125bf0b22f070c..055a43e8104b8047a7534d00c8c11d56e1373cf6 100644 (file)
@@ -156,7 +156,7 @@ zend_object_value _http_request_object_new(zend_class_entry *ce TSRMLS_DC)
        o = ecalloc(1, sizeof(http_request_object));
        o->zo.ce = ce;
        o->ch = curl_easy_init();
-       o->attached = 0;
+       o->pool = NULL;
 
        phpstr_init_ex(&o->response, HTTP_CURLBUF_SIZE, 0);
 
index 09fc261045cbeac4469f52641b3c14921553daa2..a683b05e2bb0ee83ffbc3247a1028df33575b5cf 100644 (file)
@@ -42,6 +42,7 @@ static inline void _http_requestpool_object_declare_default_properties(TSRMLS_D)
 zend_class_entry *http_requestpool_object_ce;
 zend_function_entry http_requestpool_object_fe[] = {
        PHP_ME(HttpRequestPool, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+       PHP_ME(HttpRequestPool, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
        PHP_ME(HttpRequestPool, attach, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(HttpRequestPool, detach, NULL, ZEND_ACC_PUBLIC)
        PHP_ME(HttpRequestPool, send, NULL, ZEND_ACC_PUBLIC)
@@ -90,12 +91,21 @@ void _http_requestpool_object_free(zend_object *object TSRMLS_DC)
                zend_hash_destroy(OBJ_PROP(o));
                FREE_HASHTABLE(OBJ_PROP(o));
        }
-       if (o->pool.ch) {
-               curl_multi_cleanup(o->pool.ch);
-       }
+       http_request_pool_dtor(&o->pool);
        efree(o);
 }
 
+static void http_requestpool_object_ondestructhandler(zval **request, http_request_pool *pool TSRMLS_DC)
+{
+       http_request_pool_detach(pool, *request);
+}
+
+void _http_requestpool_object_ondestruct(http_request_pool *pool TSRMLS_DC)
+{
+       zend_llist_apply_with_argument(&pool->handles, (llist_apply_with_arg_func_t) http_requestpool_object_ondestructhandler, pool TSRMLS_CC);
+}
+
+
 #endif /* HTTP_HAVE_CURL */
 #endif /* ZEND_ENGINE_2 */
 
index df335bf28ff8aa624d4fe89c494049f26c856ea9..52897b64e4e83300ff6f9f93f7a3c81dfc96c8eb 100644 (file)
@@ -131,6 +131,9 @@ PHP_HTTP_API STATUS _http_request_pool_detach(http_request_pool *pool, zval *req
 #define http_request_pool_send(p) _http_request_pool_send((p) TSRMLS_CC)
 PHP_HTTP_API STATUS _http_request_pool_send(http_request_pool *pool TSRMLS_DC);
 
+#define http_request_pool_dtor(p) _http_request_pool_dtor((p) TSRMLS_CC)
+PHP_HTTP_API void _http_request_pool_dtor(http_request_pool *pool TSRMLS_DC);
+
 #define http_request_init(ch, meth, url, body, options, response) _http_request_init((ch), (meth), (url), (body), (options), (response) TSRMLS_CC)
 PHP_HTTP_API STATUS _http_request_init(CURL *ch, http_request_method meth, const char *url, http_request_body *body, HashTable *options, phpstr *response TSRMLS_DC);
 
index e8326b39c3473b92eff1da6f1bbc9540ff992bd3..e22378548a635c66a983663f84254f24f5d66d2d 100644 (file)
@@ -32,7 +32,7 @@
 typedef struct {
        zend_object zo;
        CURL *ch;
-       zend_bool attached;
+       http_request_pool *pool;
        phpstr response;
 } http_request_object;
 
index 1981c851945ac97640077143a595a1c42ace23f6..1ee1a9e2bc3f6e0b36eb7fa6cf286a4f7c1e9ea8 100644 (file)
@@ -42,8 +42,11 @@ extern void _http_requestpool_object_init(INIT_FUNC_ARGS);
 extern zend_object_value _http_requestpool_object_new(zend_class_entry *ce TSRMLS_DC);
 #define http_requestpool_object_free _http_requestpool_object_free
 extern void _http_requestpool_object_free(zend_object *object TSRMLS_DC);
+#define http_requestpool_object_ondestruct(p) _http_requestpool_object_ondestruct((p) TSRMLS_CC)
+extern void _http_requestpool_object_ondestruct(http_request_pool *pool TSRMLS_DC);
 
 PHP_METHOD(HttpRequestPool, __construct);
+PHP_METHOD(HttpRequestPool, __destruct);
 PHP_METHOD(HttpRequestPool, attach);
 PHP_METHOD(HttpRequestPool, detach);
 PHP_METHOD(HttpRequestPool, send);