| 703 | |
| 704 | |
| 705 | CancellationCode ProcessList::sendCancelToQuery(const String & current_query_id, const String & current_user, bool kill) |
| 706 | { |
| 707 | std::shared_ptr<QueryStatus> elem; |
| 708 | |
| 709 | /// Cancelling the query should be done without the lock. |
| 710 | /// |
| 711 | /// Since it may be not that trivial, for example in case of distributed |
| 712 | /// queries it tries to cancel the query gracefully on shards and this can |
| 713 | /// take a while, so acquiring a lock during this time will lead to wait |
| 714 | /// all new queries for this cancellation. |
| 715 | /// |
| 716 | /// Another problem is that it can lead to a deadlock, because of |
| 717 | /// OvercommitTracker. |
| 718 | /// |
| 719 | /// So here we first set is_cancelling, and later reset it. |
| 720 | /// The ProcessListEntry cannot be destroy if is_cancelling is true. |
| 721 | { |
| 722 | std::lock_guard lock(mutex); |
| 723 | elem = tryGetProcessListElement(current_query_id, current_user); |
| 724 | if (!elem) |
| 725 | return CancellationCode::NotFound; |
| 726 | elem->is_cancelling = true; |
| 727 | } |
| 728 | |
| 729 | SCOPE_EXIT({ |
| 730 | DENY_ALLOCATIONS_IN_SCOPE; |
| 731 | |
| 732 | std::lock_guard lock(mutex); |
| 733 | elem->is_cancelling = false; |
| 734 | cancelled_cv.notify_all(); |
| 735 | }); |
| 736 | |
| 737 | return elem->cancelQuery(kill, false); |
| 738 | } |
| 739 | |
| 740 | |
| 741 | void ProcessList::killAllQueries() |
no test coverage detected