lmcore.c

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

C
1,370
字号
    psp_lmcFree(msg);    reply_user(lmcb, ii, NULL, 0, L_OKAY);    DEBUG5(DB_TEXT("Adding user:\n\tuser name: %s\n")            DB_TEXT("\tuser table entry %hd\n\ttaf table entry: %hd\n")            DB_TEXT("\tconnection: %08X\n"), ut->u_name, ii, taf, user)    return;unavail:    psp_lmcFree(msg);    reply_non_user(lmcb, user, NULL, 0, L_UNAVAIL);}static void l_logout(    LMCB  *lmcb,    int    user,    void  *msg){    USERTAB *ut = &lmcb->usertab[user];    reply_user(lmcb, user, NULL, 0, L_OKAY);    close_user(lmcb, user);}static void l_terminate(    LMCB  *lmcb,    int    user,    void  *msg){    DEBUG2(DB_TEXT("l_terminate(user = %d)\n"), user);    reply_non_user(lmcb, user, NULL, 0, L_OKAY);    term_flag = 1;}static void l_clearuser(    LMCB      *lmcb,    int        user,    LM_USERID *msg){    short    ii;    USERTAB *ut = lmcb->usertab;    DEBUG2(DB_TEXT("l_clearuser(user = %d)\n"), user)    for (ii = 0; ii < lmcb->numusers; ii++, ut++) {        if (vtstrcmp(ut->u_name, msg->dbuserid) == 0) {            dead_user(lmcb, ii, 1);            break;        }    }    reply_non_user(lmcb, user, NULL, 0, L_OKAY);}static int chk_recover(    LMCB *lmcb,    int   user,    int   type){    int         taf;    short       recstat;    USERTAB    *ut = &lmcb->usertab[user];    USERTAB    *rt;    TAFTAB     *tt;    LR_RECOVER *recover;    if ((taf = ut->u_taf) == -1) {        reply_user(lmcb, user, NULL, 0, L_UNAVAIL);        return 1;    }    /* Check to see if recover needs to be done for somebody or if recover is       already in progress */    tt = &lmcb->taftab[taf];    if ((recstat = tt->t_status) == REC_NEEDED) {        tt->t_status = REC_PENDING;        rt = &lmcb->usertab[ut->u_recuser = tt->t_recuser];        rt->u_status = U_BEING_REC;        recover = psp_lmcAlloc(sizeof(LR_RECOVER));        vtstrcpy(recover->logfile, fileid_get(lmcb->fidtab, rt->u_logfile));        reply_user(lmcb, user, recover, sizeof(LR_RECOVER), L_RECOVER);        return 1;    }    if (recstat == REC_PENDING || (recstat == REC_EXTERNAL &&            (type != L_DBOPEN || tt->t_recuser != user))) {        reply_user(lmcb, user, NULL, 0, L_UNAVAIL);        return 1;    }    return 0;}static void l_dbopen(    LMCB      *lmcb,    int        user,    LM_DBOPEN *msg){    short       ii;    short       jj;    long        kk;    short       new = 0;    short       avail;    short       count;    short       open_slots;    size_t      resp_size;    USERTAB    *ut = &lmcb->usertab[user];    FILETAB    *ft;    LR_DBOPEN  *response;    DB_TCHAR   *names;    DB_TCHAR    filename[FILENMLEN];    DB_TCHAR    lastname[FILENMLEN];    DEBUG4(DB_TEXT("l_dbopen(user = %d, type = %c, nfiles = %d)\n"), user,            msg->type, msg->nfiles)    DEBUG2(DB_TEXT("\tnumfiles = %d\n"), lmcb->numfiles)    if (msg->nfiles > lmcb->maxfiles)        goto unavail;    if (chk_recover(lmcb, user, L_DBOPEN)) {        psp_lmcFree(msg);        return;    }    /* first, verify that 1) if this is an exclusive open then none of the       files are already open and 2) if this is a shared open the none of the       files are already exclusively opened. */    filename[0] = lastname[0] = 0;    for (names = msg->fnames, ii = 0; ii < msg->nfiles; ii++) {        count = (short) *names++;        vtstrcpy(filename, lastname);        vtstrcpy(filename + count, names);        vtstrcpy(lastname, filename);        names += vtstrlen(names) + 1;        if (vtstrlen(filename) == 0)            goto unavail;        if ((kk = fileid_fnd(lmcb->fidtab, filename)) == -1) {            new++;            continue;        }        for (ft = lmcb->filetab, jj = 0; jj < lmcb->numfiles; jj++, ft++) {            if (kk != ft->f_index)                continue;            if (msg->type == 'x' || ft->f_lockstat == 'X')                goto unavail;            if (ft->f_taf != ut->u_taf) {                psp_lmcFree(msg);                reply_user(lmcb, user, NULL, 0, L_BADTAF);                return;            }            break;        }    }    DEBUG2(DB_TEXT("\tnew files = %hd\n"), new);    ft = lmcb->filetab;    for (open_slots = 0, ii = 0; ii < lmcb->numfiles; ii++, ft++) {        if (ft->f_index == -1)            open_slots++;    }    open_slots += lmcb->maxfiles - lmcb->numfiles;    if (new > open_slots)        goto unavail;    resp_size = sizeof(LR_DBOPEN) + (msg->nfiles - 1) * sizeof(short);    response = psp_lmcAlloc(resp_size);    /* We now know that all of the files can be added, go ahead and do it. */    filename[0] = lastname[0] = 0;    for (names = msg->fnames, ii = 0; ii < msg->nfiles; ii++) {        count = (short) *names++;        vtstrcpy(filename, lastname);        vtstrcpy(filename + count, names);        vtstrcpy(lastname, filename);        names += vtstrlen(names) + 1;        if ((kk = fileid_add(lmcb->fidtab, filename)) == -1)            goto unavail;        avail = -1;        for (ft = lmcb->filetab, jj = 0; jj < lmcb->numfiles; jj++, ft++) {            if (kk == ft->f_index)                break;            else if (avail == -1 && ft->f_index == -1)                avail = jj;        }        if (jj == lmcb->numfiles) {            if (avail != -1)                jj = avail;            else                lmcb->numfiles++;            ft = &lmcb->filetab[jj];            ft->f_index = kk;            ft->f_taf = ut->u_taf;            ft->f_lockstat = msg->type == 'x' ? 'X' : 'f';            memset(ft->f_open, 0, lmcb->userbmbytes);            memset(ft->f_lock, 0, lmcb->userbmbytes);            DEBUG3(DB_TEXT("\tnew entry # %d, %s\n"), jj, filename)        }        else {            DEBUG3(DB_TEXT("\told entry # %d, %s\n"), jj, filename);	}        response->frefs[ii] = jj;        bit_set(ft->f_open, user);        bit_set(ut->u_open, jj);    }    psp_lmcFree(msg);    response->nusers = lmcb->taftab[ut->u_taf].t_nusers;    reply_user(lmcb, user, response, resp_size, L_OKAY);    return;unavail:    psp_lmcFree(msg);    reply_user(lmcb, user, NULL, 0, L_UNAVAIL);}static void l_dbclose(    LMCB       *lmcb,    int         user,    LM_DBCLOSE *msg){    short    ii;    short   *fref;    USERTAB *ut = &lmcb->usertab[user];    FILETAB *ft = lmcb->filetab;    DEBUG3(DB_TEXT("l_dbclose(user = %d, nfiles = %hd\n"), user, msg->nfiles)    fref = msg->frefs;    for (ii = 0; ii < msg->nfiles; ii++, fref++) {        if (is_bit_set(ut->u_lock, *fref) && ft[*fref].f_lockstat == 'x')            continue;        freelock(lmcb, user, *fref);        close_file(lmcb, user, *fref);    }    psp_lmcFree(msg);    reply_user(lmcb, user, NULL, 0, L_OKAY);}static void l_lock(    LMCB    *lmcb,    int      user,    LM_LOCK *msg){    int         qptr;    short       ii;    short       locktype;    DB_LOCKREQ *reqs;    USERTAB    *ut = &lmcb->usertab[user];    FILETAB    *ft;    QUEUETAB   *qt;    DEBUG3(DB_TEXT("l_lock(user = %d, nfiles = %hd\n"), user, msg->nfiles)    if (chk_recover(lmcb, user, L_LOCK)) {        psp_lmcFree(msg);        return;    }    /* make sure there is room for these requests on the queue */    if (!room_q(lmcb, msg->nfiles)) {        lmcb->locks_rejected += msg->nfiles;        psp_lmcFree(msg);        reply_user(lmcb, user, NULL, 0, L_QUEUEFULL);        return;    }    /* Make sure all the file reference numbers are valid and that the request       won't be rejected because of an upgrade conflict */    reqs = msg->locks;    for (ii = 0; ii < msg->nfiles; ii++, reqs++) {        if (reqs->fref < 0 || reqs->fref > lmcb->numfiles) {            lmcb->locks_rejected += msg->nfiles;            psp_lmcFree(msg);            reply_user(lmcb, user, NULL, 0, L_SYSERR);            return;        }        /* is this file already locked by this user? */        ft = &lmcb->filetab[reqs->fref];        if (!is_bit_set(ft->f_lock, user))            continue;        /* is this an upgrade request? */        if (ft->f_lockstat != 'r' || reqs->type == 'r' || reqs->type == 'R')            continue;        /* This is an upgrade request.  Has an upgrade request already been           queued up by someone else?  (Upgrade requests are capital letters */        if (ft->f_queue == -1)            continue;        locktype = lmcb->queuetab[ft->f_queue].q_locktype;        if (locktype != 'W' && locktype != 'X')            continue;        /* Our worst fears.  This upgrade request cannot be granted.  This           whole lock request must be rejected. */        DEBUG1(DB_TEXT("\tCannot grant upgrade request\n"))        lmcb->locks_rejected += msg->nfiles;        psp_lmcFree(msg);        reply_user(lmcb, user, NULL, 0, L_UNAVAIL);        return;    }    /* set the # of files that must be locked before the user can proceed */    ut->u_pending = msg->nfiles;    reqs = msg->locks;    for (ii = 0; ii < msg->nfiles; ii++, reqs++) {        ft = &lmcb->filetab[reqs->fref];        DEBUG3(DB_TEXT("\treference # %d for '%c'"), reqs->fref, reqs->type)                /* set the 'requested' bit */        bit_set(ut->u_req, reqs->fref);        /* If this is an upgrade request */        if (is_bit_set(ft->f_lock, user) && ft->f_lockstat == 'r' &&                reqs->type != 'r' && reqs->type != 'R') {            /* place request at head of the queue */            qt = &lmcb->queuetab[qptr = get_q(lmcb)];            qt->q_locktype = (short) toupper(reqs->type);            qt->q_user = user;            ins_head(lmcb, reqs->fref, qptr);            DEBUG1(DB_TEXT("\tupgrade request queued\n"))        }        /* else if this is a downgrade request */        else if (is_bit_set(ft->f_lock, user) && (ft->f_lockstat == 'w' ||                ft->f_lockstat == 'R') && reqs->type == 'r') {            /* it can be granted immediately */            ft->f_lockstat = 'r';            bit_set(ut->u_lock, reqs->fref);            bit_set(ft->f_lock, user);            --ut->u_pending;            ++ut->u_waiting;            DEBUG1(DB_TEXT("\tdowngrade request granted immediately\n"))        }        else {            /* get a queue entry ready */            qt = &lmcb->queuetab[qptr = get_q(lmcb)];            qt->q_locktype = reqs->type;            qt->q_user = user;            /* if this is a Record lock request */            if (reqs->type == 'R') {                /* place this request at the head of the queue, but                   following any existing 'R' requests */                ins_Record(lmcb, reqs->fref, qptr);                DEBUG1(DB_TEXT("\tRecord lock request queued\n"))            }            else {                /* else place this request at the end of the file's queue */                ins_tail(lmcb, reqs->fref, qptr);                DEBUG1(DB_TEXT("\tlock request queued\n"))            }        }    }    psp_lmcFree(msg);    /* lock whatever is lockable */    lock_all(lmcb);    /* start the clock */    if (ut->u_timeout > 0) {        while ((ut->u_timer = psp_timeMilliSecs()) == 0)            ;    }    lock_reply(lmcb);}static void l_free(    LMCB    *lmcb,    int      user,    LM_FREE *msg){    short  ii;    short *file;    DEBUG3(DB_TEXT("l_free(user = %d, nfiles = %d)\n"), user, msg->nfiles)    for (file = msg->frefs, ii = 0; ii < msg->nfiles; ii++, file++)        freelock(lmcb, user, *file);    psp_lmcFree(msg);    /* lock any lockable files */    lock_all(lmcb);    reply_user(lmcb, user, NULL, 0, L_OKAY);     /* grant any locks that are now available */    lock_reply(lmcb);}static void l_trcommit(    LMCB        *lmcb,    int          user,    LM_TRCOMMIT *msg){    long     fid;    USERTAB *ut = &lmcb->usertab[user];    DEBUG3(DB_TEXT("l_trcommit(user=%d, logfile=%s\n"), user, msg->logfile)    fid = fileid_add(lmcb->fidtab, msg->logfile);    psp_lmcFree(msg);    if (fid == -1) {        psp_lmcFree(msg);        reply_user(lmcb, user, NULL, 0, L_UNAVAIL);        return;    }    ut->u_logfile = fid;    /* If the lock manager times out a user while file writes are taking place       it can grant simultaneous rights to write to the file to another user.       Do not allow timeouts to take place once transaction commit begins. */    ut->u_readlocksecs = 0;    ut->u_writelocksecs = 0;    reply_user(lmcb, user, NULL, 0, L_OKAY);}static void l_trend(    LMCB  *lmcb,    int    user,    void  *msg){    short    ii;    USERTAB *ut = &lmcb->usertab[user];    FILETAB *ft;    DEBUG2(DB_TEXT("l_trend(user=%d\n"), user)

⌨️ 快捷键说明

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