Example #1
0
static bool shutdown_locks(thread_db* tdbb, SSHORT flag)
{
    /**************************************
     *
     *	s h u t d o w n _ l o c k s
     *
     **************************************
     *
     * Functional description
     *	Release all attachment and database
     *	locks if database is quiet.
     *
     **************************************/
    Database* dbb = tdbb->getDatabase();

    /* Mark database and all active attachments as shutdown. */

    dbb->dbb_ast_flags &= ~(DBB_shutdown | DBB_shutdown_single | DBB_shutdown_full);

    switch (flag & isc_dpb_shut_mode_mask)
    {
    case isc_dpb_shut_normal:
        break;
    case isc_dpb_shut_multi:
        dbb->dbb_ast_flags |= DBB_shutdown;
        break;
    case isc_dpb_shut_single:
        dbb->dbb_ast_flags |= DBB_shutdown | DBB_shutdown_single;
        break;
    case isc_dpb_shut_full:
        dbb->dbb_ast_flags |= DBB_shutdown | DBB_shutdown_full;
        break;
    default:
        fb_assert(false);
    }

    Attachment* attachment;

    for (attachment = dbb->dbb_attachments; attachment; attachment = attachment->att_next)
    {
        if (!(attachment->att_flags & ATT_shutdown_manager))
        {
            attachment->att_flags |= ATT_shutdown;
            attachment->cancelExternalConnection(tdbb);
            LCK_cancel_wait(attachment);
        }
    }

    JRD_shutdown_attachments(dbb);

    for (int retry = 0; retry < 10 && dbb->dbb_use_count; retry++)
    {
        // Let active database threads rundown
        Database::Checkout dcoHolder(dbb);
        THREAD_SLEEP(1 * 100);
    }

    if (dbb->dbb_use_count)
    {
        return false;
    }

    /* Since no attachment is actively running, release all
       attachment-specfic locks while they're not looking. */

    const Attachment* shut_attachment = NULL;

    for (attachment = dbb->dbb_attachments; attachment; attachment = attachment->att_next)
    {
        if (attachment->att_flags & ATT_shutdown_manager)
        {
            shut_attachment = attachment;
            continue;
        }

        if (attachment->att_id_lock)
            LCK_release(tdbb, attachment->att_id_lock);

        TRA_shutdown_attachment(tdbb, attachment);
    }

    /* Release database locks that are shared by all attachments.
       These include relation and index existence locks, as well
       as, relation interest and record locking locks for PC semantic
       record locking. */

    CMP_shutdown_database(tdbb);

    /* If shutdown manager is here, leave enough database lock context
       to run as a normal attachment. Otherwise, get rid of the rest
       of the database locks.*/

    if (!shut_attachment)
    {
        CCH_shutdown_database(dbb);
        if (dbb->dbb_monitor_lock)
            LCK_release(tdbb, dbb->dbb_monitor_lock);
        if (dbb->dbb_shadow_lock)
            LCK_release(tdbb, dbb->dbb_shadow_lock);
        if (dbb->dbb_retaining_lock)
            LCK_release(tdbb, dbb->dbb_retaining_lock);
        if (dbb->dbb_lock)
            LCK_release(tdbb, dbb->dbb_lock);
        dbb->dbb_shared_counter.shutdown(tdbb);
        dbb->dbb_backup_manager->shutdown(tdbb);
        dbb->dbb_ast_flags |= DBB_shutdown_locks;
    }

    return true;
}