| 100 | } |
| 101 | |
| 102 | static int SDLCALL SDL_TimerThread(void *_data) |
| 103 | { |
| 104 | SDL_TimerData *data = (SDL_TimerData *)_data; |
| 105 | SDL_Timer *pending; |
| 106 | SDL_Timer *current; |
| 107 | SDL_Timer *freelist_head = NULL; |
| 108 | SDL_Timer *freelist_tail = NULL; |
| 109 | Uint32 tick, now, interval, delay; |
| 110 | |
| 111 | /* Threaded timer loop: |
| 112 | * 1. Queue timers added by other threads |
| 113 | * 2. Handle any timers that should dispatch this cycle |
| 114 | * 3. Wait until next dispatch time or new timer arrives |
| 115 | */ |
| 116 | for (;;) { |
| 117 | /* Pending and freelist maintenance */ |
| 118 | SDL_AtomicLock(&data->lock); |
| 119 | { |
| 120 | /* Get any timers ready to be queued */ |
| 121 | pending = data->pending; |
| 122 | data->pending = NULL; |
| 123 | |
| 124 | /* Make any unused timer structures available */ |
| 125 | if (freelist_head) { |
| 126 | freelist_tail->next = data->freelist; |
| 127 | data->freelist = freelist_head; |
| 128 | } |
| 129 | } |
| 130 | SDL_AtomicUnlock(&data->lock); |
| 131 | |
| 132 | /* Sort the pending timers into our list */ |
| 133 | while (pending) { |
| 134 | current = pending; |
| 135 | pending = pending->next; |
| 136 | SDL_AddTimerInternal(data, current); |
| 137 | } |
| 138 | freelist_head = NULL; |
| 139 | freelist_tail = NULL; |
| 140 | |
| 141 | /* Check to see if we're still running, after maintenance */ |
| 142 | if (!SDL_AtomicGet(&data->active)) { |
| 143 | break; |
| 144 | } |
| 145 | |
| 146 | /* Initial delay if there are no timers */ |
| 147 | delay = SDL_MUTEX_MAXWAIT; |
| 148 | |
| 149 | tick = SDL_GetTicks(); |
| 150 | |
| 151 | /* Process all the pending timers for this tick */ |
| 152 | while (data->timers) { |
| 153 | current = data->timers; |
| 154 | |
| 155 | if ((Sint32)(tick - current->scheduled) < 0) { |
| 156 | /* Scheduled for the future, wait a bit */ |
| 157 | delay = (current->scheduled - tick); |
| 158 | break; |
| 159 | } |
nothing calls this directly
no test coverage detected