From 6bd8a9818c329bb7526f3db8b8d8ef36a95f303f Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 8 Jun 2005 11:14:14 +0000 Subject: [PATCH] - make the asynchronous behaviour of curl_multi available by socketSend(), socketSelect() and socketRead() methods of HttpRequestPool --- http_methods.c | 52 +++++++++++++++++++++++++ http_request_api.c | 72 +++++++++++++++++------------------ http_requestpool_object.c | 4 ++ php_http_request_api.h | 9 +++++ php_http_requestpool_object.h | 3 ++ 5 files changed, 102 insertions(+), 38 deletions(-) diff --git a/http_methods.c b/http_methods.c index e10923b..a8f5d94 100644 --- a/http_methods.c +++ b/http_methods.c @@ -2233,6 +2233,58 @@ PHP_METHOD(HttpRequestPool, send) } /* }}} */ +/* {{{ proto protected bool HttpRequestPool::socketSend() + * + * Usage: + *
+ *	socketSend()) {
+ *			do_something_else();
+ *			if (!$pool->socketSelect()) {
+ *				die('Socket error');
+ *			}
+ *		}
+ *		$pool->socketRead();
+ *	?>
+ * 
+ */ +PHP_METHOD(HttpRequestPool, socketSend) +{ + getObject(http_requestpool_object, obj); + + NO_ARGS; + + RETURN_BOOL(0 < http_request_pool_perform(&obj->pool)); +} +/* }}} */ + +/* {{{ proto protected bool HttpRequestPool::socketSelect() + * + * See HttpRequestPool::socketSend(). + */ +PHP_METHOD(HttpRequestPool, socketSelect) +{ + getObject(http_requestpool_object, obj); + + NO_ARGS; + + RETURN_SUCCESS(http_request_pool_select(&obj->pool)); +} +/* }}} */ + +/* {{{ proto protected void HttpRequestPool::socketRead() + * + * See HttpRequestPool::socketSend(). + */ +PHP_METHOD(HttpRequestPool, socketRead) +{ + getObject(http_requestpool_object, obj); + + NO_ARGS; + + zend_llist_apply(&obj->pool.handles, (llist_apply_func_t) http_request_pool_responsehandler TSRMLS_CC); +} + /* }}} */ /* }}} */ diff --git a/http_request_api.c b/http_request_api.c index b41e020..3644f9d 100644 --- a/http_request_api.c +++ b/http_request_api.c @@ -129,9 +129,6 @@ 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, http_request_pool *pool TSRMLS_DC); -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); #if HTTP_CURL_USE_ZEND_MM static void http_curl_free(void *p) { efree(p); } @@ -906,8 +903,7 @@ PHP_HTTP_API STATUS _http_request_pool_send(http_request_pool *pool TSRMLS_DC) #if HTTP_DEBUG_REQPOOLS fprintf(stderr, "Attempt to send requests of pool %p\n", pool); #endif - http_request_pool_perform(pool); - while (pool->unfinished) { + while (http_request_pool_perform(pool)) { #if HTTP_DEBUG_REQPOOLS fprintf(stderr, "%d unfinished requests of pool %p remaining\n", pool->unfinished, pool); #endif @@ -915,7 +911,6 @@ PHP_HTTP_API STATUS _http_request_pool_send(http_request_pool *pool TSRMLS_DC) http_error(E_WARNING, HTTP_E_CURL, "Socket error"); return FAILURE; } - http_request_pool_perform(pool); } zend_llist_apply(&pool->handles, (llist_apply_func_t) http_request_pool_responsehandler TSRMLS_CC); return SUCCESS; @@ -935,31 +930,32 @@ PHP_HTTP_API void _http_request_pool_dtor(http_request_pool *pool TSRMLS_DC) } /* }}} */ -/*#*/ - -/* {{{ static void http_request_pool_freebody(http_request_body **) */ -static void http_request_pool_freebody(http_request_body **body) +/* {{{ STATUS http_request_pool_select(http_request_pool *) */ +PHP_HTTP_API STATUS _http_request_pool_select(http_request_pool *pool) { - TSRMLS_FETCH(); - http_request_body_free(*body); + int MAX; + fd_set R, W, E; + struct timeval timeout = {1, 0}; + + FD_ZERO(&R); + FD_ZERO(&W); + FD_ZERO(&E); + + curl_multi_fdset(pool->ch, &R, &W, &E, &MAX); + return (-1 != select(MAX + 1, &R, &W, &E, &timeout)) ? SUCCESS : FAILURE; } /* }}} */ -/* {{{ static void http_request_pool_freehandle(zval **, http_request_pool *) */ -static void http_request_pool_freehandle(zval **request, http_request_pool *pool TSRMLS_DC) +/* {{{ int http_request_pool_perform(http_request_pool *) */ +PHP_HTTP_API int _http_request_pool_perform(http_request_pool *pool) { - getObjectEx(http_request_object, req, *request); - if (req->pool) { - http_request_pool_detach(pool, *request); - } -#if HTTP_DEBUG_REQPOOLS - else fprintf(stderr, "Request %p (pool: %p) is not (anymore) attached to pool %p\n", req, req->pool, pool); -#endif + while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(pool->ch, &pool->unfinished)); + return pool->unfinished; } /* }}} */ -/* {{{ static void http_request_pool_responsehandler(zval **) */ -static void http_request_pool_responsehandler(zval **req TSRMLS_DC) +/* {{{ void http_request_pool_responsehandler(zval **) */ +void _http_request_pool_responsehandler(zval **req TSRMLS_DC) { getObjectEx(http_request_object, obj, *req); #if HTTP_DEBUG_REQPOOLS @@ -969,26 +965,26 @@ static void http_request_pool_responsehandler(zval **req TSRMLS_DC) } /* }}} */ -/* {{{ static inline STATUS http_request_pool_select(http_request_pool *) */ -static inline STATUS http_request_pool_select(http_request_pool *pool) -{ - int MAX; - fd_set R, W, E; - struct timeval timeout = {1, 0}; - - FD_ZERO(&R); - FD_ZERO(&W); - FD_ZERO(&E); +/*#*/ - curl_multi_fdset(pool->ch, &R, &W, &E, &MAX); - return (-1 != select(MAX + 1, &R, &W, &E, &timeout)) ? SUCCESS : FAILURE; +/* {{{ static void http_request_pool_freebody(http_request_body **) */ +static void http_request_pool_freebody(http_request_body **body) +{ + TSRMLS_FETCH(); + http_request_body_free(*body); } /* }}} */ -/* {{{ static inline void http_request_pool_perform(http_request_pool *) */ -static inline void http_request_pool_perform(http_request_pool *pool) +/* {{{ static void http_request_pool_freehandle(zval **, http_request_pool *) */ +static void http_request_pool_freehandle(zval **request, http_request_pool *pool TSRMLS_DC) { - while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(pool->ch, &pool->unfinished)); + getObjectEx(http_request_object, req, *request); + if (req->pool) { + http_request_pool_detach(pool, *request); + } +#if HTTP_DEBUG_REQPOOLS + else fprintf(stderr, "Request %p (pool: %p) is not (anymore) attached to pool %p\n", req, req->pool, pool); +#endif } /* }}} */ diff --git a/http_requestpool_object.c b/http_requestpool_object.c index e559617..000a044 100644 --- a/http_requestpool_object.c +++ b/http_requestpool_object.c @@ -47,6 +47,10 @@ zend_function_entry http_requestpool_object_fe[] = { PHP_ME(HttpRequestPool, detach, NULL, ZEND_ACC_PUBLIC) PHP_ME(HttpRequestPool, send, NULL, ZEND_ACC_PUBLIC) PHP_ME(HttpRequestPool, reset, NULL, ZEND_ACC_PUBLIC) + + PHP_ME(HttpRequestPool, socketSend, NULL, ZEND_ACC_PROTECTED) + PHP_ME(HttpRequestPool, socketSelect, NULL, ZEND_ACC_PROTECTED) + PHP_ME(HttpRequestPool, socketRead, NULL, ZEND_ACC_PROTECTED) {NULL, NULL, NULL} }; diff --git a/php_http_request_api.h b/php_http_request_api.h index 9d454b5..8ded83e 100644 --- a/php_http_request_api.h +++ b/php_http_request_api.h @@ -92,6 +92,9 @@ extern void _http_request_data_free_string(void *string); #define http_request_data_free_slist _http_request_data_free_slist extern void _http_request_data_free_slist(void *list); +#define http_request_pool_responsehandler _http_request_pool_responsehandler +extern void http_request_pool_responsehandler(zval **req TSRMLS_DC); + #define http_request_global_init _http_request_global_init extern STATUS _http_request_global_init(void); @@ -134,6 +137,12 @@ PHP_HTTP_API void _http_request_pool_detach_all(http_request_pool *pool TSRMLS_D #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_select _http_request_pool_select +PHP_HTTP_API STATUS _http_request_pool_select(http_request_pool *pool); + +#define http_request_pool_perform _http_request_pool_perform +PHP_HTTP_API int _http_request_pool_perform(http_request_pool *pool); + #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); diff --git a/php_http_requestpool_object.h b/php_http_requestpool_object.h index 46d2a5e..f11e65c 100644 --- a/php_http_requestpool_object.h +++ b/php_http_requestpool_object.h @@ -49,6 +49,9 @@ PHP_METHOD(HttpRequestPool, attach); PHP_METHOD(HttpRequestPool, detach); PHP_METHOD(HttpRequestPool, send); PHP_METHOD(HttpRequestPool, reset); +PHP_METHOD(HttpRequestPool, socketSend); +PHP_METHOD(HttpRequestPool, socketSelect); +PHP_METHOD(HttpRequestPool, socketRead); #endif #endif -- 2.30.2