/* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU General Public License version 2. */ #include "lock_dlm.h" static inline int no_work(struct gdlm_ls *ls) { int ret; spin_lock(&ls->async_lock); ret = list_empty(&ls->submit); spin_unlock(&ls->async_lock); return ret; } static int gdlm_thread(void *data) { struct gdlm_ls *ls = (struct gdlm_ls *) data; struct gdlm_lock *lp = NULL; while (!kthread_should_stop()) { wait_event_interruptible(ls->thread_wait, !no_work(ls) || kthread_should_stop()); spin_lock(&ls->async_lock); if (!list_empty(&ls->submit)) { lp = list_entry(ls->submit.next, struct gdlm_lock, delay_list); list_del_init(&lp->delay_list); spin_unlock(&ls->async_lock); gdlm_do_lock(lp); spin_lock(&ls->async_lock); } spin_unlock(&ls->async_lock); } return 0; } int gdlm_init_threads(struct gdlm_ls *ls) { struct task_struct *p; int error; p = kthread_run(gdlm_thread, ls, "lock_dlm"); error = IS_ERR(p); if (error) { log_error("can't start lock_dlm thread %d", error); return error; } ls->thread = p; return 0; } void gdlm_release_threads(struct gdlm_ls *ls) { kthread_stop(ls->thread); }