----- 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