int pipe_release(struct inode *inode, struct file *file) { struct pipe_private *pipe = file->f_private; if (file == pipe->read_end) { pipe->read_end = NULL; wake_all(&pipe->write_wait, 0); } if (file == pipe->write_end) { pipe->write_end = NULL; wake_all(&pipe->read_wait, 0); } if (!pipe->read_end && !pipe->write_end) slab_free(pipe_cachep, pipe); return 0; }
ssize_t pipe_read(struct file *file, char *dst, size_t len, unsigned long *pos) { ssize_t nr_bytes; struct pipe_private *pipe = file->f_private; while (!(nr_bytes = flexbuf_dequeue(pipe->buf, dst, len))) { // pipe is empty if (!pipe->write_end) return 0; // no writers: EOF if (file->f_flags & O_NONBLOCK) return -EAGAIN; if (wait_interruptible(&pipe->read_wait)) return -EINTR; } wake_all(&pipe->write_wait, 0); return nr_bytes; }
/* * Write @len bytes to @pipe atomically with respect to other writers. */ static ssize_t pipe_do_write(struct pipe_private *pipe, const char *src, size_t len) { size_t nr_bytes = 0; while (1) { // write as much as we can size_t this_len = MIN(len-nr_bytes, pipe_headroom(pipe)); size_t this_bytes = flexbuf_enqueue(&pipe->buf, src+nr_bytes, this_len); if (this_bytes) wake_all(&pipe->read_wait, 0); // termination condition in the middle of the loop... nr_bytes += this_bytes; if (nr_bytes == len) break; if (wait_interruptible(&pipe->write_wait)) return nr_bytes ? (ssize_t)nr_bytes : -EINTR; } return nr_bytes; }
void keyboard_handler(struct regs *r) { (void)r; /* prevent 'unused parameter' warning */ /* read from keyboard data register */ uint8_t data = inportb(KBD_DATA_REG); uint8_t scancode = data & 0x7F; if (data & 0x80) { /* key released */ if (scancode == 1) { toggle_caps_lock_light(); } } else { /* key pressed, add it to keycode queue and wake up * all threads waiting on the keycode thread queue */ uint16_t keycode = kdbus[scancode]; enqueue_keycode(keycode); /* wake all threads waiting for keyboard presses */ wake_all(&keycode_wait_queue); } }
// A function responsible for de-initialising the variable. inline void ConditionVariable::_deinitialise() { wake_all(); };