void copy_from_disk_queue_to_memory_queue(auto_drainer_t::lock_t keepalive) {
     try {
         while (!keepalive.get_drain_signal()->is_pulsed()) {
             if (disk_queue->empty()) {
                 if (items_in_queue != memory_queue.size()) {
                     // There is a push in progress, there's no good way to wait on it, so we'll start a new coroutine later
                     restart_copy_coro = true;
                 } else {
                     disk_queue.reset();
                 }
                 break;
             }
             T value;
             disk_queue->pop(&value);
             if (memory_queue.full()) {
                 guarantee(notify_when_room_in_memory_queue == NULL);
                 cond_t cond;
                 assignment_sentry_t<cond_t *> assignment_sentry(&notify_when_room_in_memory_queue, &cond);
                 wait_interruptible(&cond, keepalive.get_drain_signal());
             }
             memory_queue.push_back(value);
             available_control.set_available(true);
         }
     } catch (const interrupted_exc_t &) {
         /* ignore */
     }
 }
 void copy_from_disk_queue_to_memory_queue(auto_drainer_t::lock_t keepalive) {
     try {
         while (!keepalive.get_drain_signal()->is_pulsed()) {
             if (disk_queue->empty()) {
                 if (items_in_queue != memory_queue.size()) {
                     // There is a push in progress, there's no good way to wait on
                     // it, so we'll start a new coroutine later
                     restart_copy_coro = true;
                 } else {
                     disk_queue.reset();
                 }
                 break;
             }
             write_message_t wm;
             copying_viewer_t viewer(&wm);
             disk_queue->pop(&viewer);
             if (memory_queue_free_space <= 0) {
                 guarantee(notify_when_room_in_memory_queue == nullptr);
                 cond_t cond;
                 assignment_sentry_t<cond_t *> assignment_sentry(
                     &notify_when_room_in_memory_queue, &cond);
                 wait_interruptible(&cond, keepalive.get_drain_signal());
             }
             memory_queue_free_space -= wm.size();
             memory_queue.emplace_back(std::move(wm));
             available_control.set_available(true);
         }
     } catch (const interrupted_exc_t &) {
         /* ignore */
     }
 }
示例#3
0
 /* The purpose of `random_delay()` is to mix things up a bit to increase the
 likelihood of exposing a bug in `artificial_table_t`. */
 void random_delay(signal_t *interruptor) {
     if (randint(2) == 0) {
         signal_timer_t timer;
         timer.start(randint(100));
         wait_interruptible(&timer, interruptor);
     }
 }
示例#4
0
文件: rw_block.c 项目: drewt/Telos
/*
 * Wait until a buffer is unlocked.
 */
void buffer_wait(struct buffer *buf)
{
	while (buf->b_lock) {
		wait_interruptible(&buf->b_wait);
		// TODO: handle signals
	}
}
示例#5
0
文件: pipe.c 项目: drewt/Telos
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;
}
示例#6
0
文件: pipe.c 项目: drewt/Telos
/*
 * 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;
}