One time initialization. For simplicity, we assume initializer thread does not exit within init_routine(). */
| 155 | does not exit within init_routine(). |
| 156 | */ |
| 157 | int my_pthread_once(my_pthread_once_t *once_control, |
| 158 | void (*init_routine)(void)) |
| 159 | { |
| 160 | LONG state; |
| 161 | |
| 162 | /* |
| 163 | Do "dirty" read to find out if initialization is already done, to |
| 164 | save an interlocked operation in common case. Memory barriers are ensured by |
| 165 | Visual C++ volatile implementation. |
| 166 | */ |
| 167 | if (*once_control == MY_PTHREAD_ONCE_DONE) |
| 168 | return 0; |
| 169 | |
| 170 | state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS, |
| 171 | MY_PTHREAD_ONCE_INIT); |
| 172 | |
| 173 | switch(state) |
| 174 | { |
| 175 | case MY_PTHREAD_ONCE_INIT: |
| 176 | /* This is initializer thread */ |
| 177 | (*init_routine)(); |
| 178 | *once_control= MY_PTHREAD_ONCE_DONE; |
| 179 | break; |
| 180 | |
| 181 | case MY_PTHREAD_ONCE_INPROGRESS: |
| 182 | /* init_routine in progress. Wait for its completion */ |
| 183 | while(*once_control == MY_PTHREAD_ONCE_INPROGRESS) |
| 184 | { |
| 185 | Sleep(1); |
| 186 | } |
| 187 | break; |
| 188 | case MY_PTHREAD_ONCE_DONE: |
| 189 | /* Nothing to do */ |
| 190 | break; |
| 191 | } |
| 192 | return 0; |
| 193 | } |
| 194 | #endif |
no outgoing calls
no test coverage detected