taffcns.c

来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 544 行 · 第 1/2 页

C
544
字号
/*************************************************************************** *                                                                         * * db.*                                                                    * * open source database kernel                                             * *                                                                         * * Copyright (c) 2000 Centura Software Corporation. All rights reserved.   * *                                                                         * * Use of this software, whether in source code format, or in executable,  * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this  * * distribution of source code files.                                      *  *                                                                         * * Except as provided herein, the contents of this file are subject to the * * Centura Open Source Public License Version 1.0 (the "License"); you may * * not use this file except in compliance with the License.  A copy of the * * License will be provided to you by Club ITTIA.                          * *                                                                         * * Software distributed under the License is distributed on an "AS IS"     * * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * * License for the specific language governing rights and limitations      * * under the License.                                                      * *                                                                         * * The Original Code is db.linux version 1.0, released February 29, 2000.  * *                                                                         * * The Initial Developer of the Original Code is Centura Software          * * Corporation. Portions created by Centura Software Corporation are       * * Copyright (C) 1984-2000 Centura Software Corporation. All Rights        * * Reserved.                                                               * *                                                                         * * This file contains modifications to the Original Code made by ITTIA.    * * This file may only be used in accordance with the ITTIA DB.* V.2        * * License Agreement which is available at WWW.ITTIA.COM.                  * *                                                                         * **************************************************************************//*--------------------------------------------------------------------------    This module contains the functions which access and manipulate    the Transaction Activity File.   The name of a transaction log    file is written to the TAF just before a commit and removed    following the commit in order to provide for external recovery    in the event that the lock manager fails.    Access to the TAF must be synchronized so that only one process    has control of it at a time.  The lock manager cannot be used for    this synchronization because if it is active then the TAF is not    needed.  Thus, some outside resource must be used to lock the TAF    for exclusive access.  Function "locking" (or "lockf" on Unix) is    called to gain exclusive access to the TAF.  This function is    available in MS-DOS 3+, and Unix System V and BSD (as "lockf").    If it is not available for your particular network or operating    system then you will need to modify the call to locking to that    which is available on your system.  Alternatively, you can compile    this module with constant PORTABLE defined.  This will use a    zero-length file "dblfg" as a semaphore on the TAF.  If the file    exists then the TAF is not being used.  If it doesn't exist then    the TAF is being used.  This technique has been used in earlier    versions of db.*.  It's not ideal but it does work.    We used function "locking" instead of simply opening the file    exclusively because on PC-NETWORK a sharing violation occurs    if a program attempts to exclusively open a file which is    already exlusively opened by another program.  We could accept    this if all it did was return a status code but, for some reason,    the sharing violation is reported to the user (similar to a    floppy disk error).--------------------------------------------------------------------------*/#include "db.star.h"#ifndef O_SYNC#define O_SYNC 0x0000#endif/* maximum number of attempts to gain access TAF */#define MAXTRIES 100/* buffer containing TAF file */TAFFILE tafbuf;#define LOCK_LEN   sizeof(tafbuf)static DB_TCHAR * INTERNAL_FCN dblfg_name(DB_TASK *);static int  INTERNAL_FCN taf_lock(DB_TASK *);static void INTERNAL_FCN taf_unlock(DB_TASK *);/***************************************************************************/int INTERNAL_FCN taf_login(DB_TASK *task){    int stat;#ifdef MULTI_TAFFILE    if (task->dboptions & MULTITAF)    {        if (task->dbuserid[0])        {            vtstrcpy(psp_pathGetFile(task->dbtaf), task->dbuserid);            vtstrcat(task->dbtaf, DB_TEXT(".taf"));        }        else if (task->dbopen == 1)            return (dberr(S_DBLACCESS));    }#endif /* MULTI_TAFFILE */#if 0    /* create the taf if necessary */    if ((stat = taf_open(task)) != S_OKAY)        return (task->db_status = stat);    taf_close(task);     /* taf must be closed before access */#endif    /* TAF exists at this point */    stat = taf_access(DEL_LOGFILE, task);    if (stat != S_OKAY)        return (task->db_status = stat);    if (tafbuf.user_count == 0)    {        tafbuf.unicode = DBSTAR_UNICODE_FLAG;        vtstrcpy(tafbuf.lmc_type, task->lmc_type);        if (task->lockmgrn)            vtstrcpy(tafbuf.lockmgrn, task->lockmgrn);        else            tafbuf.lockmgrn[0] = DB_TEXT('\0');    }    else    {        /* The LMC transport type, the lock manager name, and the unicode           setting must all match between this task and the TAF file. */        if (vtstrcmp(tafbuf.lmc_type, task->lmc_type) != 0 ||                (task->lockmgrn && vtstrcmp(tafbuf.lockmgrn, task->lockmgrn)) ||                (!task->lockmgrn && tafbuf.lockmgrn[0] != DB_TEXT('\0')) ||                tafbuf.unicode != DBSTAR_UNICODE_FLAG)            goto ret_err;    }    ++tafbuf.user_count;    stat = taf_release(0, task);    return (task->db_status);ret_err:    taf_unlock(task);    taf_close(task);    return (dberr(S_TAFSYNC));}/***************************************************************************/int INTERNAL_FCN taf_logout(DB_TASK *task){    int stat;#if 0    if (task->lockMgrComm == LMC_GENERAL && task->lmc_avail(task) != S_OKAY)    {        /* assume that if the DBL is not accessable, neither is the TAF */        taf_close(task);        return task->db_status;    }#endif    stat = taf_access(DEL_LOGFILE, task);    if (stat != S_OKAY)        return (task->db_status = stat);    if (vtstrcmp(tafbuf.lmc_type, task->lmc_type) != 0 ||            (task->lockmgrn && vtstrcmp(tafbuf.lockmgrn,task->lockmgrn) != 0) ||            (!task->lockmgrn && tafbuf.lockmgrn[0] != DB_TEXT('\0')) ||            tafbuf.unicode != DBSTAR_UNICODE_FLAG)        goto ret_err;    if (tafbuf.user_count > 0)        --tafbuf.user_count;    taf_release(0, task);    taf_close(task);    return (task->db_status);ret_err:    taf_unlock(task);    taf_close(task);    return (dberr(S_TAFSYNC));}/***************************************************************************/static void INTERNAL_FCN taf_unlock(DB_TASK *task){    PSP_FH lfn;    /* one user mode does not require locks */    if (!task->db_lockmgr)        return;    /* Free the lock */    if (task->dboptions & PORTABLE)    {        if (psp_lmcFlags(task->lmc) & PSP_FLAG_TAF_CLOSE)            taf_close(task); /* close file before releasing it */        else            commit_file(task->lfn, task);        /* create lock file guard file */        lfn = open_b(dblfg_name(task), O_CREAT | O_SYNC, PSP_FLAG_SYNC, task);        if (lfn != NULL)            psp_fileClose(lfn);    }    else    {        commit_file(task->lfn, task);        /* need the file handle here */        psp_fileUnlock(task->lfn);        if (psp_lmcFlags(task->lmc) & PSP_FLAG_TAF_CLOSE)            taf_close(task); /* close file before releasing it */    }}/***************************************************************************/static int INTERNAL_FCN taf_lock(DB_TASK *task){    int not_locked;    /* one user mode does not require locks */    if (!task->db_lockmgr)          return 0;    if (task->dboptions & PORTABLE)    {        not_locked = psp_fileRemove(dblfg_name(task));        if (psp_errno() == EACCES)            dberr(S_EACCESS);    }    else        not_locked = psp_fileLock(task->lfn);    return not_locked;}/* ======================================================================    Open Transaction Activity File*/int INTERNAL_FCN taf_open(DB_TASK *task){    unsigned long rd_opt, fopt;    /* even with READONLY option set, attempt to creat log file */    rd_opt = task->dboptions & READONLY;    /* Do not re-open an open file */    if (task->lfn)        return (task->db_status);    task->dboptions &= ~READONLY;       /* try to create */    /* only open with the O_SYNC option when SYNCFILES is on */    if (task->dboptions & SYNCFILES)        fopt = O_RDWR | O_SYNC;    else        fopt = O_RDWR;    if ((task->lfn = open_b(task->dbtaf, fopt, PSP_FLAG_SYNC, task)) == NULL)    {        if (psp_errno() == ENOENT)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?