[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Recv blocks forever after close
From: |
Pradip Bepari |
Subject: |
Recv blocks forever after close |
Date: |
Mon, 14 May 2001 10:58:20 +0530 |
Hi,
We have noticed that in a multithreaded program (pthread) under linux if
a thread calls close() on a socket descriptor on which some other thread
has called a recv()/recvfrom(), the later thread hang forever on the
recv().
Is it a bug or expected behavior? Can anybody explain why this is
happening?
Thanks,
Pradip & Murugan.
Below are some information useful to reproduce the problem.
We are using RedHat 7.0 (Guiness) kernel 2.2.16-22 with glibc-2.1.92-14
running on Pentium III.
A sample program is included to reproduce this problem. The program is
compiled with the following command : gcc -g -D_REENTRANT trecv.c
-lpthread
Output:
calling recv...
calling close...
socket closed!
(hits assert after 10 secs)
An observation: when the main thread hits the assert in the program, the
stack trace of the other thread looks as follows.
#0 0x40114972 in __libc_recv () from /lib/libc.so.6
#1 0x4002bf84 in recv (fd=5, buf=0xbf7ffa0c, n=256, flags=0)
at wrapsyscall.c:199
#2 0x80487f1 in test_read_from (param=0x5) at trecv.c:23
#3 0x40026a4f in pthread_start_thread_event (arg=0xbf7ffc00) at
manager.c:274
Sample Program :
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>
#include <assert.h>
#define BUF_LEN 256
#define HARD_IPADDR "205.149.182.45"
#define HARD_PORT 10000
void *test_read_from(void *param)
{
char buf[BUF_LEN + 1];
int sock_d = (int)param;
printf("calling recv...\n"); fflush(stdout);
memset(buf, '\0', sizeof(buf));
if (recv(sock_d, buf, BUF_LEN, 0) < 0) {
printf ("Error[%d] receiving data\n", errno); fflush (stdout);
return NULL;
}
printf("Received = %s\n", buf); fflush(stdout);
return NULL;
}
int main()
{
int sd;
struct sockaddr_in sin;
char buf[BUF_LEN + 1];
pthread_t sp;
socklen_t slen;
sd = socket(PF_INET, SOCK_DGRAM, 0);
if (sd < 0) {
printf ("Error opening the socket\n");
return -1;
}
sin.sin_family = AF_INET;
if (!inet_aton(HARD_IPADDR, &sin.sin_addr)) {
printf("Error obtaining the inet_aton\n");
close(sd);
return -1;
}
sin.sin_port = htons(HARD_PORT);
if (bind(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
printf ("Error binding the socket\n");
close (sd);
return -1;
}
if (pthread_create(&sp, NULL, test_read_from, (void *)sd)) {
printf ("Error creating the thread\n");
close (sd);
return -1;
}
sleep(1);
printf ("calling close...\n"); fflush(stdout);
if (close (sd) < 0) {
printf ("Error in close!\n"); fflush(stdout);
return -1;
}
printf ("socket closed!\n"); fflush (stdout);
sleep (10);
printf ("Exiting...\n");
assert(0);
return 0;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Recv blocks forever after close,
Pradip Bepari <=