| 1964 | |
| 1965 | |
| 1966 | int TRA_wait(thread_db* tdbb, jrd_tra* trans, TraNumber number, jrd_tra::wait_t wait) |
| 1967 | { |
| 1968 | /************************************** |
| 1969 | * |
| 1970 | * T R A _ w a i t |
| 1971 | * |
| 1972 | ************************************** |
| 1973 | * |
| 1974 | * Functional description |
| 1975 | * Wait for a given transaction to drop into a stable state (i.e. non-active) |
| 1976 | * state. To do this, we first wait on the transaction number. When we |
| 1977 | * are able to get the lock, the transaction is not longer bona fide |
| 1978 | * active. Next, we determine the state of the transaction from the |
| 1979 | * transaction inventory page. If either committed, dead, or limbo, |
| 1980 | * we return the state. If the transaction is still marked active, |
| 1981 | * however, declare the transaction dead, and mark the transaction |
| 1982 | * inventory page accordingly. |
| 1983 | * |
| 1984 | **************************************/ |
| 1985 | SET_TDBB(tdbb); |
| 1986 | Database* dbb = tdbb->getDatabase(); |
| 1987 | CHECK_DBB(dbb); |
| 1988 | |
| 1989 | // Create, wait on, and release lock on target transaction. If |
| 1990 | // we can't get the lock due to deadlock |
| 1991 | |
| 1992 | if (wait != jrd_tra::tra_no_wait) |
| 1993 | { |
| 1994 | Lock temp_lock(tdbb, sizeof(TraNumber), LCK_tra); |
| 1995 | temp_lock.setKey(number); |
| 1996 | |
| 1997 | const SSHORT timeout = (wait == jrd_tra::tra_wait) ? trans->getLockWait() : 0; |
| 1998 | |
| 1999 | if (!LCK_lock(tdbb, &temp_lock, LCK_read, timeout)) |
| 2000 | { |
| 2001 | fb_utils::init_status(tdbb->tdbb_status_vector); |
| 2002 | return tra_active; |
| 2003 | } |
| 2004 | |
| 2005 | LCK_release(tdbb, &temp_lock); |
| 2006 | } |
| 2007 | |
| 2008 | int state = TRA_get_state(tdbb, number); |
| 2009 | |
| 2010 | if (wait != jrd_tra::tra_no_wait && state == tra_committed) |
| 2011 | return state; |
| 2012 | |
| 2013 | if (state == tra_precommitted) |
| 2014 | return state; |
| 2015 | |
| 2016 | // If the recorded state of the transaction is active, we know better. If |
| 2017 | // it were active, he'd be alive now. Mark him dead. |
| 2018 | |
| 2019 | if (state == tra_active) |
| 2020 | { |
| 2021 | state = tra_dead; |
| 2022 | REPL_trans_cleanup(tdbb, number); |
| 2023 | TRA_set_state(tdbb, 0, number, tra_dead); |
no test coverage detected