| 1353 | |
| 1354 | |
| 1355 | static bool internal_enqueue(thread_db* tdbb, CheckStatusWrapper* statusVector, Lock* lock, |
| 1356 | USHORT level, SSHORT wait, bool convert_flg) |
| 1357 | { |
| 1358 | /************************************** |
| 1359 | * |
| 1360 | * i n t e r n a l _ e n q u e u e |
| 1361 | * |
| 1362 | ************************************** |
| 1363 | * |
| 1364 | * Functional description |
| 1365 | * See if there is a compatible lock already held |
| 1366 | * by this process; if not, go ahead and submit the |
| 1367 | * lock to the real lock manager. |
| 1368 | * NOTE: This routine handles both enqueueing |
| 1369 | * and converting existing locks, since the convert |
| 1370 | * will find itself in the hash table and convert |
| 1371 | * itself upward. |
| 1372 | * |
| 1373 | **************************************/ |
| 1374 | SET_TDBB(tdbb); |
| 1375 | Database* const dbb = tdbb->getDatabase(); |
| 1376 | |
| 1377 | fb_assert(LCK_CHECK_LOCK(lock)); |
| 1378 | fb_assert(lock->lck_compatible); |
| 1379 | |
| 1380 | // look for an identical lock |
| 1381 | |
| 1382 | Lock* match = hash_get_lock(lock, 0, 0); |
| 1383 | if (match) |
| 1384 | { |
| 1385 | // if there are incompatible locks for which there are no blocking asts defined, give up |
| 1386 | |
| 1387 | if (!internal_compatible(match, lock, level)) |
| 1388 | { |
| 1389 | // for now return a lock conflict; it would be better if we were to |
| 1390 | // do a wait on the other lock by setting some flag bit or some such |
| 1391 | |
| 1392 | (Arg::StatusVector(statusVector) << Arg::Gds(isc_lock_conflict)).copyTo(statusVector); |
| 1393 | return false; |
| 1394 | } |
| 1395 | |
| 1396 | // if there is still an identical lock, convert the lock, otherwise fall |
| 1397 | // through and enqueue a new one |
| 1398 | |
| 1399 | if ( (match = hash_get_lock(lock, 0, 0)) ) |
| 1400 | { |
| 1401 | // if a conversion is necessary, update all identical |
| 1402 | // locks to reflect the new physical lock level |
| 1403 | |
| 1404 | if (level > match->lck_physical) |
| 1405 | { |
| 1406 | if (!dbb->lockManager()->convert(tdbb, statusVector, match->lck_id, level, wait, |
| 1407 | external_ast, lock)) |
| 1408 | { |
| 1409 | return false; |
| 1410 | } |
| 1411 | |
| 1412 | for (Lock* update = match; update; update = update->lck_identical) |
no test coverage detected