On 25 Dec 2015, at 21:40, Holger Freyther holger@freyther.de wrote:
Dear Eliot,
I was thinking what to do to make the below race free? I think I will:
* Block the SIGIO * Memory barrier? * Check if an event is already queued and then restore mask and return * Set itimer * sigsuspend * Unblock SIGIO * dispatch
Does this look correct? At the same time I think the per display backend relinquish code can be replaced with a generic unix one? Maybe even separating waiting for a timeout and waiting for I/O could be done and creates a better internal interface?
kind regards holger
static sqInt display_ioRelinquishProcessorForMicroseconds(sqInt microSeconds) {
- aioSleepForUsecs(handleEvents() ? 0 : microSeconds);
- sigset_t set;
- sigemptyset(&set);
- extern usqLong getNextWakeupUsecs();
- if (getNextWakeupUsecs() == 0) {
- sigsuspend(&set);
- } else {
- usqLong nextWakeUp = getNextWakeupUsecs();
- usqLong now = ioUTCMicroseconds();
- struct itimerval value;
- sqLong deltaMicro = nextWakeUp - now;
- if (deltaMicro < 1)
deltaMicro = 1;
- /* don't re-run automatically */
- value.it_interval.tv_sec = value.it_interval.tv_usec = 0;
- value.it_value.tv_sec = deltaMicro / 1000000;
- value.it_value.tv_usec = deltaMicro % 1000000;
- setitimer(ITIMER_REAL, &value, &value);
- sigsuspend(&set);
- value.it_value = value.it_interval;
- setitimer(ITIMER_REAL, &value, NULL);
- extern int doDispatch;
- if (doDispatch) {
doDispatch = 0;
aioPoll(0);
- }
- }