cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: block process when call curl_easy_perform

From: guilherme linhares <guilherme.linhares_at_digitro.com.br>
Date: Thu, 20 Oct 2011 11:31:39 -0200

Em 19/10/2011 18:10, Dan Fandrich escreveu:
On Wed, Oct 19, 2011 at 05:18:45PM -0200, guilherme linhares wrote:
Well, i change my code to use libcurl's multi interface.
Now i call a new thread to do:

- curl_easy_init();
- curl_easy_setopt();
- curl_multi_add_handle();
- curl_multi_perform();
- curl_multi_fdset();
- curl_easy_getinfo();
Have you read the documentation on using libcurl with threads and are you
following all the recommendations? Specifically, are you calling
curl_global_init in your main thread first and are you setting the
OpenSSL locking functions?
Ok, i will change to do this.

      
In this scenario when i add 2 or more handles in the same time and do
curl_multi_perform();

I get this errors in the log

== Info: Expire cleared
== Info: Connection #0 to host 192.168.160.158 left intact
== Info: SSLv?, Unknown (2):
== Info: SSL read: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version
number, errno 0
== Info: SSL read: error:140D2081:SSL routines:TLS1_ENC:block cipher pad is
wrong, errno 0
== Info: Expire cleared
== Info: Empty reply from server
== Info: Connection #1 to host 192.168.160.158 left intact
== Info: Internal error removing splay node = 1
This looks like a serious problem--there should never be any internal
errors. What libcurl operations are occurring in other threads while
this one runs?  Can you show us the source code to a program that can reliably
reproduce this?

pthread_create(&tid[inst],NULL,(void *)AlocaHandleGet,(Registro *)&registro);

