From: Thomas Stalder <cygwinml@gmail.com>
To: cygwin@cygwin.com
Subject: Re: poll function don't release all windows handle / possible memory leak
Date: Wed, 20 Apr 2011 13:22:00 -0000 [thread overview]
Message-ID: <BANLkTi=mkaq2tBp-BO7MzM_Cvc05si4Dmw@mail.gmail.com> (raw)
In-Reply-To: <20110418155405.GG25815@calimero.vinschen.de>
[-- Attachment #1: Type: text/plain, Size: 1467 bytes --]
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
>
>
[-- Attachment #2: server.c --]
[-- Type: text/x-csrc, Size: 5965 bytes --]
#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;
}
[-- Attachment #3: client.c --]
[-- Type: text/x-csrc, Size: 967 bytes --]
#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;
}
[-- Attachment #4: Type: text/plain, Size: 218 bytes --]
--
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
next prev parent reply other threads:[~2011-04-20 11:59 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <BANLkTi=GgZfG_QwAWtyqAYQeqOwEbcSFLw@mail.gmail.com>
2011-04-18 10:31 ` Thomas Stalder
2011-04-18 19:14 ` Corinna Vinschen
2011-04-20 13:22 ` Thomas Stalder [this message]
2011-04-21 17:39 ` Corinna Vinschen
2011-04-21 17:54 ` Thomas Stalder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='BANLkTi=mkaq2tBp-BO7MzM_Cvc05si4Dmw@mail.gmail.com' \
--to=cygwinml@gmail.com \
--cc=cygwin@cygwin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).