+ SET_EH_NORMAL();
+ RETURN_SUCCESS(status);
+}
+/* }}} */
+
+/* {{{ proto bool HttpRequestPool::send()
+ Send all attached HttpRequest objects in parallel. */
+PHP_METHOD(HttpRequestPool, send)
+{
+ STATUS status;
+ getObject(http_requestpool_object, obj);
+
+ NO_ARGS;
+
+ SET_EH_THROW_HTTP();
+ status = http_request_pool_send(&obj->pool);
+ SET_EH_NORMAL();
+
+ /* rethrow as HttpRequestPoolException */
+ http_final(HTTP_EX_CE(request_pool));
+
+ RETURN_SUCCESS(status);
+}
+/* }}} */
+
+/* {{{ proto protected bool HttpRequestPool::socketPerform()
+ Returns TRUE until each request has finished its transaction. */
+PHP_METHOD(HttpRequestPool, socketPerform)
+{
+ getObject(http_requestpool_object, obj);
+
+ NO_ARGS;
+
+ if (0 < http_request_pool_perform(&obj->pool)) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto protected bool HttpRequestPool::socketSelect([double timeout]) */
+PHP_METHOD(HttpRequestPool, socketSelect)
+{
+ double timeout = 0;
+ struct timeval custom_timeout, *custom_timeout_ptr = NULL;
+ getObject(http_requestpool_object, obj);
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|d", &timeout)) {
+ RETURN_FALSE;
+ }
+ if (ZEND_NUM_ARGS() && timeout > 0) {
+ custom_timeout.tv_sec = (time_t) timeout;
+ custom_timeout.tv_usec = HTTP_USEC(timeout) % HTTP_MCROSEC;
+ custom_timeout_ptr = &custom_timeout;
+ }
+
+ RETURN_SUCCESS(http_request_pool_select_ex(&obj->pool, custom_timeout_ptr));
+}
+/* }}} */
+
+/* {{{ proto bool HttpRequestPool::valid()
+ Implements Iterator::valid(). */
+PHP_METHOD(HttpRequestPool, valid)
+{
+ NO_ARGS;
+
+ if (return_value_used) {
+ getObject(http_requestpool_object, obj);
+ RETURN_BOOL(obj->iterator.pos >= 0 && obj->iterator.pos < zend_llist_count(&obj->pool.handles));
+ }
+}
+/* }}} */
+
+/* {{{ proto HttpRequest HttpRequestPool::current()
+ Implements Iterator::current(). */
+PHP_METHOD(HttpRequestPool, current)
+{
+ NO_ARGS;
+
+ if (return_value_used) {
+ long pos = 0;
+ zval **current = NULL;
+ zend_llist_position lpos;
+ getObject(http_requestpool_object, obj);
+
+ if (obj->iterator.pos < zend_llist_count(&obj->pool.handles)) {
+ for ( current = zend_llist_get_first_ex(&obj->pool.handles, &lpos);
+ current && obj->iterator.pos != pos++;
+ current = zend_llist_get_next_ex(&obj->pool.handles, &lpos));
+ if (current) {
+ RETURN_OBJECT(*current, 1);
+ }
+ }
+ RETURN_NULL();
+ }
+}
+/* }}} */
+
+/* {{{ proto int HttpRequestPool::key()
+ Implements Iterator::key(). */
+PHP_METHOD(HttpRequestPool, key)
+{
+ NO_ARGS;
+
+ if (return_value_used) {
+ getObject(http_requestpool_object, obj);
+ RETURN_LONG(obj->iterator.pos);
+ }
+}
+/* }}} */
+
+/* {{{ proto void HttpRequestPool::next()
+ Implements Iterator::next(). */
+PHP_METHOD(HttpRequestPool, next)
+{
+ NO_ARGS {
+ getObject(http_requestpool_object, obj);
+ ++(obj->iterator.pos);
+ }
+}
+/* }}} */
+
+/* {{{ proto void HttpRequestPool::rewind()
+ Implements Iterator::rewind(). */
+PHP_METHOD(HttpRequestPool, rewind)
+{
+ NO_ARGS {
+ getObject(http_requestpool_object, obj);
+ obj->iterator.pos = 0;
+ }
+}
+/* }}} */
+
+/* {{{ proto int HttpRequestPool::count()
+ Implements Countable::count(). */
+PHP_METHOD(HttpRequestPool, count)
+{
+ NO_ARGS {
+ getObject(http_requestpool_object, obj);
+ RETURN_LONG((long) zend_llist_count(&obj->pool.handles));
+ }
+}
+/* }}} */
+
+/* {{{ proto array HttpRequestPool::getAttachedRequests()
+ Get attached HttpRequest objects. */
+PHP_METHOD(HttpRequestPool, getAttachedRequests)
+{
+ getObject(http_requestpool_object, obj);
+
+ NO_ARGS;
+
+ array_init(return_value);
+ zend_llist_apply_with_argument(&obj->pool.handles,
+ (llist_apply_with_arg_func_t) http_requestpool_object_llist2array,
+ return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto array HttpRequestPool::getFinishedRequests()
+ Get attached HttpRequest objects that already have finished their work. */
+PHP_METHOD(HttpRequestPool, getFinishedRequests)
+{
+ getObject(http_requestpool_object, obj);
+
+ NO_ARGS;
+
+ array_init(return_value);
+ zend_llist_apply_with_argument(&obj->pool.finished,
+ (llist_apply_with_arg_func_t) http_requestpool_object_llist2array,
+ return_value TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto bool HttpRequestPool::enablePipelining([bool enable = true])
+ Enables pipelining support for all attached requests if support in libcurl is given. */
+PHP_METHOD(HttpRequestPool, enablePipelining)
+{
+ zend_bool enable = 1;
+#if defined(HAVE_CURL_MULTI_SETOPT) && HTTP_CURL_VERSION(7,16,0)
+ getObject(http_requestpool_object, obj);
+#endif
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable)) {
+ RETURN_FALSE;
+ }
+#if defined(HAVE_CURL_MULTI_SETOPT) && HTTP_CURL_VERSION(7,16,0)
+ if (CURLM_OK == curl_multi_setopt(obj->pool.ch, CURLMOPT_PIPELINING, (long) enable)) {
+ RETURN_TRUE;
+ }
+#endif
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool HttpRequestPool::enableEvents([bool enable = true])
+ Enables event-driven I/O if support in libcurl is given. */
+PHP_METHOD(HttpRequestPool, enableEvents)
+{
+ zend_bool enable = 1;
+#if defined(HTTP_HAVE_EVENT)
+ getObject(http_requestpool_object, obj);
+#endif
+
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable)) {
+#if defined(HTTP_HAVE_EVENT)
+ obj->pool.useevents = enable;
+ RETURN_TRUE;
+#endif