| 262 | } |
| 263 | |
| 264 | void reader_writer_lock::end_write(scoped_lock *I) { |
| 265 | __TBB_ASSERT(I==writer_head, "Internal error: can't unlock a thread that is not holding the lock."); |
| 266 | my_current_writer = tbb_thread::id(); |
| 267 | ITT_NOTIFY(sync_releasing, this); |
| 268 | if (I->next) { // potentially more writers |
| 269 | writer_head = I->next; |
| 270 | writer_head->status = active; |
| 271 | } |
| 272 | else { // No more writers; clear writer flag, test reader interest flag |
| 273 | __TBB_ASSERT(writer_head, NULL); |
| 274 | if (fetch_and_and(rdr_count_and_flags, ~(WFLAG1+WFLAG2)) & RFLAG) { |
| 275 | unblock_readers(); |
| 276 | } |
| 277 | writer_head.fetch_and_store(NULL); |
| 278 | if (I != writer_tail.compare_and_swap(NULL, I)) { // an incoming writer is in the process of being added |
| 279 | spin_wait_while_eq(I->next, (scoped_lock *)NULL); // wait for new writer to be added |
| 280 | __TBB_ASSERT(I->next, "There should be a node following the last writer."); |
| 281 | set_next_writer(I->next); |
| 282 | } |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | void reader_writer_lock::end_read() { |
| 287 | ITT_NOTIFY(sync_releasing, this); |
no test coverage detected