Re: Sock_recvmsg() blocks and is not killable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Title: Sock_recvmsg() blocks and is not killable
I'm not the kernel programmer but in user mode I've solved this issue by closing the socket. May be that can work for you.
 
Just a thought..
 
Thanks,
Gurmit
----- Original Message -----
Sent: Tuesday, January 24, 2006 7:25 PM
Subject: Sock_recvmsg() blocks and is not killable

Hi,

I had started a kernel thread which is supposed to listen to a particular UDP port. Now when I try to kill the thread, the thread keeps waiting on the recv call.

What is a clean way of killing the thread. I cannot make the recv function unblocking as I have rather too few packets coming on the port and the processing is done on an embedded platform. Non blocking recv call would rather eat up power and increase the CPU utilization.


/* Receive Call */
UWORD32 recv(struct socket * sockfd, UWORD8 * data, UWORD32 size,
             UWORD32 flags)
{

    struct msghdr msg;
    struct iovec iov;
    mm_segment_t oldfs;
    struct sockaddr_in  sin;
    UWORD32 len = 0;

    msg.msg_name = &sin;
    msg.msg_namelen = sizeof(struct sockaddr_in);
    iov.iov_base = data;
    iov.iov_len = size;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    msg.msg_flags = flags;

    oldfs = get_fs();
    set_fs(KERNEL_DS);
    len = sock_recvmsg(sockfd, &msg, iov.iov_len, 0);

    /* If the size is more than zero, check for the source address */
    /* It should be same as the server address                     */
    if(len > 0)
    {
         if(serveraddr.sin_addr.s_addr != sin.sin_addr.s_addr)
         {
             len = 0;
         }
    }
    set_fs(oldfs);
    return len;
}


WORD32 rthreadd(void * arg)
{
    UWORD32 len = 0;
    UWORD8  >
    UWORD8  *data_buff   = NULL;
    UWORD16 rx_buff_size = 1500;

    /* Deamonize and unmask the signkill for this thread */
    _daemonize("Threadd");
    allow_signal(SIGKILL);

    /* This buffer will be used to recieve the incoming packets */
    data_buff = kmalloc(rx_buff_size, 0);

    if(data_buff == NULL)
    {
        >
    }

    /* Receive the packet on the port                                  */
    /* If the packet is received, process the packet in the FSM */
    while(one)
    {
        len = 0;

        /* Waits for a packet, once a packet has been received, process it */
        while(len <= 0)
        {
              len = recv(g_socket, data_buff, rx_buff_size, 0);
        }
       
        if(get_pending_signal(current))
        {
            break;
        }
        /* Process the received packet */
        process_host_rx(data_buff, len);
    }

    /* Free the data buffer */
    kfree(data_buff);
   sock_release(g_socket);
    return 0;
}

Init_thread()
{
    g_pid = -1;

    /* Create the socket for the radius client */
    error = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &g_socket);
    if (error < 0)
    {
        return BFALSE;
    }
    g_socket->sk->sk_allocation = GFP_ATOMIC;

    error = (*g_socket->ops->bind)(g_socket,
            (struct sockaddr *)&clientaddr, sizeof(clientaddr));
    if (error < 0)
    {
        return BFALSE;
    }

    /* Start the kernet thread */
    g_pid = kernel_thread(radiusd, 0, CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
    if (g_pid < 0)
    {
        return BFALSE;
    }

    return BTRUE;
}

void stop_client(void)
{
If(g_pid != -1)
{
Killproc(g_pid, SIGKILL, 1);
}
}
 

Regards,
Jitesh Shah                                                              T8056601107
Bangalore-560025


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux