-#if PHP_HTTP_HAVE_EVENT
-
-typedef struct php_http_curlm_event {
- struct event evnt;
- php_http_client_t *context;
-} php_http_curlm_event_t;
-
-static inline int etoca(short action) {
- switch (action & (EV_READ|EV_WRITE)) {
- case EV_READ:
- return CURL_CSELECT_IN;
- break;
- case EV_WRITE:
- return CURL_CSELECT_OUT;
- break;
- case EV_READ|EV_WRITE:
- return CURL_CSELECT_IN|CURL_CSELECT_OUT;
- break;
- default:
- return 0;
- }
-}
-
-static void php_http_curlm_timeout_callback(int socket, short action, void *event_data)
-{
- php_http_client_t *context = event_data;
- php_http_client_curl_t *curl = context->ctx;
-
-#if DBG_EVENTS
- fprintf(stderr, "T");
-#endif
- if (curl->useevents) {
- CURLMcode rc;
- TSRMLS_FETCH_FROM_CTX(context->ts);
-
- /* ignore and use -1,0 on timeout */
- (void) socket;
- (void) action;
-
- while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle->multi, CURL_SOCKET_TIMEOUT, 0, &curl->unfinished)));
-
- if (CURLM_OK != rc) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_multi_strerror(rc));
- }
-
- php_http_curlm_responsehandler(context);
- }
-}
-
-static void php_http_curlm_event_callback(int socket, short action, void *event_data)
-{
- php_http_client_t *context = event_data;
- php_http_client_curl_t *curl = context->ctx;
-
-#if DBG_EVENTS
- fprintf(stderr, "E");
-#endif
- if (curl->useevents) {
- CURLMcode rc = CURLM_OK;
- TSRMLS_FETCH_FROM_CTX(context->ts);
-
- while (CURLM_CALL_MULTI_PERFORM == (rc = curl_multi_socket_action(curl->handle->multi, socket, etoca(action), &curl->unfinished)));
-
- if (CURLM_OK != rc) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_multi_strerror(rc));
- }
-
- php_http_curlm_responsehandler(context);
-
- /* remove timeout if there are no transfers left */
- if (!curl->unfinished && event_initialized(curl->timeout) && event_pending(curl->timeout, EV_TIMEOUT, NULL)) {
- event_del(curl->timeout);
- }
- }
-}
-
-static int php_http_curlm_socket_callback(CURL *easy, curl_socket_t sock, int action, void *socket_data, void *assign_data)
-{
- php_http_client_t *context = socket_data;
- php_http_client_curl_t *curl = context->ctx;
-
-#if DBG_EVENTS
- fprintf(stderr, "S");
-#endif
- if (curl->useevents) {
- int events = EV_PERSIST;
- php_http_curlm_event_t *ev = assign_data;
- TSRMLS_FETCH_FROM_CTX(context->ts);
-
- if (!ev) {
- ev = ecalloc(1, sizeof(php_http_curlm_event_t));
- ev->context = context;
- curl_multi_assign(curl->handle->multi, sock, ev);
- } else {
- event_del(&ev->evnt);
- }
-
- switch (action) {
- case CURL_POLL_IN:
- events |= EV_READ;
- break;
- case CURL_POLL_OUT:
- events |= EV_WRITE;
- break;
- case CURL_POLL_INOUT:
- events |= EV_READ|EV_WRITE;
- break;
-
- case CURL_POLL_REMOVE:
- efree(ev);
- /* no break */
- case CURL_POLL_NONE:
- return 0;
-
- default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown socket action %d", action);
- return -1;
- }
-
- event_assign(&ev->evnt, curl->evbase, sock, events, php_http_curlm_event_callback, context);
- event_add(&ev->evnt, NULL);
- }
-
- return 0;
-}
-
-static void php_http_curlm_timer_callback(CURLM *multi, long timeout_ms, void *timer_data)
-{
- php_http_client_t *context = timer_data;
- php_http_client_curl_t *curl = context->ctx;
-
-#if DBG_EVENTS
- fprintf(stderr, "\ntimer <- timeout_ms: %ld\n", timeout_ms);
-#endif
- if (curl->useevents) {
-
- if (timeout_ms < 0) {
- php_http_curlm_timeout_callback(CURL_SOCKET_TIMEOUT, /*EV_READ|EV_WRITE*/0, context);
- } else if (timeout_ms > 0 || !event_initialized(curl->timeout) || !event_pending(curl->timeout, EV_TIMEOUT, NULL)) {
- struct timeval timeout;
-
- if (!event_initialized(curl->timeout)) {
- event_assign(curl->timeout, curl->evbase, CURL_SOCKET_TIMEOUT, 0, php_http_curlm_timeout_callback, context);
- }
-
- timeout.tv_sec = timeout_ms / 1000;
- timeout.tv_usec = (timeout_ms % 1000) * 1000;
-
- event_add(curl->timeout, &timeout);
- }
- }
-}
-
-#endif /* HAVE_EVENT */
-