📄 trns.c
字号:
/* * trns.c - Transaction service top routine * * This file is a part of GNU SQL Server * * Copyright (c) 1996, 1997, Free Software Foundation, Inc * Developed at the Institute of System Programming * This file is written by Vera Ponomarenko * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Contacts: gss@ispras.ru * *//* $Id: trns.c,v 1.248 1997/04/17 11:03:20 vera Exp $ */#include "setup_os.h"#include "xmem.h"#include <sys/types.h>#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#include <signal.h>#include <sys/ipc.h>#include <sys/msg.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include "destrn.h"#include "strml.h"#include "expop.h"#include "fdcltrn.h"#ifndef CLK_TCK#define CLK_TCK 60#endif/*------ Transaction globals ------------------*/i4_t ljmsize;i4_t ljrsize;i4_t riskdmsz;i4_t IAMM = 0;COST cost = 0L;CPNM curcpn = 1;struct des_nseg desnseg;struct ADREC bllj;struct ADREC blmj;char *pbuflj = bllj.block;char *bufmj = blmj.block;char *pbufmj;struct ldesind **TAB_IFAM;i4_t TIFAM_SZ;struct d_r_t *firstrel = NULL;char **scptab;i2_t maxscan = DTSCAN;i4_t idtr;i4_t minidnt;u2_t trnum;struct ADBL adlj;struct ADBL admj;u2_t EXNSSIZE;u2_t S_SC_S;struct dmbl_head *ffrdmbl;struct dmbl_head *lfrdmbl;/*---------------------------------------------*/pid_t parent;static key_t keyadm, keylj, keymj, keybf, keysn, keysr, keytrn;i4_t msqida, msqidl, msqidm, msqidb, msqids, msqidq, msqidt;/*i4_t sser, ns;*/extern i4_t errno;i4_t TRNUM, N_AT_SEG = 0;char *savestring (char *);#define ARG(num, what, type) sscanf (args[num], "%d", &argum); \ what = (type)(argum)#define PRINT(x, y) /*printf(x, y);*/voidtrans_init (i4_t argc,char *args[]){ i4_t n; struct des_exns *desext; struct msg_buf sbuf; i4_t extssize, s_sc_s; char **s; i4_t argum; setbuf (stdout, NULL); ARG(1, keytrn, key_t); ARG(2, keysn, key_t); ARG(3, keysr, key_t); ARG(4, keylj, key_t); ARG(5, keymj, key_t); ARG(6, keybf, key_t); ARG(7, TRNUM, i4_t); trnum = TRNUM + CONSTTR; ARG(8, minidnt, i4_t); ARG(9, extssize, i4_t); EXNSSIZE = extssize; ARG(10, s_sc_s, i4_t); ARG(14, parent, pid_t); ARG(15, keyadm, key_t); S_SC_S = s_sc_s; if ((msqidt = msgget (keytrn, IPC_CREAT | DEFAULT_ACCESS_RIGHTS)) < 0) { perror ("TRN.msgget: Queue for TRN"); exit (1); } MSG_INIT (msqidl, keylj, "LJ"); MSG_INIT (msqidm, keymj, "MJ"); MSG_INIT (msqida, keyadm, "ADM"); MSG_INIT (msqidb, keybf, "BUF"); MSG_INIT (msqids, keysn, "SYN"); MSG_INIT (msqidq, keysr, "SORT"); TIFAM_SZ = 2; TAB_IFAM = (struct ldesind **) xmalloc (TIFAM_SZ * sizeof (struct ldesind **)); TAB_IFAM[0] = NULL; TAB_IFAM[1] = NULL; tab_difam (1); adlj.cm = 0; ljmsize = size1b + size4b + 2 * size2b + size2b + size4b + 2 * size2b + tidsize; ljrsize = size1b + size4b + 2 * size2b; scptab = (char **) xmalloc (chpsize * maxscan); for (n = 0; n < maxscan; n++) scptab[n] = NULL; desnseg.lexnum = 0; desnseg.mexnum = DEXTD; desnseg.dextab = (struct des_exns *) xmalloc (dexsize * DEXTD); for (n = 0, desext = desnseg.dextab; n < DEXTD; n++, desext++) desext->efpn = (u2_t) ~ 0; desnseg.mtobnum = TOBPTD; desnseg.tobtab = (char **) xmalloc (chpsize * TOBPTD); for (n = 0, s = desnseg.tobtab; n < TOBPTD; n++) s[n] = NULL; sbuf.mtype = START; t2bpack (trnum, sbuf.mtext); __MSGSND(msqids, &sbuf, size2b, 0,"TRN.msgsnd: START to SYN");} /* trans_init */#undef ARGintsvpnt (void){ struct msg_buf sbuf; struct id_rel idr; sbuf.mtype = SVPNT; t2bpack (trnum, sbuf.mtext); __MSGSND(msqids, &sbuf, size2b, 0,"TRN.msgsnd: SVPNT to SYN"); __MSGRCV(msqids, &sbuf, cpnsize, trnum, 0,"TRN.msgrcv: SVPNT from SYN"); curcpn = *(CPNM *) sbuf.mtext; wmlj (CPRLJ, ljrsize + cpnsize, &adlj, &idr, NULL, curcpn); return (curcpn);}intkilltran (void){ struct msg_buf sbuf; u2_t n, num_tob; struct des_tob *dt; if (IAMM != 0) { t2bpack (WLJET, sbuf.mtext); ADM_SEND (TRNUM, size2b, "TRN.msgsnd: WLJET to ADM"); __MSGRCV(msqidl, &sbuf, 0, trnum, 0,"TRN.msgrcv: Answer from LJ"); } num_tob = desnseg.mtobnum; for (n = 0; n < num_tob; n++) { dt = (struct des_tob *) *(desnseg.tobtab + n); if (dt != NULL) { delscd (dt->osctob, (char *) dt); xfree ((void *) dt); } } sbuf.mtype = COMMIT; t2bpack (trnum, sbuf.mtext); __MSGSND(msqids, &sbuf, size2b, 0,"TRN.msgsnd: COMMIT to SYN"); __MSGRCV(msqids, &sbuf, 0, trnum, 0,"TRN.msgrcv: COMMIT from SYN"); return (OK);}intclosesc (i4_t scnum){ char **t, sctype; struct d_mesc *scpr; struct d_r_t *desrel; struct d_sc_i *scind; struct ldesscan *desscan; struct des_tob *dt; if (scnum > maxscan) return (NDSC); t = scptab + scnum; scpr = (struct d_mesc *) * t; if (scpr == NULL) return (NDSC); if ((sctype = scpr->obsc) == SCR) { /* relation scan */ desrel = (struct d_r_t *) scpr->pobsc; desrel->oscnum--; scind = (struct d_sc_i *) scpr; desscan = &scind->dessc; if (desscan->cur_key != NULL) { xfree ((void *) desscan->cur_key); } } else if (sctype == SCI) { /* index scan */ scind = (struct d_sc_i *) scpr; desscan = &scind->dessc; if (desscan->cur_key != NULL) { xfree ((void *) desscan->cur_key); } desscan->pdi->oscni--; } else if (sctype == SCTR || sctype == SCF) { dt = (struct des_tob *) scpr->pobsc; dt->osctob--; } else return (NDSC); xfree ((void *) *t); *t = NULL; return (OK);}intmempos (i4_t scnum){ struct d_mesc *scpr; struct d_sc_r *screl; struct d_sc_i *scind; struct d_sc_f *scfltr; char sctype; scpr = (struct d_mesc *) * (scptab + scnum); if (scnum >= maxscan || scpr == NULL) return (NDSC); if ((sctype = scpr->obsc) == SCTR) { /* temporary relation scan */ screl = (struct d_sc_r *) scpr; screl->memtid = screl->curtid; } else if (sctype == SCI || sctype == SCR) { /* index scan */ scind = (struct d_sc_i *) scpr; scind->dessc.mtidi = scind->dessc.ctidi; } else if (sctype == SCF) { scfltr = (struct d_sc_f *) scpr; scfltr->mpnf = scfltr->pnf; scfltr->mofff = scfltr->offf; } return (OK);}intcurpos (i4_t scnum){ struct d_mesc *scpr; struct d_sc_r *screl; struct d_sc_i *scind; struct d_sc_f *scfltr; char sctype; scpr = (struct d_mesc *) * (scptab + scnum); if (scnum >= maxscan || scpr == NULL) return (NDSC); if ((sctype = scpr->obsc) == SCTR) { /* temporary relation scan */ screl = (struct d_sc_r *) scpr; screl->curtid = screl->memtid; } else if (sctype == SCI || sctype == SCR) { /* index scan */ scind = (struct d_sc_i *) scpr; scind->dessc.ctidi = scind->dessc.mtidi; } else if (sctype == SCF) { scfltr = (struct d_sc_f *) scpr; scfltr->pnf = scfltr->mpnf; scfltr->offf = scfltr->mofff; } return (OK);}voidmodmes (void){ struct msg_buf sbuf; if (IAMM != 0) return; t2bpack (IAMMOD, sbuf.mtext); ADM_SEND (TRNUM, size2b, "TRN.msgsnd: IAMMOD to ADM"); __MSGRCV(msqidt, &sbuf, size4b, (i4_t) trnum, 0,"TRN.msgrcv: IAMMOD from ADM"); idtr = t4bunpack (sbuf.mtext); IAMM++; return;}i4_tuniqnm (void){ i4_t uniq_name; struct msg_buf sbuf; t2bpack (UNIQNM, sbuf.mtext); ADM_SEND (TRNUM, size2b, "TRN.msgsnd: uniqnm to ADM"); __MSGRCV(msqidt, &sbuf, size4b, (i4_t) trnum, 0,"TRN.msgrcv: uniqnm from ADM"); uniq_name = t4bunpack (sbuf.mtext); return (uniq_name);}CPNMsn_lock (struct id_rel *pidrel, i4_t t, char *lc, i4_t sz){ char *p; struct msg_buf sbuf; CPNM cpn; sbuf.mtype = LOCK; p = sbuf.mtext; BUFPACK(trnum,p); BUFPACK(*pidrel,p); BUFPACK(cost,p); *p++ = t; BUFPACK(sz,p); bcopy (lc, p, sz); p += sz; __MSGSND(msqids, &sbuf, p - sbuf.mtext, 0,"TRN.msgsnd: LOCK to SYN"); __MSGRCV(msqids, &sbuf, cpnsize, trnum, 0,"TRN.msgrcv: LOCK from SYN"); cpn = *(CPNM *) sbuf.mtext; return (cpn);}voidsn_unltsp (CPNM cpn){ struct msg_buf sbuf; char *p; sbuf.mtype = UNLTSP; p = sbuf.mtext; BUFPACK(trnum,p); BUFPACK(cpn,p); __MSGSND(msqids, &sbuf, cpnsize + size2b, 0,"TRN.msgsnd: UNLTSP to SYN"); __MSGRCV(msqids, &sbuf, 0, trnum, 0,"TRN.msgrcv: UNLTSP from SYN");}static voidsort (i4_t type, u2_t sn, u2_t * fpn, struct des_field *df, u2_t fn, u2_t fdfn, u2_t * fsrt, u2_t kn, char prdbl, char *drctn, u2_t * lpn){ u2_t n; char *p; struct msg_buf sbuf; COST cost1; sbuf.mtype = type; p = sbuf.mtext; BUFPACK(trnum,p); BUFPACK(*fpn,p); BUFPACK(fn,p); BUFPACK(fdfn,p); for (; fn != 0; fn--, df++) BUFPACK(*df,p); if (type == FLSORT) BUFPACK(sn,p); BUFPACK(kn,p); for (n = kn; n != 0; n--, fsrt++) BUFPACK(*fsrt,p); *p++ = prdbl; bcopy (drctn, p, kn); p += kn; PRINTF (("TRN.sort: trnum = %d\n", trnum)); __MSGSND(msqidq, &sbuf, p - sbuf.mtext, 0,"TRN.msgsnd: SORT to SRT"); __MSGRCV(msqidq, &sbuf, 2 * size2b + sizeof (COST), trnum, 0, "TRN.msgrcv: SORT from SRT"); p = sbuf.mtext; BUFUPACK(p,*fpn); BUFUPACK(p,*lpn); BUFUPACK(p,cost1); cost += cost1;}voidsrtr_trsort (u2_t * fpn, struct des_field *df, u2_t fn, u2_t fdfn, u2_t * fsrt,u2_t kn, char prdbl, char *drctn, u2_t * lpn){ sort (TRSORT, 0, fpn, df, fn, fdfn, fsrt, kn, prdbl, drctn, lpn);}voidsrtr_flsort (u2_t sn, u2_t * fpn, struct des_field *df, u2_t fn, u2_t fdfn, u2_t * mfn, u2_t kn, char prdbl, char *drctn, u2_t * lpn){ sort (FLSORT, sn, fpn, df, fn, fdfn, mfn, kn, prdbl, drctn, lpn);}voidsrtr_tid (struct des_tob *dt){ char *p; struct msg_buf sbuf; COST cost1; u2_t fpn, lpn; sbuf.mtype = TIDSRT; p = sbuf.mtext; BUFPACK(trnum,p); BUFPACK(dt->firstpn,p); __MSGSND(msqidq, &sbuf, 2 * size2b, 0,"TRN.msgsnd: SORT to SRT"); __MSGRCV(msqidq, &sbuf, 2 * size2b + sizeof (cost1), trnum, 0, "TRN.msgrcv: SORT from SRT"); p = sbuf.mtext; BUFUPACK(p,fpn); BUFUPACK(p,lpn);dt->firstpn = fpn;dt->lastpn = lpn; BUFUPACK(p,cost1); cost += cost1;}voidLJ_GETREC (struct ADBL *pcadlj){ char *p; struct msg_buf sbuf; sbuf.mtype = GETREC; p = sbuf.mtext; t2bpack (trnum, p); p += size2b; bcopy ((char *) pcadlj, p, adjsize); __MSGSND(msqidl, &sbuf, adjsize + size2b, 0,"TRN.msgsnd: LJ GETREC"); __MSGRCV(msqidl, &sbuf, sizeof (struct ADREC), trnum, 0,"TRN.msgrcv: Answer from LJ"); p = sbuf.mtext; bllj.razm = t2bunpack (p); p += size2b; bcopy (p, pbuflj, bllj.razm);}voidADMT_getext (u2_t * pn){ struct msg_buf sbuf; t2bpack (GETEXT, sbuf.mtext); /* PRINT ("TRN.ADMT_getext before send: TRNUM = %d\n", (i4_t)TRNUM)*/ ADM_SEND (TRNUM, size2b, "TRN.msgsnd: GETEXT to ADM"); /* PRINT ("TRN.ADMT_getext before receive: msqidt = %d\n", (i4_t)msqidt)*/ /* PRINT ("TRN.ADMT_getext before receive: trnum = %d\n", (i4_t)trnum)*/ __MSGRCV(msqidt, &sbuf, size2b, trnum, 0,"TRN.msgrcv: GETEXT from ADM"); PRINT ("TRN.ADMT_getext after receive: sbuf.mtype = %d\n", (i4_t)sbuf.mtype) *pn = t2bunpack (sbuf.mtext);}voidADMT_putext (u2_t * mfpn, u2_t cnt){ struct msg_buf sbuf; u2_t *p, *a; p = (u2_t *) sbuf.mtext; *p++ = PUTEXT; *p++ = cnt; for (a = p + cnt; p < a;) *p++ = *mfpn; /* PRINT ("TRN.ADMT_putext before receive: msqida = %d\n", (i4_t)msqida)*/ /* PRINT ("TRN.ADMT_putext before receive: TRNUM = %d\n", (i4_t)TRNUM)*/ ADM_SEND (TRNUM, (2 + cnt) * size2b, "TRN.msgsnd: PUTEXT to ADM");}voidBUF_endop (void){ struct msg_buf sbuf; sbuf.mtype = ENDOP; __MSGSND(msqidb, &sbuf, 0, 0,"TRN.msgsnd: ENDOP to BUF"); assert (N_AT_SEG == 0);}voiderror (char *s){ printf ("error: %s\n", s); exit (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -