The helper function that the other person suggested isn't needed at all:
static int list_is_not_empty()
{
int rv = 1;
mutex_lock(request_list_mutex);
rv = !list_empty(request_list);
mutex_unlock(request_list_mutex);
return rv;
}
There's no need to lock the list just to see if it's empty or not. So simply:
static void wait_and_consume_request()
{
wait_event(request_list_post_wq, !list_empty(request_list));
mutex_lock(request_list_mutex);
if(!list_empty(request_list)) {
// do something with request
}
mutex_unlock(request_list_mutex);
}
But this won't guarantee that you actually consume a request. If we do want to ensure that we consume exactly one request, then:
static void wait_and_consume_request()
{
mutex_lock(request_list_mutex);
while(list_empty(request_list)) {
mutex_unlock(request_list_mutex);
wait_event(request_list_post_wq, !list_empty());
lock_mutex();
}
// do something with request
mutex_unlock(request_list_mutex);
}
Here's a real example from the kernel in drivers/misc/carma/carma-fpga.c (I just took the first example that I could see)
spin_lock_irq(&priv->lock);
/* Block until there is at least one buffer on the used list */
while (list_empty(used)) {
spin_unlock_irq(&priv->lock);
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
ret = wait_event_interruptible(priv->wait, !list_empty(used));
if (ret)
return ret;
spin_lock_irq(&priv->lock);
}
/* Grab the first buffer off of the used list */
dbuf = list_first_entry(used, struct data_buf, entry);
list_del_init(&dbuf->entry);
spin_unlock_irq(&priv->lock);