bug-glibc
[Top][All Lists]
Advanced

[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;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]