| 934 | } |
| 935 | |
| 936 | void CryptoManager::startCryptThread(thread_db* tdbb) |
| 937 | { |
| 938 | // Try to take crypt mutex |
| 939 | // If can't take that mutex - nothing to do, cryptThread already runs in our process |
| 940 | MutexEnsureUnlock guard(cryptThreadMtx, FB_FUNCTION); |
| 941 | if (!guard.tryEnter()) |
| 942 | return; |
| 943 | |
| 944 | // Check for recursion |
| 945 | if (run) |
| 946 | return; |
| 947 | |
| 948 | // Take exclusive threadLock |
| 949 | // If can't take that lock - nothing to do, cryptThread already runs somewhere |
| 950 | if (!LCK_lock(tdbb, threadLock, LCK_EX, LCK_NO_WAIT)) |
| 951 | { |
| 952 | // Cleanup lock manager error |
| 953 | tdbb->tdbb_status_vector->init(); |
| 954 | |
| 955 | return; |
| 956 | } |
| 957 | |
| 958 | bool releasingLock = false; |
| 959 | try |
| 960 | { |
| 961 | // Determine current page from the header |
| 962 | CchHdr hdr(tdbb, LCK_read); |
| 963 | process = hdr->hdr_flags & Ods::hdr_crypt_process ? true : false; |
| 964 | if (!process) |
| 965 | { |
| 966 | releasingLock = true; |
| 967 | LCK_release(tdbb, threadLock); |
| 968 | return; |
| 969 | } |
| 970 | |
| 971 | currentPage = hdr->hdr_crypt_page; |
| 972 | |
| 973 | // Refresh encryption flag |
| 974 | crypt = hdr->hdr_flags & Ods::hdr_encrypted ? true : false; |
| 975 | |
| 976 | // If we are going to start crypt thread, we need plugin to be loaded |
| 977 | loadPlugin(tdbb, hdr->hdr_crypt_plugin); |
| 978 | |
| 979 | releasingLock = true; |
| 980 | LCK_release(tdbb, threadLock); |
| 981 | releasingLock = false; |
| 982 | |
| 983 | // ready to go |
| 984 | guard.leave(); // release in advance to avoid races with cryptThread() |
| 985 | Thread::start(cryptThreadStatic, (THREAD_ENTRY_PARAM) this, THREAD_medium, &cryptThread); |
| 986 | } |
| 987 | catch (const Firebird::Exception&) |
| 988 | { |
| 989 | if (!releasingLock) // avoid secondary exception in catch |
| 990 | { |
| 991 | try |
| 992 | { |
| 993 | LCK_release(tdbb, threadLock); |
no test coverage detected