if(!data) {
DEBUGASSERT(0);
Curl_uint_bset_remove(&multi->process, mid);
+ Curl_uint_bset_remove(&multi->dirty, mid);
continue;
}
Curl_multi_getsock(data, &ps, "curl_multi_waitfds");
if(!data) {
DEBUGASSERT(0);
Curl_uint_bset_remove(&multi->process, mid);
+ Curl_uint_bset_remove(&multi->dirty, mid);
continue;
}
Curl_multi_getsock(data, &ps, "multi_wait");
multistate(data, MSTATE_PENDING);
/* move from process to pending set */
Curl_uint_bset_remove(&multi->process, data->mid);
+ Curl_uint_bset_remove(&multi->dirty, data->mid);
Curl_uint_bset_add(&multi->pending, data->mid);
*resultp = CURLE_OK;
return rc;
/* remove from the other sets, add to msgsent */
Curl_uint_bset_remove(&multi->process, data->mid);
+ Curl_uint_bset_remove(&multi->dirty, data->mid);
Curl_uint_bset_remove(&multi->pending, data->mid);
Curl_uint_bset_add(&multi->msgsent, data->mid);
--multi->xfers_alive;
if(!data) {
DEBUGASSERT(0);
Curl_uint_bset_remove(&multi->process, mid);
+ Curl_uint_bset_remove(&multi->dirty, mid);
continue;
}
if(data != multi->admin) {
mrc->run_cpool = TRUE;
continue;
}
+ else if(!Curl_uint_bset_contains(&multi->process, mid)) {
+ /* We are no longer proecessing this transfer */
+ Curl_uint_bset_remove(&multi->dirty, mid);
+ continue;
+ }
mrc->run_xfers++;
sigpipe_apply(data, &mrc->pipe_st);
do {
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
if(data) {
- return TRUE;
+ if(Curl_uint_bset_contains(&multi->process, mid))
+ return TRUE;
+ /* We are no longer proecessing this transfer */
+ Curl_uint_bset_remove(&multi->dirty, mid);
}
else {
CURL_TRC_M(multi->admin, "dirty transfer %u no longer found", mid);
#include "memdebug.h"
+
+static struct t530_ctx {
+ int socket_calls;
+ int max_socket_calls;
+ int timer_calls;
+ int max_timer_calls;
+ char buf[1024];
+} t530_ctx;
+
+static const char *t530_tag(void)
+{
+ curl_msnprintf(t530_ctx.buf, sizeof(t530_ctx.buf),
+ "[T530-%d-%d] [%d/%d]",
+ t530_ctx.max_socket_calls, t530_ctx.max_timer_calls,
+ t530_ctx.socket_calls, t530_ctx.timer_calls);
+ return t530_ctx.buf;
+}
+
+static void t530_msg(const char *msg)
+{
+ curl_mfprintf(stderr, "%s %s\n", t530_tag(), msg);
+}
+
+
struct t530_Sockets {
curl_socket_t *sockets;
int count; /* number of sockets actually stored in array */
int i;
if(mention)
- curl_mfprintf(stderr, "Remove socket fd %d\n", (int) fd);
+ curl_mfprintf(stderr, "%s remove socket fd %d\n", t530_tag(), (int)fd);
for(i = 0; i < sockets->count; ++i) {
if(sockets->sockets[i] == fd) {
* To ensure we only have each file descriptor once, we remove it then add
* it again.
*/
- curl_mfprintf(stderr, "Add socket fd %d for %s\n", (int) fd, what);
+ curl_mfprintf(stderr, "%s add socket fd %d for %s\n",
+ t530_tag(), (int)fd, what);
t530_removeFd(sockets, fd, 0);
/*
* Allocate array storage when required.
return 0;
}
-static int max_socket_calls;
-static int socket_calls = 0;
-
/**
* Callback invoked by curl to poll reading / writing of a socket.
*/
(void)easy; /* unused */
(void)socketp; /* unused */
- curl_mfprintf(stderr, "CURLMOPT_SOCKETFUNCTION called: %u\n",
- socket_calls++);
- if(socket_calls == max_socket_calls) {
- curl_mfprintf(stderr, "curlSocketCallback returns error\n");
+ t530_ctx.socket_calls++;
+ t530_msg("-> CURLMOPT_SOCKETFUNCTION");
+ if(t530_ctx.socket_calls == t530_ctx.max_socket_calls) {
+ t530_msg("<- CURLMOPT_SOCKETFUNCTION returns error");
return -1;
}
return 0;
}
-static int max_timer_calls;
-static int timer_calls = 0;
-
/**
* Callback invoked by curl to set a timeout.
*/
struct curltime *timeout = userp;
(void)multi; /* unused */
- curl_mfprintf(stderr, "CURLMOPT_TIMERFUNCTION called: %u\n", timer_calls++);
- if(timer_calls == max_timer_calls) {
- curl_mfprintf(stderr, "curlTimerCallback returns error\n");
+ t530_ctx.timer_calls++;
+ t530_msg("-> CURLMOPT_TIMERFUNCTION");
+ if(t530_ctx.timer_calls == t530_ctx.max_timer_calls) {
+ t530_msg("<- CURLMOPT_TIMERFUNCTION returns error");
return -1;
}
if(timeout_ms != -1) {
*success = 0;
}
else {
- curl_mfprintf(stderr, "Got an unexpected message from curl: %i\n",
- (int)message->msg);
+ curl_mfprintf(stderr, "%s got an unexpected message from curl: %i\n",
+ t530_tag(), (int)message->msg);
result = 1;
*success = 0;
}
int numhandles = 0;
CURLMcode result = curl_multi_socket_action(curl, s, evBitmask, &numhandles);
if(result != CURLM_OK) {
- curl_mfprintf(stderr, "Curl error on %s (%i) %s\n",
- info, result, curl_multi_strerror(result));
+ curl_mfprintf(stderr, "%s Curl error on %s (%i) %s\n",
+ t530_tag(), info, result, curl_multi_strerror(result));
}
return (int)result;
}
return result;
}
-static CURLcode testone(char *URL, int timercb, int socketcb)
+static CURLcode testone(char *URL, int timer_fail_at, int socket_fail_at)
{
CURLcode res = CURLE_OK;
CURL *curl = NULL; CURLM *m = NULL;
timeout.tv_sec = (time_t)-1;
/* set the limits */
- max_timer_calls = timercb;
- max_socket_calls = socketcb;
- timer_calls = 0; /* reset the globals */
- socket_calls = 0;
+ memset(&t530_ctx, 0, sizeof(t530_ctx));
+ t530_ctx.max_timer_calls = timer_fail_at;
+ t530_ctx.max_socket_calls = socket_fail_at;
- curl_mfprintf(stderr, "start test: %d %d\n", timercb, socketcb);
+ t530_msg("start");
start_test_timing();
res_global_init(CURL_GLOBAL_ALL);
}
if(!success) {
- curl_mfprintf(stderr, "Error getting file.\n");
+ t530_msg("Error getting file.");
res = TEST_ERR_MAJOR_BAD;
}
test_cleanup:
/* proper cleanup sequence */
- curl_mfprintf(stderr, "cleanup: %d %d\n", timercb, socketcb);
+ t530_msg("cleanup");
curl_multi_remove_handle(m, curl);
curl_easy_cleanup(curl);
curl_multi_cleanup(m);
/* free local memory */
free(sockets.read.sockets);
free(sockets.write.sockets);
+ t530_msg("done");
return res;
}
CURLcode rc;
/* rerun the same transfer multiple times and make it fail in different
callback calls */
- rc = testone(URL, 0, 0);
+ rc = testone(URL, 0, 0); /* no callback fails */
if(rc)
- curl_mfprintf(stderr, "test 0/0 failed: %d\n", rc);
+ curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc);
- rc = testone(URL, 1, 0);
+ rc = testone(URL, 1, 0); /* fail 1st call to timer callback */
if(!rc)
- curl_mfprintf(stderr, "test 1/0 failed: %d\n", rc);
+ curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc);
- rc = testone(URL, 2, 0);
+ rc = testone(URL, 2, 0); /* fail 2nd call to timer callback */
if(!rc)
- curl_mfprintf(stderr, "test 2/0 failed: %d\n", rc);
+ curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc);
- rc = testone(URL, 0, 1);
+ rc = testone(URL, 0, 1); /* fail 1st call to socket callback */
if(!rc)
- curl_mfprintf(stderr, "test 0/1 failed: %d\n", rc);
+ curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc);
- rc = testone(URL, 0, 2);
+ rc = testone(URL, 0, 2); /* fail 2nd call to socket callback */
if(!rc)
- curl_mfprintf(stderr, "test 0/2 failed: %d\n", rc);
+ curl_mfprintf(stderr, "%s FAILED: %d\n", t530_tag(), rc);
return CURLE_OK;
}