unlock.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:4k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  * unlock.c - Unlock, Kernel of GNU SQL-server. Synchronizer
  3.  *
  4.  *  This file is a part of GNU SQL Server
  5.  *
  6.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  7.  *  Developed at the Institute of System Programming
  8.  *  This file is written by  Vera Ponomarenko
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23.  *
  24.  *  Contacts:   gss@ispras.ru
  25.  *
  26.  */
  27. /* $Id: unlock.c,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  28. #include "setup_os.h"
  29. #include "dessnch.h"
  30. #include "fdclsyn.h"
  31. #include <assert.h>
  32. extern struct des_rel *firstrel;
  33. static void
  34. delsrd (struct des_rel *r) /* To delete the relation descriptor */
  35. {
  36.   if (r->brellist == NULL)
  37.     firstrel = r->frellist;
  38.   else
  39.     r->brellist->frellist = r->frellist;
  40.   if (r->frellist != NULL)
  41.     r->frellist->brellist = r->brellist;
  42.   xfree ((void *) r);
  43. }
  44. int
  45. unlock (struct des_tran *tr, struct des_lock *alock)
  46. {
  47.   struct des_lock *a, *bl, *pa, *ff, *wff;
  48.   struct des_wlock *a1, *aw;
  49.   struct des_rel *r;
  50.   i4_t size, k;
  51.   u2_t pn, ind, *a2b;
  52.   char *ab1, *ab2;
  53.   COST newcost;
  54.   ff = (struct des_lock *) tr->firstfree;
  55.   for (a = alock; a < ff;)
  56.     { /* the first pass along unlock locks */
  57.       if ((k = a->dls) != cpsize)
  58. {
  59.   /* remove the lock from the relation locks list */
  60.   lilore (a->rel, a, a->of, a->ob);
  61.   if (a->lockin == 'm' && (pa = a->rel->rof) != NULL && a < a->tran->pwlock)
  62.     {
  63.       r = a->rel;
  64.       delsrd (r);
  65.       a2b = (u2_t *) ((char *) a + locksize);
  66.       pn = *a2b++;
  67.       ind = *a2b;
  68.       r = crtsrd (tr->idtr,&r->idrel, pn, ind);
  69.       r->rof = pa;
  70.     }
  71. }
  72.       a = (struct des_lock *) ((char *) a + k);
  73.     }
  74.   if ((aw = (struct des_wlock *) tr->pwlock) != NULL)
  75.     {
  76.       bl = aw->Dup; /* the block lock address */
  77.       if (bl->Ddown == aw)
  78.         bl->Ddown = aw->Dqueue;
  79.       else
  80.         {
  81.           for (a1 = bl->Ddown; a1 != NULL; a1 = a1->Dqueue)
  82.             if (a1->Dqueue == aw)
  83.               break;
  84.           assert(a1); /* this lock must exist */
  85.           a1->Dqueue = aw->Dqueue;
  86.         }
  87.     }
  88.   for (; alock < ff;)
  89.     { /* the second pass along unlock locks */
  90.       if ((k = alock->dls) != cpsize)
  91. /* the cycle on suns in the block queue */
  92. for (aw = alock->Ddown; aw != NULL; aw = a1)
  93.   {
  94.     a1 = aw->Dqueue;
  95.     size = aw->l.dls - wlocksize;
  96.     ab1 = (char *) aw + wlocksize;
  97.     if (alock->ob == NULL)
  98.       bl = alock->rel->rof;
  99.     else
  100.       bl = alock->ob->of;
  101.     if (shartest ((struct des_lock *) aw, size, ab1, bl) != 0)
  102.               continue; /* not shared */
  103.     tr = aw->l.tran;
  104.             /*     f = tr->firstfree;*/
  105.     ab1 = (char *) aw + locksize;
  106.             ab2 = (char *) aw + wlocksize;
  107.     newcost = aw->newcost;
  108.             size = tr->firstfree - ab2;
  109.             bcopy (ab2, ab1, size);
  110.     aw->l.dls -= wlsize;
  111.     tr->freelb += wlsize;
  112.     tr->firstfree -= wlsize;
  113.     wff = (struct des_lock *) tr->firstfree;
  114.     tr->pbltr = NULL;
  115.     a = (struct des_lock *) ((char *) aw + aw->l.dls);
  116.     for (; a < wff; a = (struct des_lock *) ((char *) a + a->dls))
  117.       refrem (a);
  118.     for (; a < wff;)
  119.       {
  120. size = a->dls - locksize;
  121. if (shartest (a, size, (char *) a + locksize, bl) != 0)
  122.   {
  123.     /* a wait lock isn't satisfyed */
  124.     ((struct des_wlock *) a)->newcost = newcost;
  125.     return (0);
  126.   }
  127. /* a wait lock is satisfyed */
  128. a = (struct des_lock *) ((char *) a + a->dls);
  129.       }
  130.     tr->pwlock = NULL;
  131.     tr->trcost = newcost;
  132.     answer_opusk (tr->idtr, (CPNM) 0);
  133.   }
  134.       alock = (struct des_lock *) ((char *) alock + k);
  135.     }
  136.   return (0);
  137. }
  138. void
  139. lilore (struct des_rel *r, struct des_lock *a, struct des_lock *f, struct des_lock *b)
  140. {
  141.   if (a->ob == NULL)
  142.     r->rof = f; /* if the lock is first in the list */
  143.   else
  144.     a->ob->of = f;
  145.   if (a->of == NULL)
  146.     r->rob = b; /* if the lock is last */
  147.   else
  148.     a->of->ob = b;
  149. }