Reputation: 15
I have a server that accepts clients. I'm doing some multi-threading, and when I create a thread, I pass the socketfd as an argument. The accept fails because the sockFd it takes is zero. However I can't figure out why this would be the case. The sockfd is valid for the take_client function, and it has been set up correctly. I just included this section of my code because I'm certain the issue is here.
void* thread_func(void* pSockfd) {
int sockFd;
sockFd = *(int*)pSockfd;
printf("sockFD = %d\n", sockFd); //returns zero
struct sockaddr_in sockAddr;
socklen_t sockAddrSize;
sockAddrSize = sizeof(struct sockaddr_in);
accept(sockFd, (struct sockaddr*) &sockAddr, &sockAddrSize);
return 0;
}
void take_client(int sock) { //when called, 'sock' is a valid number > 0
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, (void*)&sock);
}
If anything stands out that might be an issue, I'd be really grateful to hear. Thanks!
Upvotes: 0
Views: 521
Reputation: 4732
there is a race condition in you code, it may look ok "sometimes":
void take_client(int sock) { //sock live on stack here
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, (void*)&sock);
// you pass the stack address of sock to your thread
}
The address you pass must remain valid when thread is running, thus either you can afford that(it is kind of "global" somewhere), either you need to allocate a new buffer and pass it to the thread.
Sometime you will see code casting sock value to void* ( (void*)sock) and casting back the pointer to an int in the thread.
This may work, but I think allocating a new buffer is better for readability, and gives a clear ownership of who is responsible for this buffer (having a shared 'sock' between threads would need locking to be perfectly safe).
Moreover, usually, you end up with the need of passing many more info to the thread, thus already having a buffer ease the evolution of your code.
Upvotes: 3
Reputation: 517
check out the man page for socket return value: "On success, a file descriptor for the new socket is returned. On error, -1 is returned, and errno is set appropriately." So a zero return value is valid. unless I didn't understand the issue you have.
Upvotes: 0