sockfilt.c: Reduce the number of individual memory allocations
Merge multiple internal arrays into one, even if some variables will not not be used. They are all created with the number of file descriptors as their size. Also fix possible thread handle leak in CloseHandle-loop.
This commit is contained in:
		@@ -666,15 +666,22 @@ static HANDLE select_ws_wait(HANDLE handle, HANDLE event)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return thread;
 | 
					  return thread;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					struct select_ws_data {
 | 
				
			||||||
 | 
					  curl_socket_t fd;      /* the original input handle   (indexed by fds) */
 | 
				
			||||||
 | 
					  curl_socket_t wsasock; /* the internal socket handle  (indexed by wsa) */
 | 
				
			||||||
 | 
					  WSAEVENT wsaevent;     /* the internal WINSOCK2 event (indexed by wsa) */
 | 
				
			||||||
 | 
					  HANDLE thread;         /* the internal threads handle (indexed by thd) */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 | 
					static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 | 
				
			||||||
                     fd_set *exceptfds, struct timeval *timeout)
 | 
					                     fd_set *exceptfds, struct timeval *timeout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  DWORD milliseconds, wait, idx;
 | 
					  DWORD milliseconds, wait, idx;
 | 
				
			||||||
  WSAEVENT wsaevent, *wsaevents;
 | 
					 | 
				
			||||||
  WSANETWORKEVENTS wsanetevents;
 | 
					  WSANETWORKEVENTS wsanetevents;
 | 
				
			||||||
  HANDLE handle, *handles, *threads;
 | 
					  struct select_ws_data *data;
 | 
				
			||||||
  curl_socket_t sock, *fdarr, *wsasocks;
 | 
					  HANDLE handle, *handles;
 | 
				
			||||||
 | 
					  curl_socket_t sock;
 | 
				
			||||||
  long networkevents;
 | 
					  long networkevents;
 | 
				
			||||||
 | 
					  WSAEVENT wsaevent;
 | 
				
			||||||
  int error, fds;
 | 
					  int error, fds;
 | 
				
			||||||
  HANDLE waitevent = NULL;
 | 
					  HANDLE waitevent = NULL;
 | 
				
			||||||
  DWORD nfd = 0, thd = 0, wsa = 0;
 | 
					  DWORD nfd = 0, thd = 0, wsa = 0;
 | 
				
			||||||
