void CCOspApplication::OnBackground(void) { Timer* timer = CCEGLView::sharedOpenGLView()->getTimer(); if (timer != null) { timer->Cancel(); } }
void MicrosecondTimer::Calibrate() { iCount = 0; Expired(); iExpired = false; while(!iExpired) { } iExpired = false; while(!iExpired) { iCount++; } iTimer.Cancel(); }
/** * Destructor. Discards any pending events. */ ~RateLimiter() { Cancel(); }
int sys_ppoll(struct pollfd* user_fds, size_t nfds, const struct timespec* user_timeout_ts, const sigset_t* user_sigmask) { ioctx_t ctx; SetupKernelIOCtx(&ctx); struct timespec timeout_ts; if ( !FetchTimespec(&timeout_ts, user_timeout_ts) ) return -1; if ( user_sigmask ) return errno = ENOSYS, -1; struct pollfd* fds = CopyFdsFromUser(user_fds, nfds); if ( !fds ) { return -1; } PollNode* nodes = new PollNode[nfds]; if ( !nodes ) { delete[] fds; return -1; } Process* process = CurrentProcess(); kthread_mutex_t wakeup_mutex = KTHREAD_MUTEX_INITIALIZER; kthread_cond_t wakeup_cond = KTHREAD_COND_INITIALIZER; kthread_mutex_lock(&wakeup_mutex); int ret = -1; bool self_woken = false; bool remote_woken = false; bool unexpected_error = false; Timer timer; struct poll_timeout pts; if ( timespec_le(timespec_make(0, 1), timeout_ts) ) { timer.Attach(Time::GetClock(CLOCK_MONOTONIC)); struct itimerspec its; its.it_interval = timespec_nul(); its.it_value = timeout_ts; pts.wake_mutex = &wakeup_mutex; pts.wake_cond = &wakeup_cond; pts.woken = &remote_woken; timer.Set(&its, NULL, 0, poll_timeout_callback, &pts); } size_t reqs; for ( reqs = 0; !unexpected_error && reqs < nfds; ) { PollNode* node = nodes + reqs; if ( fds[reqs].fd < 0 ) { fds[reqs].revents = POLLNVAL; // TODO: Should we set POLLNVAL in node->revents too? Should this // system call ignore this error and keep polling, or return to // user-space immediately? What if conditions are already true on // some of the file descriptors (those we have processed so far?)? node->revents = 0; reqs++; continue; } Ref<Descriptor> desc = process->GetDescriptor(fds[reqs].fd); if ( !desc ) { self_woken = unexpected_error = true; break; } node->events = fds[reqs].events | POLL__ONLY_REVENTS; node->revents = 0; node->wake_mutex = &wakeup_mutex; node->wake_cond = &wakeup_cond; node->woken = &remote_woken; reqs++; // TODO: How should errors be handled? if ( desc->poll(&ctx, node) == 0 ) self_woken = true; else if ( errno == EAGAIN ) errno = 0; else unexpected_error = self_woken = true; } if ( timeout_ts.tv_sec == 0 && timeout_ts.tv_nsec == 0 ) self_woken = true; while ( !(self_woken || remote_woken) ) { if ( !kthread_cond_wait_signal(&wakeup_cond, &wakeup_mutex) ) errno = -EINTR, self_woken = true; } kthread_mutex_unlock(&wakeup_mutex); for ( size_t i = 0; i < reqs; i++ ) if ( 0 <= fds[i].fd ) nodes[i].Cancel(); if ( timespec_le(timespec_make(0, 1), timeout_ts) ) { timer.Cancel(); timer.Detach(); } if ( !unexpected_error ) { int num_events = 0; for ( size_t i = 0; i < reqs; i++ ) { if ( fds[i].fd < -1 ) continue; if ( (fds[i].revents = nodes[i].revents) ) num_events++; } if ( CopyFdsToUser(user_fds, fds, nfds) ) ret = num_events; } delete[] nodes; delete[] fds; return ret; }