| 184 | } |
| 185 | |
| 186 | int |
| 187 | CacheVC::openReadFromWriter(int event, Event *e) |
| 188 | { |
| 189 | if (!f.read_from_writer_called) { |
| 190 | // The assignment to last_collision as nullptr was |
| 191 | // made conditional after INKqa08411 |
| 192 | last_collision = nullptr; |
| 193 | // Let's restart the clock from here - the first time this a reader |
| 194 | // gets in this state. Its possible that the open_read was called |
| 195 | // before the open_write, but the reader could not get the volume |
| 196 | // lock. If we don't reset the clock here, we won't choose any writer |
| 197 | // and hence fail the read request. |
| 198 | start_time = ink_get_hrtime(); |
| 199 | f.read_from_writer_called = 1; |
| 200 | } |
| 201 | cancel_trigger(); |
| 202 | intptr_t err = ECACHE_DOC_BUSY; |
| 203 | DDbg(dbg_ctl_cache_read_agg, "%p: key: %X In openReadFromWriter", this, first_key.slice32(1)); |
| 204 | if (_action.cancelled) { |
| 205 | od = nullptr; // only open for read so no need to close |
| 206 | return free_CacheVC(this); |
| 207 | } |
| 208 | CACHE_TRY_LOCK(lock, stripe->mutex, mutex->thread_holding); |
| 209 | if (!lock.is_locked()) { |
| 210 | VC_SCHED_LOCK_RETRY(); |
| 211 | } |
| 212 | od = stripe->open_read(&first_key); // recheck in case the lock failed |
| 213 | if (!od) { |
| 214 | MUTEX_RELEASE(lock); |
| 215 | write_vc = nullptr; |
| 216 | SET_HANDLER(&CacheVC::openReadStartHead); |
| 217 | return openReadStartHead(event, e); |
| 218 | } else { |
| 219 | ink_assert(od == stripe->open_read(&first_key)); |
| 220 | } |
| 221 | if (!write_vc) { |
| 222 | int ret = openReadChooseWriter(event, e); |
| 223 | if (ret < 0) { |
| 224 | MUTEX_RELEASE(lock); |
| 225 | SET_HANDLER(&CacheVC::openReadFromWriterFailure); |
| 226 | return openReadFromWriterFailure(CACHE_EVENT_OPEN_READ_FAILED, reinterpret_cast<Event *>(ret)); |
| 227 | } else if (ret == EVENT_RETURN) { |
| 228 | MUTEX_RELEASE(lock); |
| 229 | SET_HANDLER(&CacheVC::openReadStartHead); |
| 230 | return openReadStartHead(event, e); |
| 231 | } else if (ret == EVENT_CONT) { |
| 232 | ink_assert(!write_vc); |
| 233 | if (writer_lock_retry < cache_config_read_while_writer_max_retries) { |
| 234 | VC_SCHED_WRITER_RETRY(); |
| 235 | } else { |
| 236 | return openReadFromWriterFailure(CACHE_EVENT_OPEN_READ_FAILED, reinterpret_cast<Event *>(-err)); |
| 237 | } |
| 238 | } else { |
| 239 | ink_assert(write_vc); |
| 240 | } |
| 241 | } else { |
| 242 | if (writer_done()) { |
| 243 | MUTEX_RELEASE(lock); |
nothing calls this directly
no test coverage detected