| 2291 | } |
| 2292 | |
| 2293 | void CCH_unwind(thread_db* tdbb, const bool punt) |
| 2294 | { |
| 2295 | /************************************** |
| 2296 | * |
| 2297 | * C C H _ u n w i n d |
| 2298 | * |
| 2299 | ************************************** |
| 2300 | * |
| 2301 | * Functional description |
| 2302 | * Synchronously unwind cache after I/O or lock error. |
| 2303 | * |
| 2304 | **************************************/ |
| 2305 | SET_TDBB(tdbb); |
| 2306 | Database* dbb = tdbb->getDatabase(); |
| 2307 | |
| 2308 | // CCH_unwind is called when any of the following occurs: |
| 2309 | // - IO error |
| 2310 | // - journaling error => obsolete |
| 2311 | // - bad page checksum => obsolete |
| 2312 | // - wrong page type |
| 2313 | // - page locking (not latching) deadlock |
| 2314 | |
| 2315 | BufferControl* bcb = dbb->dbb_bcb; |
| 2316 | if (!bcb || (tdbb->tdbb_flags & TDBB_no_cache_unwind)) |
| 2317 | { |
| 2318 | if (punt) |
| 2319 | ERR_punt(); |
| 2320 | |
| 2321 | return; |
| 2322 | } |
| 2323 | |
| 2324 | // A cache error has occurred. Scan the cache for buffers |
| 2325 | // which may be in use and release them. |
| 2326 | |
| 2327 | for (FB_SIZE_T n = 0; n < tdbb->tdbb_bdbs.getCount(); ++n) |
| 2328 | { |
| 2329 | BufferDesc *bdb = tdbb->tdbb_bdbs[n]; |
| 2330 | if (bdb) |
| 2331 | { |
| 2332 | if (bdb->bdb_flags & BDB_marked) |
| 2333 | BUGCHECK(268); // msg 268 buffer marked during cache unwind |
| 2334 | |
| 2335 | if (bdb->ourIOLock()) |
| 2336 | { |
| 2337 | bdb->unLockIO(tdbb); |
| 2338 | } |
| 2339 | else |
| 2340 | { |
| 2341 | if (bdb->ourExclusiveLock()) |
| 2342 | bdb->bdb_flags &= ~(BDB_writer | BDB_faked | BDB_must_write); |
| 2343 | |
| 2344 | bdb->release(tdbb, true); |
| 2345 | } |
| 2346 | } |
| 2347 | } |
| 2348 | |
| 2349 | /*** |
| 2350 | bcb_repeat* tail = bcb->bcb_rpt; |
no test coverage detected