cURL / Mailing Lists / curl-library / Single Mail

curl-library

pthread_cancel while in curl_easy_perform

From: Andrew Strohman <astrohman_at_edgecast.com>
Date: Tue, 29 Jan 2013 13:27:52 -0800

Hello,

  I would like to be able to cancel a thread that is in the middle of
curl_easy_perform without leaking memory or sockets. My first attempt
was to do this:

 curl_handle = curl_easy_init();
 pthread_cleanup_push((void (*)(void*))curl_easy_cleanup, (void *)curl_handle);

I noticed that when I cancel a a thread while it's still attempting to
connect, I leak sockets. Strangely, this does not appear to happen
the first couple of times this happens, but then leaks sockets
consistently thereafter. So it seems like curl_easy_cleanup will not
clean up all resources if curl_easy_perform is not allowed to
complete?

To try to work around this, I do:

void closeSock(void * pSock)
{
  if(*(int *)pSock != -1)
  {
    if(!close(*(short int *)pSock))
      *(int *)pSock = -1;
  }
}

int curl_close_socket(void *clientp, curl_socket_t item)
{
  closeSock(clientp);
  return 0;
}

curl_socket_t curl_open_socket(void *clientp, curlsocktype purpose,
struct curl_sockaddr *address)
{
  int sock = socket(address->family, address->socktype, address->protocol);
  *(int *)clientp = sock;
  return sock;
}

 CURL *curl_handle;
 int sock = -1;
 pthread_cleanup_push(closeSock, &sock);
 curl_handle = curl_easy_init();
 pthread_cleanup_push((void (*)(void*))curl_easy_cleanup, (void *)curl_handle);

  if(curl_easy_setopt(curl_handle, CURLOPT_OPENSOCKETFUNCTION,
&curl_open_socket))
    printf("CURLOPT_OPENSOCKETFUNCTION");
  if(curl_easy_setopt(curl_handle, CURLOPT_OPENSOCKETDATA, &sock))
    printf("CURLOPT_OPENSOCKETDATA");
 if(curl_easy_setopt(curl_handle, CURLOPT_CLOSESOCKETFUNCTION,
&curl_close_socket))
    printf("CURLOPT_CLOSESOCKETFUNCTION");
  if(curl_easy_setopt(curl_handle, CURLOPT_CLOSESOCKETDATA, &sock))
    printf("CURLOPT_CLOSESOCKETDATA");

This stops the sockets from being leaked.

I have two problems with what I did here:

1) Is there some other resource that will be leaked besides these sockets?
2) If I comment out the closeSock(clientp) call in curl_close_socket,
it seems like the socket gets closed anyway? The behaviour I expect
is that none of the sockets would get closed. Can you guys help me
understand that? I want to make sure that curl_close_socket is the
only way sockets are being closed so that another threads socket does
not get inadvertently closed.

I am using libcurl/7.22.0, and I don't see those curl_easy_setopt calls failing.

Any help would be much appreciated.

Thanks,

Andy
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-01-29