Adds/Deletes alternate to the od->vector (write_vector). If the vector is empty, deletes the directory entry pointing to the vector. Each CacheVC must write the vector down to disk after making changes. If we wait till the last writer, that writer will have the responsibility of of writing the vector even if the http state machine aborts. This makes it easier to handle situations where writers ab
| 71 | // of writing the vector even if the http state machine aborts. This |
| 72 | // makes it easier to handle situations where writers abort. |
| 73 | int |
| 74 | CacheVC::updateVector(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) |
| 75 | { |
| 76 | cancel_trigger(); |
| 77 | if (od->reading_vec || od->writing_vec) { |
| 78 | VC_SCHED_LOCK_RETRY(); |
| 79 | } |
| 80 | int ret = 0; |
| 81 | { |
| 82 | CACHE_TRY_LOCK(lock, stripe->mutex, mutex->thread_holding); |
| 83 | if (!lock.is_locked() || od->writing_vec) { |
| 84 | VC_SCHED_LOCK_RETRY(); |
| 85 | } |
| 86 | |
| 87 | int vec = alternate.valid(); |
| 88 | if (f.update) { |
| 89 | // all Update cases. Need to get the alternate index. |
| 90 | alternate_index = get_alternate_index(write_vector, update_key); |
| 91 | Dbg(dbg_ctl_cache_update, "updating alternate index %d frags %d", alternate_index, |
| 92 | alternate_index >= 0 ? write_vector->get(alternate_index)->get_frag_offset_count() : -1); |
| 93 | // if its an alternate delete |
| 94 | if (!vec) { |
| 95 | ink_assert(!total_len); |
| 96 | if (alternate_index >= 0) { |
| 97 | write_vector->remove(alternate_index, true); |
| 98 | alternate_index = CACHE_ALT_REMOVED; |
| 99 | if (!write_vector->count()) { |
| 100 | dir_delete(&first_key, stripe, &od->first_dir); |
| 101 | } |
| 102 | } |
| 103 | // the alternate is not there any more. somebody might have |
| 104 | // deleted it. Just close this writer |
| 105 | if (alternate_index != CACHE_ALT_REMOVED || !write_vector->count()) { |
| 106 | SET_HANDLER(&CacheVC::openWriteCloseDir); |
| 107 | return openWriteCloseDir(EVENT_IMMEDIATE, nullptr); |
| 108 | } |
| 109 | } |
| 110 | if (update_key == od->single_doc_key && (total_len || f.allow_empty_doc || !vec)) { |
| 111 | od->move_resident_alt = false; |
| 112 | } |
| 113 | } |
| 114 | if (cache_config_http_max_alts > 1 && write_vector->count() >= cache_config_http_max_alts && alternate_index < 0) { |
| 115 | if (od->move_resident_alt && get_alternate_index(write_vector, od->single_doc_key) == 0) { |
| 116 | od->move_resident_alt = false; |
| 117 | } |
| 118 | if (cache_config_log_alternate_eviction) { |
| 119 | // Initially there was an attempt to make alternate eviction a log |
| 120 | // field. However it was discovered this could not work because this |
| 121 | // code, in which alternates are evicted, happens during the processing |
| 122 | // of IO which happens after transaction logs are emitted and after the |
| 123 | // HttpSM is destructed. Instead, therefore, alternate eviction logging |
| 124 | // was implemented for diags.log with the |
| 125 | // proxy.config.cache.log.alternate.eviction toggle. |
| 126 | CacheHTTPInfo *info = write_vector->get(0); |
| 127 | HTTPHdr *request = info->request_get(); |
| 128 | if (request->valid()) { |
| 129 | // Marking the request's target as dirty will guarantee that the |
| 130 | // internal members of the request used for printing the URL will be |
nothing calls this directly
no test coverage detected