kern/97921: close() socket deadlocks blocked threads
Kurt Miller
lists at intricatesoftware.com
Thu May 25 17:40:44 UTC 2006
>Number: 97921
>Category: kern
>Synopsis: close() socket deadlocks blocked threads
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu May 25 17:40:17 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Kurt Miller
>Release: 6.1-release
>Organization:
Intricate Software
>Environment:
FreeBSD freebsd6-1.zonesville.com 6.1-RELEASE FreeBSD 6.1-RELEASE #0: Sun May 7 04:42:56 UTC 2006 root at opus.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP i386
>Description:
When a thread is blocked waiting for data on a socket and another thread closes the socket, the blocked thread remains blocked indefinitely. Both kse and thr have this issue. c_r returns with -1 errno==EBADF. Solaris
returns with -1 errno==0.
I originally posted this on the freebsd-threads list. Daniel Eischen replied indicating this is not a thread library issue.
>How-To-Repeat:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/param.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
static void *
start_routine(void *arg)
{
int sock1 = (int)arg;
struct sockaddr remote_addr;
char readBuf;
int n, remote_addr_len = sizeof(struct sockaddr);
n = recvfrom(sock1, &readBuf, 1, 0, &remote_addr, &remote_addr_len);
if (n == -1) {
printf("unblocked with errno = %d\n", errno);
}
return (0);
}
void
buildAddr4(struct sockaddr_in *addr4, int address, short port) {
memset((char *) addr4, 0, sizeof(struct sockaddr_in));
addr4->sin_port = htons(port);
addr4->sin_addr.s_addr = (uint32_t) htonl(address);
addr4->sin_family = AF_INET;
}
int
main() {
int sock1;
struct sockaddr addr;
pthread_t thread1;
void *value_ptr;
buildAddr4((struct sockaddr_in *)&addr, 0, 0);
if ((sock1 = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
exit(1);
if (bind(sock1, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0)
exit(1);
pthread_create(&thread1, NULL, start_routine, (void *)sock1);
sleep(1);
close(sock1);
pthread_join(thread1, &value_ptr);
return (0);
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list