blob: 74f22ee29fec7dcb776a7999e34353e1100a8a6d [file] [log] [blame]
Jon Medhurst15ce78d2014-04-10 09:02:02 +01001/**
2 * Copyright (C) ARM Limited 2013-2014. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include "Monitor.h"
10
11#include <errno.h>
Jon Medhurst96b56152014-10-30 18:01:15 +000012#include <fcntl.h>
Jon Medhurst15ce78d2014-04-10 09:02:02 +010013#include <string.h>
14#include <unistd.h>
15
16#include "Logging.h"
17
18Monitor::Monitor() : mFd(-1) {
19}
20
21Monitor::~Monitor() {
Jon Medhurste31266f2014-08-04 15:47:44 +010022 if (mFd >= 0) {
23 ::close(mFd);
24 }
25}
26
27void Monitor::close() {
28 if (mFd >= 0) {
29 ::close(mFd);
30 mFd = -1;
Jon Medhurst15ce78d2014-04-10 09:02:02 +010031 }
32}
33
34bool Monitor::init() {
Jon Medhurst96b56152014-10-30 18:01:15 +000035#ifdef EPOLL_CLOEXEC
36 mFd = epoll_create1(EPOLL_CLOEXEC);
37#else
Jon Medhurst15ce78d2014-04-10 09:02:02 +010038 mFd = epoll_create(16);
Jon Medhurst96b56152014-10-30 18:01:15 +000039#endif
Jon Medhurst15ce78d2014-04-10 09:02:02 +010040 if (mFd < 0) {
41 logg->logMessage("%s(%s:%i): epoll_create1 failed", __FUNCTION__, __FILE__, __LINE__);
42 return false;
43 }
44
Jon Medhurst96b56152014-10-30 18:01:15 +000045#ifndef EPOLL_CLOEXEC
46 int fdf = fcntl(mFd, F_GETFD);
47 if ((fdf == -1) || (fcntl(mFd, F_SETFD, fdf | FD_CLOEXEC) != 0)) {
48 logg->logMessage("%s(%s:%i): fcntl failed", __FUNCTION__, __FILE__, __LINE__);
49 ::close(mFd);
50 return -1;
51 }
52#endif
53
Jon Medhurst15ce78d2014-04-10 09:02:02 +010054 return true;
55}
56
57bool Monitor::add(const int fd) {
58 struct epoll_event event;
59 memset(&event, 0, sizeof(event));
60 event.data.fd = fd;
61 event.events = EPOLLIN;
62 if (epoll_ctl(mFd, EPOLL_CTL_ADD, fd, &event) != 0) {
63 logg->logMessage("%s(%s:%i): epoll_ctl failed", __FUNCTION__, __FILE__, __LINE__);
64 return false;
65 }
66
67 return true;
68}
69
70int Monitor::wait(struct epoll_event *const events, int maxevents, int timeout) {
71 int result = epoll_wait(mFd, events, maxevents, timeout);
72 if (result < 0) {
73 // Ignore if the call was interrupted as this will happen when SIGINT is received
74 if (errno == EINTR) {
75 result = 0;
76 } else {
77 logg->logMessage("%s(%s:%i): epoll_wait failed", __FUNCTION__, __FILE__, __LINE__);
78 }
79 }
80
81 return result;
82}