Subject: pkg/17944: pth gets deadlocked and pth-syscall aborts with "SCHEDULER INTERNAL ERROR"
To: None <gnats-bugs@gnats.netbsd.org>
From: None <ChristianBiere@gmx.de>
List: netbsd-bugs
Date: 08/14/2002 18:10:29
>Number: 17944
>Category: pkg
>Synopsis: pth gets deadlocked and pth-syscall aborts with "SCHEDULER INTERNAL ERROR"
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: pkg-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Aug 14 18:11:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Christian Biere
>Release: 1.6_BETA4
>Organization:
>Environment:
NetBSD localhost 1.6_BETA4 NetBSD 1.6_BETA4 (DURON) #1: Sat Aug 10 12:09:01 CEST 2002 root@localhost:/usr/src-1-6/sys/arch/i386/compile/DURON i386
>Description:
I'm experimenting with a program which should handle many connections
using one thread per connection. If I install pkgsrc/devel/pth I get the following result:
$ ./main
Idle!
fd=256
fd=257
fd=258
fd=259
fd=260
fd=261
**Pth** SCHEDULER INTERNAL ERROR: no more thread(s) available to schedule!?!?
Abort trap
If install pkgsrc/devel/pth-syscall instead the process will hang forever after "fd=256". I use the IP 1.2.3.4 because it takes a moment until the connect() fails and I really get 256 descriptors. As you can see I set FD_SETSIZE to 2048 and I should be able to open this many descriptors or socket() should fail. I've submitted this bug to the author but it might be NetBSD-specific.
Regards,
Christian
>How-To-Repeat:
main.c:
#define FD_SETSIZE 2048
#define ADDR_IP "1.2.3.4"
#define ADDR_PORT 8000
#include <pth.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
int wait_select(int fd, time_t timeout) {
struct timeval tv = {
timeout, 0
};
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
return pth_select(fd+1, &fds, &fds, &fds, &tv);
}
static int connect_this(u_int32_t ip, u_int16_t port) {
struct sockaddr_in s_addr;
int fd = -1;
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("connect_this() failed");
goto failure;
}
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(port);
memcpy(&s_addr.sin_addr, &ip, sizeof(struct in_addr));
if ((pth_connect(fd, (struct sockaddr *)&s_addr, sizeof(s_addr))) == -1)
if (errno != EINPROGRESS) {
perror("pth_connect() failed");
goto failure;
}
return fd;
failure:
if (fd != -1)
close(fd);
return -1;
}
static void *my_thread(void *arg) {
u_int32_t ip;
int ret, fd = -1;
pth_sleep(2);
if ((ret = inet_pton(AF_INET, ADDR_IP, &ip)) != 1) {
perror( ret == -1
? "inet_pton() failed"
: "inet_pton() failed: Could not parse address '" ADDR_IP "'"
);
goto cleanup;
}
if ((fd = connect_this(ip, ADDR_PORT)) == -1)
goto cleanup;
printf("fd=%d\n", fd);
if ((ret = wait_select(fd, 5)) <= 0) {
if (ret == -1)
perror("is_writeable");
goto cleanup;
}
cleanup:
if (fd != -1)
close(fd);
return NULL;
}
void *idle_thread(void *arg) {
while(1) {
printf("Idle!\n");
pth_sleep(5);
}
return NULL;
}
int main(int argc, char *argv[]) {
int thread_counter = 0;
pth_attr_t attr;
pth_init();
attr = pth_attr_new();
pth_attr_set(attr, PTH_ATTR_STACK_SIZE, 64*1024);
pth_attr_set(attr, PTH_ATTR_JOINABLE, FALSE);
pth_attr_set(attr, PTH_ATTR_NAME, "handler");
while (thread_counter++ < 257)
if (pth_spawn(attr, &my_thread, NULL) == NULL)
perror("pth_spawn() failed");
pth_join(pth_spawn(NULL, &idle_thread, NULL), NULL);
return EXIT_SUCCESS;
}
---------------------------
Makefile:
CC = gcc
CFLAGS = -g -Wall `pth-config --cflags --all`
LDFLAGS = `pth-config --ldflags --all`
LIBS = `pth-config --libs`
all:
$(CC) $(CPPFLAGS) $(CFLAGS) -o main main.c $(LDFLAGS) $(LIBS)
clean:
rm -rf main *.core
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: