| 599 | */ |
| 600 | |
| 601 | bool Query_cache::try_lock(THD *thd, Cache_try_lock_mode mode) |
| 602 | { |
| 603 | bool interrupt= TRUE; |
| 604 | Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__); |
| 605 | DBUG_ENTER("Query_cache::try_lock"); |
| 606 | |
| 607 | mysql_mutex_lock(&structure_guard_mutex); |
| 608 | DBUG_EXECUTE_IF("status_wait_query_cache_mutex_sleep", { sleep(5); }); |
| 609 | if (m_cache_status == DISABLED) |
| 610 | { |
| 611 | mysql_mutex_unlock(&structure_guard_mutex); |
| 612 | DBUG_RETURN(TRUE); |
| 613 | } |
| 614 | m_requests_in_progress++; |
| 615 | fix_local_query_cache_mode(thd); |
| 616 | |
| 617 | while (1) |
| 618 | { |
| 619 | if (m_cache_lock_status == Query_cache::UNLOCKED) |
| 620 | { |
| 621 | m_cache_lock_status= Query_cache::LOCKED; |
| 622 | #ifndef DBUG_OFF |
| 623 | m_cache_lock_thread_id= thd->thread_id; |
| 624 | #endif |
| 625 | interrupt= FALSE; |
| 626 | break; |
| 627 | } |
| 628 | else if (m_cache_lock_status == Query_cache::LOCKED_NO_WAIT) |
| 629 | { |
| 630 | /* |
| 631 | If query cache is protected by a LOCKED_NO_WAIT lock this thread |
| 632 | should avoid using the query cache as it is being evicted. |
| 633 | */ |
| 634 | break; |
| 635 | } |
| 636 | else |
| 637 | { |
| 638 | DBUG_ASSERT(m_cache_lock_status == Query_cache::LOCKED); |
| 639 | /* |
| 640 | To prevent send_result_to_client() and query_cache_insert() from |
| 641 | blocking execution for too long a timeout is put on the lock. |
| 642 | */ |
| 643 | if (mode == WAIT) |
| 644 | { |
| 645 | mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex); |
| 646 | } |
| 647 | else if (mode == TIMEOUT) |
| 648 | { |
| 649 | struct timespec waittime; |
| 650 | set_timespec_nsec(waittime,50000000UL); /* Wait for 50 msec */ |
| 651 | int res= mysql_cond_timedwait(&COND_cache_status_changed, |
| 652 | &structure_guard_mutex, &waittime); |
| 653 | if (res == ETIMEDOUT) |
| 654 | break; |
| 655 | } |
| 656 | else |
| 657 | { |
| 658 | /** |
no test coverage detected