> Do you have a specific use case for when this causes problems? It could help 
> to make a test case for it so that a restructure of the code can be tested 
> against a good scenario.

Attached code reproduces the issue, at least part of it.

--
Paras
                                          
#include <curl/curl.h>

void multi_perform(CURLM *multi) {
  int still_running;
  int i;
  curl_multi_perform(multi, &still_running);
  do {
    struct timeval timeout;
    int rc;

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;

    long curl_timeo = -1;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    curl_multi_timeout(multi, &curl_timeo);
    if(curl_timeo >= 0) {
      timeout.tv_sec = curl_timeo / 1000;
      if(timeout.tv_sec > 1)
        timeout.tv_sec = 1;
      else
        timeout.tv_usec = (curl_timeo % 1000) * 1000;
    }

    curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

    switch(rc) {
    case -1:
      break;
    case 0:
    default:
      curl_multi_perform(multi, &still_running);
      break;
    }
  } while(still_running);
}

int main(int argc, char** argv) {
  CURL *easy1 = curl_easy_init();
  curl_easy_setopt(easy1, CURLOPT_USERPWD, "user1:pwd");
  curl_easy_setopt(easy1, CURLOPT_HTTPAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM);
  curl_easy_setopt(easy1, CURLOPT_URL, "https://www.ntlm.com/";);
  curl_easy_setopt(easy1, CURLOPT_MAXREDIRS, 2L);
  //curl_easy_setopt(easy1, CURLOPT_VERBOSE, 1L);
  CURL *easy2 = curl_easy_duphandle(easy1);
  curl_easy_setopt(easy1, CURLOPT_USERPWD, "user2:pwd");

  CURLM *multi = curl_multi_init();
  curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, 1L);

  curl_multi_add_handle(multi, easy1);
  multi_perform(multi);

  int messages_left;
  CURLMsg *msg = curl_multi_info_read(multi, &messages_left);
  //Should be success
  printf("%s\n", msg->data.result == CURLE_OK ? "Success" : "Failure");

  curl_multi_add_handle(multi, easy2);
  multi_perform(multi);
  msg = curl_multi_info_read(multi, &messages_left);
  //Failure indicates that the previous connection has interfered with the 
current operation,
  //specifically, an extra redirect was needed because cleaning up the previous 
connection has reset state.authhost.picked
  printf("%s\n", msg->data.result == CURLE_OK ? "Success" : "Failure");

  curl_multi_cleanup(multi);
  curl_easy_cleanup(easy1);
  curl_easy_cleanup(easy2);

  return 0;
}
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to