void AlocaHandleGet(Registro *Reg){

  pthread_t phtread_atual;
  int i;
  struct data config;
  int rc, maxfd, still_running;
  struct timeval timeout;
  fd_set fdread, fdwrite, fdexcep;
  int msgs_left;
  guint  size;
  long httpcode;
  CURLMsg *msg;
  CURLcode res;
  PONT_GEN psFrame;
  byte     pbyFrame[ defMAX_LENGTH_FRAME ];
  //struct curl_version_info_data *version;

  pidenvDestino = vpidenvTabela_PId[ 5 ];
  i = Reg->i;
  still_running = -1;
  psFrame.b = pbyFrame;

  config.trace_ascii = 1; /* enable ascii tracing */

  //version = curl_version_info(CURLVERSION_NOW);
  //trace("Versao libCURL:%s", version->version);

  //signal(SIGSTOP, SignalHandler);

  Reg->handle[i] = curl_easy_init();

  Reg->pPassphrase[i] = NULL;

  Reg->ocupado[i] = TRUE;

  curl_easy_setopt(Reg->handle[i], CURLOPT_URL, Reg->url[i]);
  if(Reg->metodo_http[i] == 1) //post
    curl_easy_setopt(Reg->handle[i], CURLOPT_POSTFIELDS, Reg->parametros_consulta[i]);

  curl_easy_setopt(Reg->handle[i], CURLOPT_DEBUGFUNCTION, my_trace);
  curl_easy_setopt(Reg->handle[i], CURLOPT_DEBUGDATA, &config);
  curl_easy_setopt(Reg->handle[i], CURLOPT_VERBOSE, 1L);
  curl_easy_setopt(Reg->handle[i], CURLOPT_SSL_VERIFYPEER, 0);
  //curl_easy_setopt(Reg->handle[i], CURLOPT_SSL_VERIFYHOST, 0);
  switch(Reg->tipoSSL[i])
  {
    case 1:
    {
      curl_easy_setopt(Reg->handle[i],CURLOPT_SSLCERT,Reg->arqCRT[i]);
      curl_easy_setopt(Reg->handle[i],CURLOPT_SSLCERTPASSWD,Reg->certPASS[i]);
      curl_easy_setopt(Reg->handle[i],CURLOPT_SSLKEYPASSWD,Reg->certPASS[i]);
    }
    break;
    case 2:
    {
      curl_easy_setopt(Reg->handle[i],CURLOPT_SSLKEY,Reg->arqPEM[i]);
    }
    break;
    case 3:
    {
      curl_easy_setopt(Reg->handle[i],CURLOPT_SSLCERT,Reg->arqCRT[i]);
      curl_easy_setopt(Reg->handle[i],CURLOPT_SSLCERTPASSWD,Reg->certPASS[i]);
      curl_easy_setopt(Reg->handle[i],CURLOPT_SSLKEYPASSWD,Reg->certPASS[i]);
      curl_easy_setopt(Reg->handle[i],CURLOPT_SSLKEY,Reg->arqPEM[i]);
    }
    break;
  }
  curl_easy_setopt(Reg->handle[i], CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(Reg->handle[i], CURLOPT_WRITEDATA, (void *)&Reg->chunk[i]);
  curl_easy_setopt(Reg->handle[i], CURLOPT_USERAGENT, "persona-libcurl-agent/1.0");
  curl_easy_setopt(Reg->handle[i], CURLOPT_TIMEOUT, 30); //Era 30
  //curl_easy_setopt(Reg->handle[i], CURLOPT_TIMEOUT_MS, Reg->timeoutMS[i]);  //fetchtimeout
  //curl_easy_setopt(Reg->handle[i], CURLOPT_PRIVATE, i);
  curl_easy_setopt(Reg->handle[i], CURLOPT_USERPWD, Reg->userpwd[i]);
  curl_multi_add_handle(Reg->multi_handle, Reg->handle[i]);
  trace("XXXX i=[%d]", i);

  while(CURLM_CALL_MULTI_PERFORM ==
    curl_multi_perform(Reg->multi_handle, &still_running));

  //Espera o resultado da consulta
  while(still_running) {
    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    trace("XFDXXXXX:%d", i);
    curl_multi_fdset(Reg->multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
    trace("XSELECTXXXX:%d", i);
    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

    switch(rc) {
      case -1:
        still_running = 0;
                 trace("COM-Processa select() retornou error");
                  break;
      case 0:
      default:
      trace("XLOOP PERFOM INT XXXX:%d", i);
        while(CURLM_CALL_MULTI_PERFORM ==
              curl_multi_perform(Reg->multi_handle, &still_running));
       trace("resposta CHEGOU sair:%d",i);
       trace("X2XXX i=[%d]", i);
        break;
    }
  }


  trace("X3XXX i=[%d]", i);


  while ((msg = curl_multi_info_read(Reg->multi_handle, &msgs_left))) {
    if (msg->msg == CURLMSG_DONE) {
      int idx, found = 0;

      /* Find out which handle this message is about */
      for (idx=0; idx<i; idx++) {
        found = (msg->easy_handle == Reg->handle[idx]);
        if(found)
          break;
      }
      res = curl_easy_getinfo(Reg->handle[idx], CURLINFO_HTTP_CODE, &httpcode);
      trace("X4XXX i=[%d]", idx);
      trace("COM-Ver_Resposta_Desaloca  httpcode:%ld.Inst:%d", httpcode, Reg->instAt[idx]);
      trace("COM-Ver_Resposta_Desaloca Conteudo[%lo]='%s'",(long)Reg->chunk[idx].size, Reg->chunk[idx].memory);
      //curl_multi_remove_handle(Reg->multi_handle, Reg->handle[idx]);
      registro.httpcode[idx] = httpcode;
      //curl_easy_cleanup(Reg->handle[i]);

     //This is send a command to main thread when this function are done

      /* CMD */
      *(psFrame.b++) = Cmd_TS_TS_Resultado_Fim_Thread;
      /* wHandle */
      *(psFrame.w++) = htons( (word)(idx) );
      /* wInst */
      *(psFrame.w++) = htons( (word) Reg->instAt[idx] );

      envia_cmd( envPERS, (psFrame.b - pbyFrame), pbyFrame);

      trace("NV4-ENV-COM TS_TS_Resultado_Fim_Thread  Inst:%d", Reg->instAt[idx]);
    }
  }
}


      
I use libcurl 7.19.4 openssl-0.9.7m
These are both fairly old versions. Have you tried newer versions to see if you
still have issues?
I already used curl-7.22.0 and openssl-0.9.7m but the problem continued
Do you have any openssl version to suggest ?

      
Dan
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html


-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-10-20