static ssize_t my_read(struct file *filp, char __user *buf, size_t count, loff_t *off) { ssize_t ret; mutex_lock(&my_lock); int len = strlen(str); mutex_unlock(&my_lock); if (*off < len || len == 0) { // ret = wait_event_interruptible_exclusive(my_wait, condition() > 5); if (!(condition())) { do { DEFINE_WAIT(__wait); \ for (;;) { prepare_to_wait_exclusive(&my_wait, &__wait, TASK_INTERRUPTIBLE); if (condition()) { finish_wait(&my_wait, &__wait); break; } if (!signal_pending(current)) { schedule(); continue; } ret = -ERESTARTSYS; abort_exclusive_wait(&my_wait, &__wait, TASK_INTERRUPTIBLE, NULL); break; } } while (0); } if (ret < 0) { return ret; } } mutex_lock(&my_lock); ret = simple_read_from_buffer(buf, count, off, str, strlen(str)); mutex_unlock(&my_lock); return ret; }
int __sched __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, int (*action)(void *), unsigned mode) { do { int ret; prepare_to_wait_exclusive(wq, &q->wait, mode); if (!test_bit(q->key.bit_nr, q->key.flags)) continue; ret = action(q->key.flags); if (!ret) continue; abort_exclusive_wait(wq, &q->wait, mode, &q->key); return ret; } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); finish_wait(wq, &q->wait); return 0; }