linux-sg2042/fs/gfs2/locking/dlm/thread.c

69 lines
1.4 KiB
C

/*
* 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);
}