Skip to content

Commit 773dbb2

Browse files
authored
Fix #4393 (#4418)
* Fix #4393 * Optimize tests
1 parent 280fd49 commit 773dbb2

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

ext-src/swoole_curl.cc

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ int Multi::cb_error(Reactor *reactor, Event *event) {
4444

4545
int Multi::handle_socket(CURL *easy, curl_socket_t s, int action, void *userp, void *socketp) {
4646
Multi *multi = (Multi *) userp;
47+
swoole_trace_log(SW_TRACE_CO_CURL, SW_ECHO_CYAN "action=%d, userp=%p, socketp=%p", "[HANDLE_SOCKET]", action, userp, socketp);
4748
switch (action) {
4849
case CURL_POLL_IN:
4950
case CURL_POLL_OUT:
@@ -94,7 +95,7 @@ void Multi::del_event(CURL *cp, void *socket_ptr, curl_socket_t sockfd) {
9495
Handle *handle = get_handle(cp);
9596
handle->socket = nullptr;
9697

97-
swoole_trace_log(SW_TRACE_CO_CURL, SW_ECHO_RED " handle=%p, curl=%p, fd=%d", "[DEL]", handle, cp, sockfd);
98+
swoole_trace_log(SW_TRACE_CO_CURL, SW_ECHO_RED " handle=%p, curl=%p, fd=%d", "[DEL_EVENT]", handle, cp, sockfd);
9899
}
99100

100101
void Multi::set_event(CURL *cp, void *socket_ptr, curl_socket_t sockfd, int action) {
@@ -119,7 +120,7 @@ void Multi::set_event(CURL *cp, void *socket_ptr, curl_socket_t sockfd, int acti
119120
handle->action = action;
120121

121122
swoole_trace_log(
122-
SW_TRACE_CO_CURL, SW_ECHO_GREEN " handle=%p, curl=%p, fd=%d, events=%d", "[ADD]", handle, cp, sockfd, events);
123+
SW_TRACE_CO_CURL, SW_ECHO_GREEN " handle=%p, curl=%p, fd=%d, events=%d", "[ADD_EVENT]", handle, cp, sockfd, events);
123124
}
124125

125126
CURLMcode Multi::add_handle(CURL *cp) {
@@ -132,6 +133,8 @@ CURLMcode Multi::add_handle(CURL *cp) {
132133
curl_easy_setopt(cp, CURLOPT_PRIVATE, handle);
133134
}
134135
handle->multi = this;
136+
swoole_trace_log(
137+
SW_TRACE_CO_CURL, SW_ECHO_GREEN " handle=%p, curl=%p", "[ADD_HANDLE]", handle, cp);
135138
}
136139
return retval;
137140
}
@@ -143,6 +146,8 @@ CURLMcode Multi::remove_handle(CURL *cp) {
143146
if (handle) {
144147
handle->multi = nullptr;
145148
}
149+
swoole_trace_log(
150+
SW_TRACE_CO_CURL, SW_ECHO_RED " handle=%p, curl=%p", "[REMOVE_HANDLE]", handle, cp);
146151
}
147152
return retval;
148153
}
@@ -233,6 +238,7 @@ CURLcode Multi::read_info() {
233238

234239
int Multi::handle_timeout(CURLM *mh, long timeout_ms, void *userp) {
235240
Multi *multi = (Multi *) userp;
241+
swoole_trace_log(SW_TRACE_CO_CURL, SW_ECHO_BLUE "timeout_ms=%d", "[HANDLE_TIMEOUT]", timeout_ms);
236242
if (!swoole_event_is_available()) {
237243
return 0;
238244
}
@@ -252,13 +258,20 @@ long Multi::select(php_curlm *mh, double timeout) {
252258
return 0;
253259
}
254260

261+
if (curl_multi_socket_all(multi_handle_, &running_handles_) != CURLM_OK) {
262+
return CURLE_FAILED_INIT;
263+
}
264+
255265
for (zend_llist_element *element = mh->easyh.head; element; element = element->next) {
256266
zval *z_ch = (zval *) element->data;
257267
php_curl *ch;
258268
if ((ch = swoole_curl_get_handle(z_ch, false)) == NULL) {
259269
continue;
260270
}
261271
Handle *handle = get_handle(ch->cp);
272+
273+
swoole_trace_log(SW_TRACE_CO_CURL, "handle=%p, handle->socket=%p, handle->socket->removed=%d", handle, handle ? handle->socket :nullptr);
274+
262275
if (handle && handle->socket && handle->socket->removed) {
263276
if (swoole_event_add(handle->socket, get_event(handle->action)) == SW_OK) {
264277
event_count_++;
@@ -278,6 +291,8 @@ long Multi::select(php_curlm *mh, double timeout) {
278291
co->yield_ex(timeout);
279292
co = nullptr;
280293

294+
swoole_trace_log(SW_TRACE_CO_CURL, "yield timeout, count=%d", zend_llist_count(&mh->easyh));
295+
281296
auto count = selector->active_handles.size();
282297

283298
for (zend_llist_element *element = mh->easyh.head; element; element = element->next) {
@@ -297,7 +312,7 @@ long Multi::select(php_curlm *mh, double timeout) {
297312

298313
if (selector->timer_callback) {
299314
selector->timer_callback = false;
300-
curl_multi_socket_action(multi_handle_, -1, 0, &running_handles_);
315+
curl_multi_socket_action(multi_handle_, CURL_SOCKET_TIMEOUT, 0, &running_handles_);
301316
swoole_trace_log(SW_TRACE_CO_CURL, "socket_action[timer], running_handles=%d", running_handles_);
302317
}
303318

tests/swoole_curl/multi/bug4393.phpt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
--TEST--
2+
swoole_curl: guzzle
3+
--SKIPIF--
4+
<?php
5+
require __DIR__ . '/../../include/skipif.inc';
6+
?>
7+
--FILE--
8+
<?php
9+
require __DIR__ . '/../../include/bootstrap.php';
10+
require_once TESTS_LIB_PATH . '/vendor/autoload.php';
11+
12+
use Swoole\Coroutine\Barrier;
13+
use Swoole\Runtime;
14+
use GuzzleHttp\Client;
15+
use GuzzleHttp\Promise;
16+
17+
use function Swoole\Coroutine\run;
18+
use function Swoole\Coroutine\go;
19+
20+
Runtime::enableCoroutine(SWOOLE_HOOK_NATIVE_CURL);
21+
22+
run(function () {
23+
$guzzle = new Client();
24+
25+
$test = function () use ($guzzle) {
26+
$promises = [
27+
'qq' => $guzzle->getAsync('https://www.qq.com/'),
28+
'baidu' => $guzzle->getAsync('http://www.baidu.com/'),
29+
];
30+
31+
$responses = [];
32+
foreach (Promise\Utils::settle($promises)->wait() as $k => $v) {
33+
$responses[$k] = $v['value'];
34+
}
35+
36+
Assert::contains($responses['baidu']->getBody(), '百度');
37+
Assert::contains(iconv('gbk', 'utf-8', $responses['qq']->getBody()), '腾讯');
38+
};
39+
40+
$n = 2;
41+
while ($n--) {
42+
$s = microtime(true);
43+
$test();
44+
Assert::lessThan(microtime(true) - $s, 1.5);
45+
}
46+
47+
echo 'Done' . PHP_EOL;
48+
});
49+
?>
50+
--EXPECT--
51+
Done

0 commit comments

Comments
 (0)