#include "poll.h"
-unsigned int poll_max_size;
+
+/*
+ * Maximum number of fd we can monitor.
+ *
+ * For poll(2), the max fds must not exceed RLIMIT_NOFILE given by
+ * getrlimit(2).
+ */
+static unsigned int poll_max_size;
/*
* Resize the epoll events structure of the new size.
/*
* Create pollfd data structure.
*/
+LTTNG_HIDDEN
int compat_poll_create(struct lttng_poll_event *events, int size)
{
struct compat_poll_event_array *current, *wait;
/*
* Add fd to pollfd data structure with requested events.
*/
+LTTNG_HIDDEN
int compat_poll_add(struct lttng_poll_event *events, int fd,
uint32_t req_events)
{
/*
* Modify an fd's events..
*/
+LTTNG_HIDDEN
int compat_poll_mod(struct lttng_poll_event *events, int fd,
uint32_t req_events)
{
/*
* Remove a fd from the pollfd structure.
*/
+LTTNG_HIDDEN
int compat_poll_del(struct lttng_poll_event *events, int fd)
{
int i, count = 0, ret;
/*
* Wait on poll() with timeout. Blocking call.
*/
+LTTNG_HIDDEN
int compat_poll_wait(struct lttng_poll_event *events, int timeout,
bool interruptible)
{
int ret, active_fd_count;
- int idle_pfd_index = 0;
- size_t i;
+ size_t pos = 0, consecutive_entries = 0, non_idle_pos;
if (events == NULL || events->current.events == NULL) {
ERR("poll wait arguments error");
active_fd_count = ret;
/*
- * Swap all active pollfd structs to the beginning of the
- * array to emulate compat-epoll behaviour. This algorithm takes
- * advantage of poll's returned value and the burst nature of active
- * events on the file descriptors. The while loop guarantees that
- * idle_pfd will always point to an idle fd.
+ * Move all active pollfd structs to the beginning of the
+ * array to emulate compat-epoll behaviour.
*/
if (active_fd_count == events->wait.nb_fd) {
goto end;
}
- while (idle_pfd_index < active_fd_count &&
- events->wait.events[idle_pfd_index].revents != 0) {
- idle_pfd_index++;
- }
- for (i = idle_pfd_index + 1; idle_pfd_index < active_fd_count;
- i++) {
- struct pollfd swap_pfd;
- struct pollfd *idle_pfd = &events->wait.events[idle_pfd_index];
- struct pollfd *current_pfd = &events->wait.events[i];
-
- if (idle_pfd->revents != 0) {
- swap_pfd = *current_pfd;
- *current_pfd = *idle_pfd;
- *idle_pfd = swap_pfd;
- idle_pfd_index++;
+ while (consecutive_entries != active_fd_count) {
+ struct pollfd *current = &events->wait.events[pos];
+ struct pollfd idle_entry;
+
+ if (current->revents != 0) {
+ consecutive_entries++;
+ pos++;
+ continue;
}
- }
+ non_idle_pos = pos;
+
+ /* Look for next non-idle entry. */
+ while (events->wait.events[++non_idle_pos].revents == 0);
+
+ /* Swap idle and non-idle entries. */
+ idle_entry = *current;
+ *current = events->wait.events[non_idle_pos];
+ events->wait.events[non_idle_pos] = idle_entry;
+
+ consecutive_entries++;
+ pos++;
+ }
end:
return ret;
/*
* Setup poll set maximum size.
*/
+LTTNG_HIDDEN
int compat_poll_set_max_size(void)
{
int ret, retval = 0;