Hello, Thanks for the fix.
I have made some tests with the CVS version and I don't have anymore not closed Handle, but I still have a memory leaks. I have made 2 testcases : $ gcc server.c -o server $ gcc server.c -Dnoleak -o servernoleak $ gcc client.c -o client I execute sever.exe and client.exe after 1 minute I have 2992Ko memory used by server.exe (see http://www.netsolux.ch/cyg/5.gif) after about 10 minutes I have 5156Ko memory used by server.exe (see http://www.netsolux.ch/cyg/6.gif) If I execute severnoleak.exe and client.exe I dont have memory leak. The memory leak seem to be in the poll (select) function. Regards, Thomas 2011/4/18 Corinna Vinschen > On Apr 18 11:35, Thomas Stalder wrote: >> Hello, >> >> I have found that poll function don't release all windows handle (with >> network socket) and generate memory leak. > > That's actually a pthread problem in conjunction with select (poll only > calls select under the hood). I applied a fix to CVS. Thanks for the > testcase! > > > Corinna > > -- > Corinna Vinschen Please, send mails regarding Cygwin to > Cygwin Project Co-Leader cygwin AT cygwin DOT com > Red Hat > > -- > Problem reports: http://cygwin.com/problems.html > FAQ: http://cygwin.com/faq/ > Documentation: http://cygwin.com/docs.html > Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple > >
#include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <arpa/inet.h> #include <netdb.h> #include <sys/un.h> #include <errno.h> #include <unistd.h> #include <pthread.h> #include <fcntl.h> #include <poll.h> #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #define port 8082 #define REQUIRED_STACK_SIZE 200*1024 #define OK 0 #define NOT_OK (!OK) pthread_mutex_t mutex_log = PTHREAD_MUTEX_INITIALIZER; int logger(const char *file, const char *function, int line, const char *fmt, ...) { va_list arglist; pthread_mutex_lock(&mutex_log); fprintf(stderr, "%s (%s) - line %04d : ", file, function, line); va_start(arglist, fmt); vfprintf(stderr, fmt, arglist); va_end(arglist); fprintf(stderr, "\n"); pthread_mutex_unlock(&mutex_log); return 0; } #define _log(fmt, ...) logger(__FILE__, (char *)__FUNCTION__, __LINE__, fmt, ## __VA_ARGS__) int close_socket_fd(int fd) { int rc; if(fd < 0) return OK; rc = shutdown(fd, SHUT_RDWR); rc = close(fd); if(rc) { _log("close %d : %s", fd, strerror(errno)); } return OK; } static void *serverthread(void *parm) { struct pollfd pfd; char buff; int fd = (int)parm; int rc; #ifdef noleak sleep(3); rc = 1; #else pfd.fd = fd; pfd.events = POLLIN | POLLPRI; pfd.revents = 0; rc = poll(&pfd, 1, 3000); #endif if (rc == 1) { _log("ICI %d", fd); rc = read(fd, &buff, 1); _log("read %d bytes", rc); } close_socket_fd(fd); pthread_exit(0); return NULL; } int create_thread(pthread_t * thread, void * thread_func, void * arg, unsigned char must_detach) { int err = OK; pthread_attr_t attr; pthread_t null_thread; /* Initialize the attribute */ err = pthread_attr_init(&attr); if(err) { _log("pthread_attr_init err=%d: %s", err, strerror(errno)); return NOT_OK; } err = pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); if(err) { _log("pthread_attr_setinheritsched: %s", strerror(errno)); pthread_attr_destroy(&attr); return NOT_OK; } err = pthread_attr_setstacksize(&attr, REQUIRED_STACK_SIZE); if(err) { _log("pthread_attr_setstacksize: %s", strerror(errno)); pthread_attr_destroy(&attr); return NOT_OK; } if(must_detach) { err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if(err) { _log("pthread_attr_setdetachstate: %s", strerror(errno)); pthread_attr_destroy(&attr); return NOT_OK; } } /* Create the thread with our attribute */ err = pthread_create((thread != NULL) ? (thread) : (&null_thread), &attr, thread_func, arg); if(err) { _log("pthread_create: %s", strerror(errno)); pthread_attr_destroy(&attr); return (err); } pthread_attr_destroy(&attr); return OK; } int main(void) { struct sockaddr_in addr; int new_sock, on; struct pollfd pfd; int fd; socklen_t addrlen; int ret, rc; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; memset(&(addr.sin_zero), '\0', 8); fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(fd < 0) { _log("socket : %s", strerror(errno)); return NOT_OK; } else { _log("Socket OK"); } on = 1; ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if(ret < 0) { _log("setsockopt : %s", strerror(errno)); } ret = -1; while(ret < 0) { ret = bind(fd, (struct sockaddr *) & addr, sizeof(struct sockaddr_in)); if(ret < 0) { _log("bind : %s", strerror(errno)); sleep(1); // close_socket(listen_socket); } else { _log("Bind OK on port %d", port); } } ret = listen(fd, 1); if(ret != 0) { _log("listen : %s", strerror(errno)); close_socket_fd(fd); return NOT_OK; } else { _log("Listen OK on port %d", port); } while(1) { addrlen = sizeof(struct sockaddr_in); pfd.fd = fd; pfd.events = POLLIN | POLLPRI; pfd.revents = 0; rc = poll(&pfd, 1, 2000); if(rc == -1) { _log("poll : %s", strerror(errno)); sleep(1); continue; } if(pfd.revents == 0) { continue; } new_sock = accept(fd, (struct sockaddr *) & addr, &addrlen); if(new_sock < 0) { _log("accept : %s", strerror(errno)); close_socket_fd(new_sock); } else { struct linger linger; int option; struct timeval wait_timeout; _log("The client %s are connected", inet_ntoa(addr.sin_addr)); ret = create_thread(NULL, serverthread, (void *) new_sock, 1); if(ret < 0) { _log("Impossible de demarrer le thread client sur le port %d", port); close_socket_fd(new_sock); } } } return NOT_OK; }
#include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <arpa/inet.h> #include <netdb.h> #include <sys/un.h> #include <errno.h> #include <unistd.h> #include <pthread.h> #include <fcntl.h> #include <poll.h> #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #define port 8082 #define OK 0 #define NOT_OK (!OK) int main(void) { struct sockaddr_in addr; int sock; socklen_t addrlen; struct hostent *h; int ret; start: memset((char *)&addr, '0', sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); h = gethostbyname("127.0.0.1"); memcpy((char *) & (addr.sin_addr), h->h_addr, h->h_length); sock = socket(AF_INET, SOCK_STREAM, 0); ret = connect(sock, (struct sockaddr *) & addr, sizeof(struct sockaddr_in)); if (ret == 0) { write(sock, "a", 1); } close(sock); goto start; }
-- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple