1: # include "../ingres.h" 2: # include "../tree.h" 3: # include "decomp.h" 4: # include "../lock.h" 5: /* 6: ** lockit - sets relation locks for integrity locking 7: ** 8: ** arguements: 9: ** root- the root of a query tree; 10: ** resvar- index of variable to be updated. 11: ** 12: */ 13: lockit(root, resvar) 14: struct querytree *root; 15: int resvar; 16: { 17: register struct querytree *r; 18: register int i, j; 19: long vlist[MAXRANGE]; 20: int bmap, cv; 21: char mode; 22: int skvr; 23: int redo; 24: struct descriptor *d, *openr1(); 25: long restid; 26: int k; 27: 28: r = root; 29: bmap = ((struct qt_root *)r)->lvarm | ((struct qt_root *)r)->rvarm; 30: if (resvar >= 0) 31: bmap |= 01 << resvar; 32: else 33: restid = -1; 34: i = 0; 35: /* put relids of relations to be locked into vlist 36: check for and remove duplicates */ 37: for (j = 0; j < MAXRANGE; j++) 38: if (bmap & (01 << j)) 39: { 40: d = openr1(j); 41: if (j == resvar) 42: restid = d->reltid; 43: for (k = 0; k < i; k++) 44: if (vlist[k] == d->reltid) 45: break; 46: if (k == i) 47: vlist[i++] = d->reltid; 48: } 49: cv = i; 50: /* 51: * set the locks: set the first lock with the sleep option 52: * set other locks checking for failure; 53: * if failure, release all locks, sleep on blocking 54: * lock. 55: */ 56: skvr = -1; 57: do 58: { 59: /* skvr is the index of the relation already locked 60: try to lock the remaining relations */ 61: redo = FALSE; 62: for (i = 0; i < cv; i++) 63: if (i != skvr) 64: { 65: if (restid == vlist[i]) 66: mode = M_EXCL; 67: else 68: mode = M_SHARE; 69: if (setrll(A_RTN, vlist[i], mode) < 0) 70: /* a lock request failed */ 71: { 72: unlall(); /* release all locks */ 73: setrll(A_SLP, vlist[i], mode); 74: /* wait on problem lock*/ 75: skvr = i; 76: redo = TRUE; 77: break; /* reset the other locks */ 78: } 79: } 80: } 81: while (redo); 82: }