32 std::vector<struct pollfd> fds;
38 return poll(&fds[0], fds.size(), 0) > 0;
43 void Fail(
const char* msg)
49 #ifdef HAVE_SYS_EVENTFD_H
50 #include <sys/eventfd.h>
54 fds[0] = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
56 Fail(
"eventfd failed");
65 if (write(fds[0], &n, 8) == -1)
71 return (read(fds[0], &n, 8) != -1);
78 fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | O_NONBLOCK);
79 fcntl(fds[0], F_SETFD, FD_CLOEXEC);
80 fcntl(fds[1], F_SETFD, FD_CLOEXEC);
90 if (write(fds[1], &c, 1) == -1)
99 if (read(fds[0], &c, 1) <= 0)
109 pollfd pfd = { fds[0], POLLIN, 0 };
110 checkfds.push_back(pfd);
116 std::vector<struct pollfd> fds;
117 std::map<StdSchedulerProc *, std::pair<unsigned int, unsigned int> > fds_for_proc;
120 for (
auto proc : procs)
122 unsigned int os = fds.size();
124 if (os != fds.size())
125 fds_for_proc[proc] = std::pair<unsigned int, unsigned int>(os, fds.size());
129 int cnt = poll(&fds[0], fds.size(), iTimeout);
131 bool fSuccess =
true;
135 bool any_executed =
false;
138 for (
size_t i = 0; i < procs.size(); i++)
140 auto proc = procs[i];
141 auto tProcTick = proc->GetNextTick(tNow);
142 if (tProcTick <= tNow)
144 struct pollfd * pfd =
nullptr;
145 if (fds_for_proc.find(proc) != fds_for_proc.end())
146 pfd = &fds[fds_for_proc[proc].first];
147 if (!proc->Execute(0, pfd))
156 if (fds_for_proc.find(proc) == fds_for_proc.end())
159 unsigned int begin = fds_for_proc[proc].first;
160 unsigned int end = fds_for_proc[proc].second;
161 for (
unsigned int j = begin; j < end; ++j)
163 if (fds[j].events & fds[j].revents)
165 if (any_executed && proc->IsLowPriority())
167 if (!proc->Execute(0, &fds[begin]))
181 else if (cnt < 0 && errno != EINTR)
183 printf(
"StdScheduler::%s: poll failed: %s\n",__func__,strerror(errno));
188 #if defined(HAVE_SYS_TIMERFD_H)
189 #include <sys/timerfd.h>
192 fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
194 Log(
"timerfd_create failed");
198 CStdMultimediaTimerProc::~CStdMultimediaTimerProc()
203 void CStdMultimediaTimerProc::SetDelay(uint32_t inDelay)
205 struct itimerspec nv, ov;
206 nv.it_interval.tv_sec = inDelay / 1000;
207 nv.it_interval.tv_nsec = (inDelay % 1000) * 1000000;
208 nv.it_value = nv.it_interval;
209 timerfd_settime(fd, 0, &nv, &ov);
212 void CStdMultimediaTimerProc::Set()
214 struct itimerspec nv, ov;
215 timerfd_gettime(fd, &nv);
216 nv.it_value.tv_sec = 0;
217 nv.it_value.tv_nsec = 1;
218 timerfd_settime(fd, 0, &nv, &ov);
221 bool CStdMultimediaTimerProc::CheckAndReset()
224 return read(fd, &n, 8) != -1;
227 void CStdMultimediaTimerProc::GetFDs(std::vector<struct pollfd> & checkfds)
229 pollfd pfd = { fd, POLLIN, 0 };
230 checkfds.push_back(pfd);
234 #if !defined(USE_COCOA)
bool Log(const char *szMessage)
#define CStdMultimediaTimerProc
static C4TimeMilliseconds Now()
~CStdNotifyProc() override
void GetFDs(std::vector< struct pollfd > &checkfds) override
virtual void OnError(StdSchedulerProc *)
virtual bool DoScheduleProcs(int iTimeout)
void Added(StdSchedulerProc *pProc)
void StartOnCurrentThread()
void Removing(StdSchedulerProc *pProc)
void Changed(StdSchedulerProc *pProc)
virtual void GetFDs(std::vector< struct pollfd > &)