Доброго времени суток.
Возникла не понятная мне ситуация. Суть вот в чем:
1. В первом потоке настраивается сокет на прием подключений.
2. Создается новый поток, в котором вызывается функция accept() для этого сокета. Второй поток завершается по выходу из accept().
3. В первом потоке, после создания второго, закрываем сокет и ждем завершения второго потока.
В таком варианте всё работает отлично. Если во втором потоке в нескольких местах вызвать usleep(), то тоже всё работает. Но стоит вызвать usleep() в первом потоке после создания второго, но перед закрытием сокета - второй поток не выходит из функции accept() после закрытия сокета.
Ладно, я мог бы подумать, что в работающем случае сокет закрывается до вызова accept() (да, по большей части так и происходит) и accept() не завершается при закрытии сокета, но есть нюанс.
Если не работающий вариант пошагово под отладкой пройти - всё работает. Более того если прокрутить всё без отладчика до момента, когда уже первый поток ушел в ожидание завершения второго, а второй никак не может вылезти из accept() (т.е. до момента, когда всё повесилось), а потом в любом месте поставить breakpoint - второй поток тут же вываливается из accept() и всё нормально завершается. Вот что происходит?
Да, еще:
1. Под виндой в той же ситуации всё работает абсолютно без проблем.
2. Отлаживал не чистым gdb, а из под Eclipse.
Собственно, сам код:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#define Sleep(a) (usleep(a*1000))
//Далее еще куча дефайнов для совместимости с виндой
int InitServerSocket(SOCKET *serverSocket){
//Здесь сокет настраивается для приема подключений
};
void *ThreadPro(void *arg){
SOCKADDR_IN clientAddr;
SOCKADDR_LEN clientAddrLen;
SOCKET serverSocket;
SOCKET clientSocket;
serverSocket = *(SOCKET *)arg;
clientAddrLen = sizeof(clientAddr);
printf("1\n");
while ((clientSocket = accept(serverSocket, (SOCKADDR *)&clientAddr, &clientAddrLen)) != INVALID_SOCKET){
printf("WTF?!\n");
}
printf("2\n");
Sleep(5000);
return NULL;
}
int main(void) {
SOCKET serverSocket;
pthread_t thread;
InitServerSocket(&serverSocket);
pthread_create(&thread, NULL, ThreadPro, &serverSocket);
printf("3\n");
Sleep(5000);
closesocket(serverSocket);
printf("4\n");
pthread_join(thread, NULL);
return EXIT_SUCCESS;
}