Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does pthread_cancel works if the thread is running blocking code like accept connection?

Tags:

c

I am beginner to C programming I created a new thread and its working fine ,my thread blocks the code at accept.Does calling pthread_cancel from outside terminates the thread.Or do I need to close the socket from outside.

Inside thread code it is a blocking code

 while( (clientfd = accept(socketfd, (struct sockaddr *)&client,&clilen)) )
        {
                printf("New Client connected");
                ......
        }

Calling pthread_cancel from outside

pthread_cancel(thread_id);

What happens?

like image 793
priwiljay Avatar asked Mar 24 '16 07:03

priwiljay


2 Answers

About the socket resource, you have to clen it up manually, because the thread cancellation will not close your resources.

You could use a cleanup_handler to do that you should look at pthread_cleanup_push() and void pthread_cleanup_pop.

A short example could be:

void cleanup_handler(void *arg )
{
   printf("cleanup \n");
   // close your socket
}

void *execute_on_thread(void *arg)
{
    pthread_cleanup_push(cleanup_handler, NULL);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

    while(1)
    {
        sleep(1);
        printf("Running\n");
        //thread stuff
    }

    pthread_cleanup_pop(1);

    return (void *) 0;
}

int main( )
{
    pthread_t tid;
    pthread_create(&tid,NULL,execute_on_thread,NULL);

    sleep(2);

    if (!pthread_cancel(tid))
    {
        pthread_join(tid, NULL);
    }
    else
    {
        perror("pthread_cancel");
    }

    return 0;
}
like image 128
LPs Avatar answered Dec 15 '22 18:12

LPs


According to open standard 2.9.5 section thread can be canceled at any of cancellation points. Cancellation point will occur if thread is calling accept function. So, you are good to go.

The socket won't be closed automatically. Only connection accepting will be canceled. Note, that port is still held by socket because the result of bind was not canceled. So, you still need to close your socket by close.

By default the tcp port won't be returned to OS immanently after socket is closed. If you want the socket to return the port right after it is closed add this lines after socket creation.

int flag = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int));
like image 22
ivaigult Avatar answered Dec 15 '22 16:12

ivaigult