if (!task->tk_action) 
if (task->tk_action != NULL) { lock_kernel(); task->tk_action(task); unlock_kernel(); } else if (__rpc_do_exit(task)) 
static int __rpc_execute(struct rpc_task *task){	int		status = 0;	dprintk("RPC: %4d rpc_execute flgs %x\n",				task->tk_pid, task->tk_flags);	BUG_ON(RPC_IS_QUEUED(task)); restarted:	while (1) {		/*		 * Garbage collection of pending timers...		 */		rpc_delete_timer(task);		/*		 * Execute any pending callback.		 */		if (RPC_DO_CALLBACK(task)) {			/* Define a callback save pointer */			void (*save_callback)(struct rpc_task *);				/* 			 * If a callback exists, save it, reset it,			 * call it.			 * The save is needed to stop from resetting			 * another callback set within the callback handler			 * - Dave			 */			save_callback=task->tk_callback;			task->tk_callback=NULL;			lock_kernel();			save_callback(task);			unlock_kernel();		}		/*		 * Perform the next FSM step.		 * tk_action may be NULL when the task has been killed		 * by someone else.		 */		if (!RPC_IS_QUEUED(task)) {			if (!task->tk_action)				break;			lock_kernel();			task->tk_action(task);			unlock_kernel();		}		/*		 * Lockless check for whether task is sleeping or not.		 */		if (!RPC_IS_QUEUED(task))			continue;		rpc_clear_running(task);		if (RPC_IS_ASYNC(task)) {			/* Careful! we may have raced... */			if (RPC_IS_QUEUED(task))				return 0;			if (rpc_test_and_set_running(task))				return 0;			continue;		}		/* sync task: sleep here */		dprintk("RPC: %4d sync task going to sleep\n", task->tk_pid);		if (RPC_TASK_UNINTERRUPTIBLE(task)) {			__wait_event(task->u.tk_wait.waitq, !RPC_IS_QUEUED(task));		} else {			__wait_event_interruptible(task->u.tk_wait.waitq, !RPC_IS_QUEUED(task), status);			/*			 * When a sync task receives a signal, it exits with			 * -ERESTARTSYS. In order to catch any callbacks that			 * clean up after sleeping on some queue, we don't			 * break the loop here, but go around once more.			 */			if (status == -ERESTARTSYS) {				dprintk("RPC: %4d got signal\n", task->tk_pid);				task->tk_flags |= RPC_TASK_KILLED;				rpc_exit(task, -ERESTARTSYS);				rpc_wake_up_task(task);			}		}		rpc_set_running(task);		dprintk("RPC: %4d sync task resuming\n", task->tk_pid);	}	if (task->tk_exit) {		lock_kernel();		task->tk_exit(task);		unlock_kernel();		/* If tk_action is non-null, the user wants us to restart */		if (task->tk_action) {			if (!RPC_ASSASSINATED(task)) {				/* Release RPC slot and buffer memory */				if (task->tk_rqstp)					xprt_release(task);				rpc_free(task);				goto restarted;			}			printk(KERN_ERR "RPC: dead task tries to walk away.\n");		}	}	dprintk("RPC: %4d exit() = %d\n", task->tk_pid, task->tk_status);	status = task->tk_status;	/* Release all resources associated with the task */	rpc_release_task(task);	return status;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/d05fdb0cec75415b2d9eb95748386e67414e49c3/sched.c/buggy/net/sunrpc/sched.c