| 261 | } |
| 262 | |
| 263 | void private_worker::run() { |
| 264 | my_server.propagate_chain_reaction(); |
| 265 | |
| 266 | // Transiting to st_normal here would require setting my_handle, |
| 267 | // which would create race with the launching thread and |
| 268 | // complications in handle management on Windows. |
| 269 | |
| 270 | ::rml::job& j = *my_client.create_one_job(); |
| 271 | while( my_state!=st_quit ) { |
| 272 | if( my_server.my_slack>=0 ) { |
| 273 | my_client.process(j); |
| 274 | } else { |
| 275 | thread_monitor::cookie c; |
| 276 | // Prepare to wait |
| 277 | my_thread_monitor.prepare_wait(c); |
| 278 | // Check/set the invariant for sleeping |
| 279 | if( my_state!=st_quit && my_server.try_insert_in_asleep_list(*this) ) { |
| 280 | my_thread_monitor.commit_wait(c); |
| 281 | my_server.propagate_chain_reaction(); |
| 282 | } else { |
| 283 | // Invariant broken |
| 284 | my_thread_monitor.cancel_wait(); |
| 285 | } |
| 286 | } |
| 287 | } |
| 288 | my_client.cleanup(j); |
| 289 | |
| 290 | ++my_server.my_slack; |
| 291 | my_server.remove_server_ref(); |
| 292 | } |
| 293 | |
| 294 | inline void private_worker::wake_or_launch() { |
| 295 | if( my_state==st_init && my_state.compare_and_swap( st_starting, st_init )==st_init ) { |
no test coverage detected