Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "EventNotify.h"
00031 #include "ink_hrtime.h"
00032 #include "ink_defs.h"
00033
00034 #ifdef HAVE_EVENTFD
00035 #include <sys/eventfd.h>
00036 #include <sys/fcntl.h>
00037 #include <sys/epoll.h>
00038 #endif
00039
00040 EventNotify::EventNotify()
00041 {
00042 #ifdef HAVE_EVENTFD
00043 int ret;
00044 struct epoll_event ev;
00045
00046 m_event_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
00047 if (m_event_fd < 0) {
00048
00049 m_event_fd = eventfd(0, 0);
00050
00051 fcntl(m_event_fd, F_SETFD, FD_CLOEXEC);
00052 fcntl(m_event_fd, F_SETFL, O_NONBLOCK);
00053 }
00054 ink_release_assert(m_event_fd != -1);
00055
00056 ev.events = EPOLLIN;
00057 ev.data.fd = m_event_fd;
00058
00059 m_epoll_fd = epoll_create(1);
00060 ink_release_assert(m_epoll_fd != -1);
00061
00062 ret = epoll_ctl(m_epoll_fd, EPOLL_CTL_ADD, m_event_fd, &ev);
00063 ink_release_assert(ret != -1);
00064 #else
00065 ink_cond_init(&m_cond);
00066 ink_mutex_init(&m_mutex, NULL);
00067 #endif
00068 }
00069
00070 void
00071 EventNotify::signal(void)
00072 {
00073 #ifdef HAVE_EVENTFD
00074 uint64_t value = 1;
00075
00076
00077
00078
00079
00080 ATS_UNUSED_RETURN(write(m_event_fd, &value, sizeof(uint64_t)));
00081 #else
00082 ink_cond_signal(&m_cond);
00083 #endif
00084 }
00085
00086 int
00087 EventNotify::wait(void)
00088 {
00089 #ifdef HAVE_EVENTFD
00090 ssize_t nr, nr_fd;
00091 uint64_t value = 0;
00092 struct epoll_event ev;
00093
00094 do {
00095 nr_fd = epoll_wait(m_epoll_fd, &ev, 1, -1);
00096 } while (nr_fd == -1 && errno == EINTR);
00097
00098 if (nr_fd == -1)
00099 return errno;
00100
00101 nr = read(m_event_fd, &value, sizeof(uint64_t));
00102 if (nr == sizeof(uint64_t))
00103 return 0;
00104 else
00105 return errno;
00106 #else
00107 ink_cond_wait(&m_cond, &m_mutex);
00108 return 0;
00109 #endif
00110 }
00111
00112 int
00113 EventNotify::timedwait(int timeout)
00114 {
00115 #ifdef HAVE_EVENTFD
00116 ssize_t nr, nr_fd = 0;
00117 uint64_t value = 0;
00118 struct epoll_event ev;
00119
00120
00121
00122
00123
00124
00125 if (timeout < 0)
00126 return ETIMEDOUT;
00127
00128 do {
00129 nr_fd = epoll_wait(m_epoll_fd, &ev, 1, timeout);
00130 } while (nr_fd == -1 && errno == EINTR);
00131
00132 if (nr_fd == 0)
00133 return ETIMEDOUT;
00134 else if (nr_fd == -1)
00135 return errno;
00136
00137 nr = read(m_event_fd, &value, sizeof(uint64_t));
00138 if (nr == sizeof(uint64_t))
00139 return 0;
00140 else
00141 return errno;
00142 #else
00143 ink_timestruc abstime;
00144
00145 abstime = ink_hrtime_to_timespec(ink_get_hrtime_internal() + HRTIME_SECONDS(timeout));
00146 return ink_cond_timedwait(&m_cond, &m_mutex, &abstime);
00147 #endif
00148 }
00149
00150 void
00151 EventNotify::lock(void)
00152 {
00153 #ifdef HAVE_EVENTFD
00154
00155 #else
00156 ink_mutex_acquire(&m_mutex);
00157 #endif
00158 }
00159
00160 bool
00161 EventNotify::trylock(void)
00162 {
00163 #ifdef HAVE_EVENTFD
00164 return true;
00165 #else
00166 return ink_mutex_try_acquire(&m_mutex);
00167 #endif
00168 }
00169
00170 void
00171 EventNotify::unlock(void)
00172 {
00173 #ifdef HAVE_EVENTFD
00174
00175 #else
00176 ink_mutex_release(&m_mutex);
00177 #endif
00178 }
00179
00180 EventNotify::~EventNotify()
00181 {
00182 #ifdef HAVE_EVENTFD
00183 close(m_event_fd);
00184 close(m_epoll_fd);
00185 #else
00186 ink_cond_destroy(&m_cond);
00187 ink_mutex_destroy(&m_mutex);
00188 #endif
00189 }