dect
/
linux-2.6
Archived
13
0
Fork 0

staging: usbip: usbip_common: kill rx thread on tx thread creation error.

Signed-off-by: Himanshu Chauhan <hschauhan@nulltrace.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Himanshu Chauhan 2010-06-04 23:16:27 +05:30 committed by Greg Kroah-Hartman
parent 9341625307
commit f2102d31de
1 changed files with 33 additions and 13 deletions

View File

@ -378,47 +378,67 @@ int usbip_thread(void *param)
complete_and_exit(&ut->thread_done, 0);
}
static void stop_rx_thread(struct usbip_device *ud)
{
if (ud->tcp_rx.thread != NULL) {
send_sig(SIGKILL, ud->tcp_rx.thread, 1);
wait_for_completion(&ud->tcp_rx.thread_done);
usbip_udbg("rx_thread for ud %p has finished\n", ud);
}
}
static void stop_tx_thread(struct usbip_device *ud)
{
if (ud->tcp_tx.thread != NULL) {
send_sig(SIGKILL, ud->tcp_tx.thread, 1);
wait_for_completion(&ud->tcp_tx.thread_done);
usbip_udbg("tx_thread for ud %p has finished\n", ud);
}
}
int usbip_start_threads(struct usbip_device *ud)
{
/*
* threads are invoked per one device (per one connection).
*/
struct task_struct *th;
int err = 0;
th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip");
if (IS_ERR(th)) {
printk(KERN_WARNING
"Unable to start control thread\n");
return PTR_ERR(th);
err = PTR_ERR(th);
goto ust_exit;
}
th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip");
if (IS_ERR(th)) {
printk(KERN_WARNING
"Unable to start control thread\n");
return PTR_ERR(th);
err = PTR_ERR(th);
goto tx_thread_err;
}
/* confirm threads are starting */
wait_for_completion(&ud->tcp_rx.thread_done);
wait_for_completion(&ud->tcp_tx.thread_done);
return 0;
tx_thread_err:
stop_rx_thread(ud);
ust_exit:
return err;
}
EXPORT_SYMBOL_GPL(usbip_start_threads);
void usbip_stop_threads(struct usbip_device *ud)
{
/* kill threads related to this sdev, if v.c. exists */
if (ud->tcp_rx.thread != NULL) {
send_sig(SIGKILL, ud->tcp_rx.thread, 1);
wait_for_completion(&ud->tcp_rx.thread_done);
usbip_udbg("rx_thread for ud %p has finished\n", ud);
}
if (ud->tcp_tx.thread != NULL) {
send_sig(SIGKILL, ud->tcp_tx.thread, 1);
wait_for_completion(&ud->tcp_tx.thread_done);
usbip_udbg("tx_thread for ud %p has finished\n", ud);
}
stop_rx_thread(ud);
stop_tx_thread(ud);
}
EXPORT_SYMBOL_GPL(usbip_stop_threads);