/* PROGRAM: dsmDatabaseProcessEvents - perform xxx processing * * NOTE: Quiet points and tmdelayed commit are supported here * * RETURNS: DSM_S_SUCCESS * DSM_S_INVALID_USER * DSM_S_SHUT_DOWN on EXBAD or EXGOOD */ dsmStatus_t dsmDatabaseProcessEvents( dsmContext_t *pcontext) { dbcontext_t *pdbcontext = pcontext->pdbcontext; dbshm_t *pdbshm = pdbcontext->pdbpub; usrctl_t *pusr = pcontext->pusrctl; mstrblk_t *pmstr; dsmStatus_t returnCode; #if OPSYS==WIN32API if (fWin95) return -1; #endif pdbcontext->inservice++; /* "post-pone" signal handling while in DSM API */ SETJMP_ERROREXIT(pcontext, returnCode) /* Ensure error exit address set */ if ((returnCode = dsmThreadSafeEntry(pcontext)) != DSM_S_SUCCESS) { returnCode = dsmEntryProcessError(pcontext, returnCode, (TEXT *)"dsmDatabaseProcessEvents"); goto done; } /* Check for quiet point command requests */ if (pdbshm->quietpoint == QUIET_POINT_REQUEST) { /* Shut off update activity for the quiet point */ rlTXElock(pcontext,RL_TXE_EXCL,RL_MISC_OP); MT_LOCK_MTX(); pmstr = pdbcontext->pmstrblk; /* Switch after imaging extent if there are ai extents */ if( rlaiqon(pcontext) && pmstr->mb_aibusy_extent > 0 ) { MT_LOCK_AIB(); if (rlaiswitch(pcontext, (int)RLAI_NEW, 1) ) { MT_UNLK_AIB(); /* Unable to switch to new ai extent */ MSGN_CALLBACK(pcontext, drMSG205); if ( MTHOLDING(MTL_MTX) ) MT_UNLK_MTX(); if ( pusr->uc_txelk ) rlTXEunlock(pcontext); goto done; } MT_UNLK_AIB(); } /* Flush the buffer pool and bi buffers */ rlbiflsh(pcontext,RL_FLUSH_ALL_BI_BUFFERS); /* At this point, the quiet point is in place */ MSGN_CALLBACK(pcontext, drMSG402); pdbshm->quietpoint = QUIET_POINT_ENABLED; while(pdbshm->quietpoint == QUIET_POINT_ENABLED && !pdbshm->shutdn) { utsleep(1); } MT_UNLK_MTX(); rlTXEunlock(pcontext); /* Release transaction end lock */ /* At this point, normal operations can return */ MSGN_CALLBACK(pcontext, drMSG403); pdbshm->quietpoint = QUIET_POINT_NORMAL; } /* Process delayed commit (-Mf) */ tmchkdelay(pcontext, 0); /* Check if table locking can be shut off */ lkTableLockCheck(pcontext); returnCode = DSM_S_SUCCESS; done: dsmThreadSafeExit(pcontext); pdbcontext->inservice--; /* re-allow signal handling */ return returnCode; } /* end dsmDatabaseProcessEvents */
/* PROGRAM: rlmemwt - write the transaction table and phy. backout flag * into an rlnote * * RETURNS: DSMVOID */ DSMVOID rlmemwt(dsmContext_t *pcontext) { dbcontext_t *pdbcontext = pcontext->pdbcontext; dbshm_t *pdbpub = pdbcontext->pdbpub; MEMNOTE note; TEXT *ptx; TX *ptrn; TEXT *pdata; COUNT dlen; TRANTAB *ptran = pdbcontext->ptrantab; int i,j,numToGo; TRACE_CB(pcontext, "rlmemwt") INITNOTE(note, RL_INMEM, RL_PHY ); note.rlpbkout = pdbcontext->prlctl->rlpbkout; note.lasttask = pdbcontext->pmstrblk->mb_lasttask; note.numLive = pdbcontext->ptrantab->numlive; note.numMemnotes = (note.numLive / (UCOUNT)MAX_ENTRIES_PER_NOTE) + 1; note.tmsize = sizeof (TX) - sizeof(txPlus_t); /* This is a funny note. It describes physical state but since no action is taken and no database blocks depend on it so we'll write it with... */ note.rlnote.rlArea = 0; /* bug 20000114-034 by dmeyer in v9.1b */ note.rlnote.rldbk = 0; note.rlnote.rlupdctr = 0; note.spare[0] = 0; note.spare[1] = 0; /* put 0 in the trn id part of the note */ note.rlnote.rlTrid = 0; if ( ptran->numlive > MAX_ENTRIES_PER_NOTE ) note.numThisNote = MAX_ENTRIES_PER_NOTE; else note.numThisNote = ptran->numlive; dlen = note.numThisNote * note.tmsize; /* bug 93-01-21-035: use stRent instead of stkpush */ pdata = (TEXT *)stRentd (pcontext, pdsmStoragePool, (unsigned)dlen); numToGo = ptran->numlive; ptrn = ptran->trn; for ( j = 0; j < (int)note.numMemnotes; j++) { note.noteSequence = j + 1; MT_LOCK_AIB(); note.aiupdctr = pdbcontext->pmstrblk->mb_aictr; note.ainew = pdbcontext->pmstrblk->mb_ai.ainew; if(pdbcontext->ptlctl) { note.tlWriteBlockNumber = pdbcontext->ptlctl->writeLocation; note.tlWriteOffset = pdbcontext->ptlctl->writeOffset; } else { note.tlWriteBlockNumber = 0; note.tlWriteOffset = 0; } if (pdbpub->qaictl) note.aiwrtloc = pdbcontext->paictl->ailoc + pdbcontext->paictl->aiofst; else note.aiwrtloc = 0; /* bug 20000114-034 by dmeyer in v9.1b */ MT_UNLK_AIB(); for(i=note.numThisNote, ptx = pdata; i > 0; ptrn++) { /* Only copy the transaction if it is in an active state */ if (ptrn->txstate && (ptrn->txstate != TM_TS_ALLOCATED) ) { bufcop (ptx, (TEXT *)ptrn, note.tmsize); ptx += note.tmsize; i--; } } /* Why not just use rlputnote here? */ rlwrite(pcontext, (RLNOTE *)¬e, dlen, pdata); if (rlainote (pcontext, (RLNOTE *)¬e)) { /* write note to ai also. Notice that the ai information which is recorded in the note will change when we do this. */ MT_LOCK_AIB (); rlaiwrt (pcontext, (RLNOTE *)¬e, dlen, pdata, ++pdbcontext->pmstrblk->mb_aictr, pcontext->pusrctl->uc_lstdpend); MT_UNLK_AIB (); } numToGo -= note.numThisNote; if( numToGo > MAX_ENTRIES_PER_NOTE ) note.numThisNote = MAX_ENTRIES_PER_NOTE; else { note.numThisNote = numToGo; dlen = numToGo * note.tmsize; } } /* bug 93-01-21-035: use stVacate instead of stkpop */ stVacate (pcontext, pdsmStoragePool, pdata); /* Write out the ready to commit tx table if there any */ if( pdbcontext->ptrcmtab != NULL ) rlrctwt(pcontext); } /* end rlmemwt */