| 4069 | |
| 4070 | |
| 4071 | static LockState lock_buffer(thread_db* tdbb, BufferDesc* bdb, const SSHORT wait, |
| 4072 | const SCHAR page_type) |
| 4073 | { |
| 4074 | /************************************** |
| 4075 | * |
| 4076 | * l o c k _ b u f f e r |
| 4077 | * |
| 4078 | ************************************** |
| 4079 | * |
| 4080 | * Functional description |
| 4081 | * Get a lock on page for a buffer. If the lock ever slipped |
| 4082 | * below READ, indicate that the page must be read. |
| 4083 | * |
| 4084 | * input: |
| 4085 | * wait: LCK_WAIT = 1 => Wait as long a necessary to get the lock. |
| 4086 | * LCK_NO_WAIT = 0 => If the lock can't be acquired immediately, |
| 4087 | * give up and return -1. |
| 4088 | * <negative number> => Lock timeout interval in seconds. |
| 4089 | * |
| 4090 | * return: 0 => buffer locked, page is already in memory. |
| 4091 | * 1 => buffer locked, page needs to be read from disk. |
| 4092 | * -1 => timeout on lock occurred, see input parameter 'wait'. |
| 4093 | * |
| 4094 | **************************************/ |
| 4095 | SET_TDBB(tdbb); |
| 4096 | BufferControl* const bcb = bdb->bdb_bcb; |
| 4097 | fb_assert(!(bcb->bcb_flags & BCB_exclusive)); |
| 4098 | |
| 4099 | const USHORT lock_type = (bdb->bdb_flags & (BDB_dirty | BDB_writer)) ? LCK_write : LCK_read; |
| 4100 | |
| 4101 | CCH_TRACE(("FE LOCK %d:%06d, %s", bdb->bdb_page.getPageSpaceID(), bdb->bdb_page.getPageNum(), |
| 4102 | (lock_type >= LCK_write) ? "EX" : "SH" )); |
| 4103 | |
| 4104 | Lock* const lock = bdb->bdb_lock; |
| 4105 | |
| 4106 | if (lock->lck_logical >= lock_type) |
| 4107 | return lsLockedHavePage; |
| 4108 | |
| 4109 | TEXT errmsg[MAX_ERRMSG_LEN + 1]; |
| 4110 | |
| 4111 | ThreadStatusGuard tempStatus(tdbb); |
| 4112 | |
| 4113 | if (lock->lck_logical == LCK_none) |
| 4114 | { |
| 4115 | // Prevent header and TIP pages from generating blocking AST |
| 4116 | // overhead. The promise is that the lock will unconditionally |
| 4117 | // be released when the buffer use count indicates it is safe to do so. |
| 4118 | |
| 4119 | if (page_type == pag_header || page_type == pag_transactions) |
| 4120 | { |
| 4121 | fb_assert(lock->lck_ast == blocking_ast_bdb); |
| 4122 | fb_assert(lock->lck_object == bdb); |
| 4123 | lock->lck_ast = 0; |
| 4124 | lock->lck_object = NULL; |
| 4125 | } |
| 4126 | else { |
| 4127 | fb_assert(lock->lck_ast != NULL); |
| 4128 | } |
no test coverage detected