/** * lttng_metadata_ring_buffer_poll - LTTng ring buffer poll file operation * @filp: the file * @wait: poll table * * Handles the poll operations for the metadata channels. */ static unsigned int lttng_metadata_ring_buffer_poll(struct file *filp, poll_table *wait) { struct lttng_metadata_stream *stream = filp->private_data; struct lib_ring_buffer *buf = stream->priv; int finalized; unsigned int mask = 0; if (filp->f_mode & FMODE_READ) { poll_wait_set_exclusive(wait); poll_wait(filp, &stream->read_wait, wait); finalized = stream->finalized; /* * lib_ring_buffer_is_finalized() contains a smp_rmb() * ordering finalized load before offsets loads. */ WARN_ON(atomic_long_read(&buf->active_readers) != 1); if (finalized) mask |= POLLHUP; mutex_lock(&stream->metadata_cache->lock); if (stream->metadata_cache->metadata_written > stream->metadata_out) mask |= POLLIN; mutex_unlock(&stream->metadata_cache->lock); } return mask; }
unsigned int lib_ring_buffer_poll(struct file *filp, poll_table *wait, struct lib_ring_buffer *buf) { unsigned int mask = 0; struct channel *chan = buf->backend.chan; const struct lib_ring_buffer_config *config = &chan->backend.config; int finalized, disabled; if (filp->f_mode & FMODE_READ) { poll_wait_set_exclusive(wait); poll_wait(filp, &buf->read_wait, wait); finalized = lib_ring_buffer_is_finalized(config, buf); disabled = lib_ring_buffer_channel_is_disabled(chan); /* * lib_ring_buffer_is_finalized() contains a smp_rmb() ordering * finalized load before offsets loads. */ WARN_ON(atomic_long_read(&buf->active_readers) != 1); retry: if (disabled) return POLLERR; if (subbuf_trunc(lib_ring_buffer_get_offset(config, buf), chan) - subbuf_trunc(lib_ring_buffer_get_consumed(config, buf), chan) == 0) { if (finalized) return POLLHUP; else { /* * The memory barriers * __wait_event()/wake_up_interruptible() take * care of "raw_spin_is_locked" memory ordering. */ if (raw_spin_is_locked(&buf->raw_tick_nohz_spinlock)) goto retry; else return 0; } } else { if (subbuf_trunc(lib_ring_buffer_get_offset(config, buf), chan) - subbuf_trunc(lib_ring_buffer_get_consumed(config, buf), chan) >= chan->backend.buf_size) return POLLPRI | POLLRDBAND; else return POLLIN | POLLRDNORM; } } return mask; }
/** * lttng_channel_poll - lttng stream addition/removal monitoring * * @file: the file * @wait: poll table */ unsigned int lttng_channel_poll(struct file *file, poll_table *wait) { struct lttng_channel *channel = file->private_data; unsigned int mask = 0; if (file->f_mode & FMODE_READ) { poll_wait_set_exclusive(wait); poll_wait(file, channel->ops->get_hp_wait_queue(channel->chan), wait); if (channel->ops->is_disabled(channel->chan)) return POLLERR; if (channel->ops->is_finalized(channel->chan)) return POLLHUP; if (channel->ops->buffer_has_read_closed_stream(channel->chan)) return POLLIN | POLLRDNORM; return 0; } return mask; }