@@ -699,9 +706,9 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 | 
				
			|||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* allocate internal array for the original input handles */
 | 
					  /* allocate internal array for the internal data */
 | 
				
			||||||
  fdarr = malloc(nfds * sizeof(curl_socket_t));
 | 
					  data = malloc(nfds * sizeof(struct select_ws_data));
 | 
				
			||||||
  if(fdarr == NULL) {
 | 
					  if(data == NULL) {
 | 
				
			||||||
    errno = ENOMEM;
 | 
					    errno = ENOMEM;
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -709,40 +716,14 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 | 
				
			|||||||
  /* allocate internal array for the internal event handles */
 | 
					  /* allocate internal array for the internal event handles */
 | 
				
			||||||
  handles = malloc(nfds * sizeof(HANDLE));
 | 
					  handles = malloc(nfds * sizeof(HANDLE));
 | 
				
			||||||
  if(handles == NULL) {
 | 
					  if(handles == NULL) {
 | 
				
			||||||
    free(fdarr);
 | 
					    free(data);
 | 
				
			||||||
    errno = ENOMEM;
 | 
					    errno = ENOMEM;
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* allocate internal array for the internal threads handles */
 | 
					  /* clear internal arrays */
 | 
				
			||||||
  threads = malloc(nfds * sizeof(HANDLE));
 | 
					  memset(data, 0, nfds * sizeof(struct select_ws_data));
 | 
				
			||||||
  if(threads == NULL) {
 | 
					  memset(handles, 0, nfds * sizeof(HANDLE));
 | 
				
			||||||
    free(handles);
 | 
					 | 
				
			||||||
    free(fdarr);
 | 
					 | 
				
			||||||
    errno = ENOMEM;
 | 
					 | 
				
			||||||
    return -1;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* allocate internal array for the internal socket handles */
 | 
					 | 
				
			||||||
  wsasocks = malloc(nfds * sizeof(curl_socket_t));
 | 
					 | 
				
			||||||
  if(wsasocks == NULL) {
 | 
					 | 
				
			||||||
    free(threads);
 | 
					 | 
				
			||||||
    free(handles);
 | 
					 | 
				
			||||||
    free(fdarr);
 | 
					 | 
				
			||||||
    errno = ENOMEM;
 | 
					 | 
				
			||||||
    return -1;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* allocate internal array for the internal WINSOCK2 events */
 | 
					 | 
				
			||||||
  wsaevents = malloc(nfds * sizeof(WSAEVENT));
 | 
					 | 
				
			||||||
  if(wsaevents == NULL) {
 | 
					 | 
				
			||||||
    free(threads);
 | 
					 | 
				
			||||||
    free(wsasocks);
 | 
					 | 
				
			||||||
    free(handles);
 | 
					 | 
				
			||||||
    free(fdarr);
 | 
					 | 
				
			||||||
    errno = ENOMEM;
 | 
					 | 
				
			||||||
    return -1;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* loop over the handles in the input descriptor sets */
 | 
					  /* loop over the handles in the input descriptor sets */
 | 
				
			||||||
  for(fds = 0; fds < nfds; fds++) {
 | 
					  for(fds = 0; fds < nfds; fds++) {
 | 
				
			||||||
@@ -760,12 +741,12 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* only wait for events for which we actually care */
 | 
					    /* only wait for events for which we actually care */
 | 
				
			||||||
    if(networkevents) {
 | 
					    if(networkevents) {
 | 
				
			||||||
      fdarr[nfd] = curlx_sitosk(fds);
 | 
					      data[nfd].fd = curlx_sitosk(fds);
 | 
				
			||||||
      if(fds == fileno(stdin)) {
 | 
					      if(fds == fileno(stdin)) {
 | 
				
			||||||
        handle = GetStdHandle(STD_INPUT_HANDLE);
 | 
					        handle = GetStdHandle(STD_INPUT_HANDLE);
 | 
				
			||||||
        handle = select_ws_wait(handle, waitevent);
 | 
					        handle = select_ws_wait(handle, waitevent);
 | 
				
			||||||
        handles[nfd] = handle;
 | 
					        handles[nfd] = handle;
 | 
				
			||||||
        threads[thd] = handle;
 | 
					        data[thd].thread = handle;
 | 
				
			||||||
        thd++;
 | 
					        thd++;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else if(fds == fileno(stdout)) {
 | 
					      else if(fds == fileno(stdout)) {
 | 
				
			||||||
@@ -781,8 +762,8 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 | 
				
			|||||||
          if(error != SOCKET_ERROR) {
 | 
					          if(error != SOCKET_ERROR) {
 | 
				
			||||||
            handle = (HANDLE) wsaevent;
 | 
					            handle = (HANDLE) wsaevent;
 | 
				
			||||||
            handles[nfd] = handle;
 | 
					            handles[nfd] = handle;
 | 
				
			||||||
            wsasocks[wsa] = curlx_sitosk(fds);
 | 
					            data[wsa].wsasock = curlx_sitosk(fds);
 | 
				
			||||||
            wsaevents[wsa] = wsaevent;
 | 
					            data[wsa].wsaevent = wsaevent;
 | 
				
			||||||
            wsa++;
 | 
					            wsa++;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          else {
 | 
					          else {
 | 
				
			||||||
@@ -790,7 +771,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 | 
				
			|||||||
            handle = (HANDLE) curlx_sitosk(fds);
 | 
					            handle = (HANDLE) curlx_sitosk(fds);
 | 
				
			||||||
            handle = select_ws_wait(handle, waitevent);
 | 
					            handle = select_ws_wait(handle, waitevent);
 | 
				
			||||||
            handles[nfd] = handle;
 | 
					            handles[nfd] = handle;
 | 
				
			||||||
            threads[thd] = handle;
 | 
					            data[thd].thread = handle;
 | 
				
			||||||
            thd++;
 | 
					            thd++;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -816,7 +797,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 | 
				
			|||||||
  /* loop over the internal handles returned in the descriptors */
 | 
					  /* loop over the internal handles returned in the descriptors */
 | 
				
			||||||
  for(idx = 0; idx < nfd; idx++) {
 | 
					  for(idx = 0; idx < nfd; idx++) {
 | 
				
			||||||
    handle = handles[idx];
 | 
					    handle = handles[idx];
 | 
				
			||||||
    sock = fdarr[idx];
 | 
					    sock = data[idx].fd;
 | 
				
			||||||
    fds = curlx_sktosi(sock);
 | 
					    fds = curlx_sktosi(sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* check if the current internal handle was triggered */
 | 
					    /* check if the current internal handle was triggered */
 | 
				
			||||||
@@ -876,22 +857,19 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(idx = 0; idx < wsa; idx++) {
 | 
					  for(idx = 0; idx < wsa; idx++) {
 | 
				
			||||||
    WSAEventSelect(wsasocks[idx], NULL, 0);
 | 
					    WSAEventSelect(data[idx].wsasock, NULL, 0);
 | 
				
			||||||
    WSACloseEvent(wsaevents[idx]);
 | 
					    WSACloseEvent(data[idx].wsaevent);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(idx = 0; idx < thd; idx++) {
 | 
					  for(idx = 0; idx < thd; idx++) {
 | 
				
			||||||
    WaitForSingleObject(threads[thd], INFINITE);
 | 
					    WaitForSingleObject(data[idx].thread, INFINITE);
 | 
				
			||||||
    CloseHandle(threads[thd]);
 | 
					    CloseHandle(data[idx].thread);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CloseHandle(waitevent);
 | 
					  CloseHandle(waitevent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  free(wsaevents);
 | 
					 | 
				
			||||||
  free(wsasocks);
 | 
					 | 
				
			||||||
  free(threads);
 | 
					 | 
				
			||||||
  free(handles);
 | 
					  free(handles);
 | 
				
			||||||
  free(fdarr);
 | 
					  free(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user