예제 #1
0
파일: rt_sansm.c 프로젝트: siamect/proview
static void removeServer(gdb_sNode* np, san_sServer* sp)
{
  hash_Remove(NULL, gdbroot->sans_ht, sp);

  if (sp->flags.b.sansAct) {
    pool_Qremove(NULL, gdbroot->pool, &sp->sansAct_ll);
    np->sansAct_lc--;
    np->sans_gen++;
  }
  if (sp->flags.b.sansUpd)
    pool_Qremove(NULL, gdbroot->pool, &sp->sansUpd_ll);

  pool_Free(NULL, gdbroot->pool, sp);
}
예제 #2
0
void
cvolsm_RemoveMountedOn (
  pwr_tStatus		*sts,
  gdb_sMountedOn	*mop
)
{

  gdb_AssumeLocked;

  pool_Qremove(NULL, gdbroot->pool, &mop->nodmo_ll);
  pool_Qremove(NULL, gdbroot->pool, &mop->volmo_ll);

  pool_Free(NULL, gdbroot->pool, mop);
}
예제 #3
0
파일: rt_cvolcm.c 프로젝트: siamect/proview
void cvolcm_FlushNode(pwr_tStatus* sts, gdb_sNode* np)
{
  pool_sQlink* vl;
  gdb_sVolume* vp;
  gdb_sCclassVolume* cvp;
  pwr_tStatus lsts;

  gdb_AssumeLocked;
  pwr_Assert(np != gdbroot->my_node && np != gdbroot->no_node);

  for (vl = pool_Qsucc(NULL, gdbroot->pool, &np->own_lh); vl != &np->own_lh;
       vl = pool_Qsucc(NULL, gdbroot->pool, &np->own_lh)) {
    vp = pool_Qitem(vl, gdb_sVolume, l.own_ll);
    pwr_Assert(vp->l.flags.b.isCached);
    if (vp->l.flags.b.isCached)
      cvolcm_FlushVolume(NULL, vp);
  }

  for (vl = pool_Qsucc(NULL, gdbroot->pool, &np->ccvol_lh); vl != &np->ccvol_lh;
       vl = pool_Qsucc(NULL, gdbroot->pool, &np->ccvol_lh)) {
    cvp = pool_Qitem(vl, gdb_sCclassVolume, ccvol_ll);

    hash_Remove(&lsts, gdbroot->ccvol_ht, cvp);
    if (EVEN(lsts))
      errh_Bugcheck(lsts, "cached class volume inconsistency");

    pool_Qremove(NULL, gdbroot->pool, &cvp->ccvol_ll);
    pool_Free(NULL, gdbroot->pool, cvp);
  }
}
예제 #4
0
파일: rt_cvolcm.c 프로젝트: siamect/proview
void cvolcm_ExternVolumeFlush(gdb_sNode* np)
{
  pool_sQlink* vl;
  gdb_sVolume* vp;
  pool_sQlink* ol;
  gdb_sObject* op;
  gdb_sMountServer* msp;
  pwr_tStatus sts;

  // Flush local node
  gdb_AssumeLocked;

  for (vl = pool_Qsucc(NULL, gdbroot->pool, &np->own_lh); vl != &np->own_lh;
       vl = pool_Qsucc(NULL, gdbroot->pool, vl)) {
    vp = pool_Qitem(vl, gdb_sVolume, l.own_ll);
    pwr_Assert(vp->l.flags.b.isCached);
    if (vp->l.flags.b.isCached) {
      for (ol = pool_Qsucc(NULL, gdbroot->pool, &vp->l.obj_lh);
           ol != &vp->l.obj_lh;
           ol = pool_Qsucc(NULL, gdbroot->pool, &vp->l.obj_lh)) {
        op = pool_Qitem(ol, gdb_sObject, l.obj_ll);
        if (op->l.flags.b.isMountServer) {
          msp = (gdb_sMountServer*)hash_Search(
              &sts, gdbroot->ms_ht, &op->g.oid);
          if (msp == NULL)
            errh_Bugcheck(sts, "mount server inconsitency");
          msp->msor = pool_cNRef;
          pool_Qremove(NULL, gdbroot->pool, &msp->nodms_ll);
          /* Todo !!! Clear alarm and blocklevel in all mount clients. */
        }
        cvol_FlushObject(op);
      }
    }
  }
}
예제 #5
0
void *
hash_Remove (
  pwr_tStatus		*sts,
  hash_sTable		*htp,
  void			*ip		/* Address of item to be removed.  */
)
{
  hash_sGtable		*ghtp;
  pool_sQlink		*il;
  pool_sQlink		*bl;


  ghtp = htp->ghtp;
  ghtp->removes++;

  il = findEntry(sts, &bl, htp, (char *)ip + ghtp->key_offset);
  if (il == NULL) return NULL;

  il = pool_Qremove(sts, htp->php, il);
  if (il == NULL)
    return NULL;

  ghtp->entries--;
  if (bl->flink == bl->self)
    ghtp->used_buckets--;

  pwr_Return(ip, sts, HASH__SUCCESS);
}
예제 #6
0
void
cvolcm_FlushVolume (
  pwr_tStatus		*sts,
  gdb_sVolume		*vp 
)
{
  pool_sQlink		*ol;
  gdb_sObject		*op;
  gdb_sMountServer	*msp;

  gdb_AssumeLocked;

  for (
    ol = pool_Qsucc(NULL, gdbroot->pool, &vp->l.obj_lh);
    ol != &vp->l.obj_lh;
    ol = pool_Qsucc(NULL, gdbroot->pool, &vp->l.obj_lh)
  ) {
    op = pool_Qitem(ol, gdb_sObject, l.obj_ll);
    if (op->l.flags.b.isMountServer) {
      msp = hash_Search(sts, gdbroot->ms_ht, &op->g.oid);
      if (msp == NULL) errh_Bugcheck(*sts, "mount server inconsitency");
      msp->msor = pool_cNRef;
      pool_Qremove(NULL, gdbroot->pool, &msp->nodms_ll);
      /* Todo !!! Clear alarm and blocklevel in all mount clients. */
    }
    cvol_FlushObject(op);
  }
  
  pwr_Assert(vp->l.flags.b.inOwnList);
  pool_Qremove(NULL, gdbroot->pool, &vp->l.own_ll);
  vp->l.flags.b.inOwnList = 0;
  vp->g.nid = pwr_cNNodeId;

  pwr_Assert(pool_QisEmpty(NULL, gdbroot->pool, &vp->u.c.cacheLock.lh));
  pwr_Assert(vp->u.c.cacheLock.lc == 0);
  pwr_Assert(pool_QisEmpty(NULL, gdbroot->pool, &vp->u.c.cacheVol.lh));
  pwr_Assert(vp->u.c.cacheVol.lc == 0);

  vp->l.flags.b.isConnected = 0;
  vp->l.flags.b.isCached = 0;
  vp->l.flags.b.netCached = 0;
  vp->l.flags.b.remote = 0;
}
예제 #7
0
void
subs_DeleteServer (
  sub_sServer		*sp
)
{
  pwr_tStatus		sts;
  sub_sBuffer		*bp;
  gdb_sObject		*op;

  gdb_AssumeLocked;

  bp = pool_Address(NULL, gdbroot->pool, sp->br);

  /* Disconnect from buffer. If the number of servers connected
     to the buffer reaches zero, the buffer gets disposed when
     it times out the next time.  */

  pool_Qremove(NULL, gdbroot->pool, &sp->bufsubs_ll);
  bp->bufsubs_lc -= 1;
  bp->totsize -= sp->aref.Size;

  /* Now give the subsrv entry back to the pool.  */

  pool_Qremove(NULL, gdbroot->pool, &sp->subs_ll);
  gdbroot->db->subs_lc--;
  pool_Qremove(NULL, gdbroot->pool, &sp->nodsubs_ll);

  /* Remove from server table.  */

  hash_Remove(&sts, gdbroot->subs_ht, sp);

  /* Decrement subcounter for referenced object */

  op = vol_OidToObject(&sts, sp->aref.Objid, gdb_mLo_owned, vol_mTrans_alias, cvol_eHint_none);
  if (op != NULL) {
    op->u.n.subcount--;
  }

  pool_Free(NULL, gdbroot->pool, sp);
}
예제 #8
0
파일: rt_subc.c 프로젝트: hfuhuang/proview
static void
cancelTimeoutWatch (
    sub_sClient		*cp
)
{

    gdb_AssumeLocked;

    if (cp->tmoactive) {
        pool_Qremove(NULL, gdbroot->pool, &cp->subt_ll);
        cp->tmoactive = FALSE;
        gdbroot->db->subt_lc--;
    }
}
예제 #9
0
파일: rt_subc.c 프로젝트: hfuhuang/proview
void
subc_CancelUser (
    pid_t			subscriber
)
{
    sub_sClient		*cp;
    pool_sQlink		*cl;
    gdb_sNode		*np;
    pool_sQlink		*nl;
    pool_sQlink		*lh;

    /* Allocate a temporary root */

    gdb_AssumeLocked;

    lh = pool_Qalloc(NULL, gdbroot->pool);

    /* Build a list with all clients to cancel */

    for (
        nl = pool_Qsucc(NULL, gdbroot->pool, &gdbroot->db->nod_lh);
        nl != &gdbroot->db->nod_lh;
        nl = pool_Qsucc(NULL, gdbroot->pool, nl)
    ) {
        np = pool_Qitem(nl, gdb_sNode, nod_ll);

        for (cl = pool_Qsucc(NULL, gdbroot->pool, &np->subc_lh); cl != &np->subc_lh; ) {
            cp = pool_Qitem(cl, sub_sClient, subc_ll);
            cl = pool_Qsucc(NULL, gdbroot->pool, cl);

            if (cp->subscriber == subscriber) {
                pool_Qremove(NULL, gdbroot->pool, &cp->subc_ll);
                pool_QinsertPred(NULL, gdbroot->pool, &cp->subc_ll, lh);
            }
        } /* For all clients of that node. */
    } /* For all nodes */

    /* Now cancel them all! */

    subc_CancelList(lh);

    /* Return the root to the pool */

    pool_Free(NULL, gdbroot->pool, lh);

}
예제 #10
0
파일: rt_sanc.c 프로젝트: siamect/proview
pwr_tBoolean sanc_Subscribe(pwr_tStatus* sts, gdb_sObject* op)
{
  gdb_sVolume* vp;
  gdb_sNode* np;

  if (sts != NULL)
    *sts = 1;

  gdb_AssumeLocked;

  if (op->l.flags.b.isNative)
    pwr_Return(NO, sts, SAN__NATIVE);

  if (op->u.c.flags.m & (gdb_mCo_sancAdd | gdb_mCo_sancAct)) {
    op->u.c.sanexp = 0;
    return YES;
  }

  vp = pool_Address(NULL, gdbroot->pool, op->l.vr);
  np = pool_Address(NULL, gdbroot->pool, vp->l.nr);

  if (op->u.c.flags.b.sancRem) {
    pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
    op->u.c.flags.b.sancRem = 0;
    pwr_Assert(np->sancRem_lc != 0);
    np->sancRem_lc--;
    pool_QinsertPred(NULL, gdbroot->pool, &op->u.c.sanc_ll, &np->sancAct_lh);
    op->u.c.flags.b.sancAct = 1;
    np->sancAct_lc++;
    return YES;
  }

  pwr_Assert(!pool_QisLinked(NULL, gdbroot->pool, &op->u.c.sanc_ll));

  pool_QinsertPred(NULL, gdbroot->pool, &op->u.c.sanc_ll, &np->sancAdd_lh);
  op->u.c.flags.b.sancAdd = 1;
  memset(&op->l.al, 0, sizeof(op->l.al));
  np->sancAdd_lc++;
  ++gdbroot->db->sancid.rix;
  op->u.c.sanid = gdbroot->db->sancid;
  op->u.c.sanexp = 0;

  return YES;
}
예제 #11
0
파일: rt_dl.c 프로젝트: hfuhuang/proview
void
dl_Cancel (
  pwr_tStatus		*sts,
  pwr_tDlid		dlid
)
{
  dl_sLink		*dp;
  gdb_sObject		*op;
  cdh_uRefId		rid;

  gdb_AssumeLocked;
  
  rid.pwr = dlid;
  if (rid.r.vid_3 != cdh_eVid3_dlid) {
    pwr_Status(sts, GDH__DLID);
    return;
  }

  dp = hash_Search(sts, gdbroot->subc_ht, &dlid);
  if (dp == NULL) {
    pwr_Status(sts, GDH__DLID);
    return;
  }

  dp = hash_Remove(sts, gdbroot->subc_ht, dp);
  if (dp == NULL) errh_Bugcheck(GDH__WEIRD, "hash_Remove");

  pool_Qremove(NULL, gdbroot->pool, &dp->dl_ll);
  gdbroot->db->dl_lc--;

  op = pool_Address(NULL, gdbroot->pool, dp->opr);
  if (op == NULL) errh_Bugcheck(GDH__WEIRD, "direct link inconsitency");

  gdb_UnlockObject(sts, op);

  pool_Free(NULL, gdbroot->pool, dp);

  return;
}
예제 #12
0
파일: rt_sancm.c 프로젝트: Strongc/proview
void
sancm_MoveExpired (
    pwr_tStatus		*status,
    gdb_sNode		*np
)
{
    pool_sQlink		*ol;
    gdb_sObject		*op;

    if (status != NULL) *status = 1;

    gdb_AssumeLocked;

    if (np->sancAct_lc == 0) return;

    for (
        ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAct_lh);
        ol != &np->sancAct_lh;
    ) {
        op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);
        ol = pool_Qsucc(NULL, gdbroot->pool, ol);

        pwr_Assert(op->u.c.flags.b.sancAct);

        if (op->u.c.sanexp) {
            pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
            op->u.c.flags.b.sancAct = 0;
            pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
            pwr_Assert(np->sancAct_lc != 0);
            np->sancAct_lc--;

            pool_QinsertPred(NULL, gdbroot->pool, &op->u.c.sanc_ll, &np->sancRem_lh);
            op->u.c.flags.b.sancRem = 1;
            np->sancRem_lc++;
            op->u.c.sanexp = 0;
        } else if (!op->l.flags.b.isMountServer)
            op->u.c.sanexp = 1;
    }
}
예제 #13
0
파일: rt_subc.c 프로젝트: hfuhuang/proview
static void
deleteClient (
    sub_sClient		*cp
)
{
    pwr_tStatus		sts;
    gdb_sNode		*np;

    gdb_AssumeLocked;

    cancelTimeoutWatch(cp);

    subc_RemoveFromMessage(cp);

    hash_Remove(&sts, gdbroot->subc_ht, cp);
    if (EVEN(sts)) errh_Bugcheck(sts, "remove client from hash table");

    np = hash_Search(&sts, gdbroot->nid_ht, &cp->nid);
    if (np == NULL) errh_Bugcheck(sts, "node not found");

    pool_Qremove(&sts, gdbroot->pool, &cp->subc_ll);
    np->subc_lc--;

    if (cp->userdata != pool_cNRef) {
        pool_FreeReference(NULL, gdbroot->rtdb, cp->userdata);
    }

    if (cp->cclass != pool_cNRef) {
        gdb_sCclass	*ccp;

        ccp = pool_Address(NULL, gdbroot->pool, cp->cclass);
        if (ccp == NULL) errh_Bugcheck(GDH__WEIRD, "cached class address");
        cmvolc_UnlockClass(NULL, ccp);
        cp->cclass = pool_cNRef;
    }

    pool_Free(NULL, gdbroot->pool, cp);

}
예제 #14
0
파일: rt_subc.c 프로젝트: hfuhuang/proview
void
subc_RemoveFromMessage (
    sub_sClient		*cp
)
{
    sub_sMessage		*mp;

    if (cp->submsg == pool_cNRef)
        return;

    gdb_AssumeLocked;

    mp = pool_Address(NULL, gdbroot->pool, cp->submsg);
    if (--mp->msg.count == 0) {
        pool_Qremove(NULL, gdbroot->pool, &mp->subm_ll);
        gdbroot->db->subm_lc--;

        pool_Free(NULL, gdbroot->pool, mp);

    } /* Last reference to that SUBMSG, dispose it */

    cp->submsg  = pool_cNRef;
    cp->subdata = pool_cNRef;
}
예제 #15
0
파일: rt_sancm.c 프로젝트: Strongc/proview
void
sancm_Add (
    pwr_tStatus		*status,
    gdb_sNode		*np
)
{
    net_sSanAdd		*ap;
    pool_sQlink		*ol;
    gdb_sObject		*op;
    int			count;
    int			i;
    qcom_sQid		tgt;

    if (status != NULL) *status = 1;

    gdb_AssumeLocked;

    if (np->sancAdd_lc == 0) return;
    count = MIN(np->sancAdd_lc, net_cSanMaxAdd);
    ap = malloc(sizeof(net_sSanAdd) + (count - 1) * sizeof(ap->sane[0]));
    if (ap == NULL) return;

    tgt.nid = np->nid;
    tgt.qix = net_cProcHandler;

    for (
        i = 0, ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAdd_lh);
        ol != &np->sancAdd_lh;
        ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAdd_lh)
    ) {
        op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

        ap->sane[i].oid = op->g.oid;
        ap->sane[i].sid = op->u.c.sanid;
        i++;
        pwr_Assert(op->u.c.flags.b.sancAdd);
        pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
        op->u.c.flags.b.sancAdd = 0;
        pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
        pwr_Assert(np->sancAdd_lc != 0);
        np->sancAdd_lc--;
        pwr_Assert(!op->u.c.flags.b.sancAct);
        pool_QinsertPred(NULL, gdbroot->pool, &op->u.c.sanc_ll, &np->sancAct_lh);
        op->u.c.flags.b.sancAct = 1;
        np->sancAct_lc++;
        if (i >= count) {
            ap->count = count;
            gdb_Unlock;
            net_Put(NULL, &tgt, ap, net_eMsg_sanAdd, 0, pwr_Offset(ap, sane[i]), 0);
            gdb_Lock;
            i = 0;
        }
    }

    pwr_Assert(np->sancAdd_lc == 0);

    /* Send remaining san entries.  */

    if (i > 0) {
        ap->count = i;
        gdb_Unlock;
        net_Put(NULL, &tgt, ap, net_eMsg_sanAdd, 0, pwr_Offset(ap, sane[i]), 0);
        gdb_Lock;
    }

    free(ap);
}
예제 #16
0
파일: rt_sancm.c 프로젝트: Strongc/proview
void
sancm_Remove (
    pwr_tStatus		*status,
    gdb_sNode		*np
)
{
    net_sSanRemove	*rp;
    pool_sQlink		*ol;
    gdb_sObject		*op;
    int			count;
    int			i;
    qcom_sQid		tgt;

    if (status != NULL) *status = 1;

    gdb_AssumeLocked;

    if (np->sancRem_lc == 0) return;

    count = MIN(np->sancRem_lc, net_cSanMaxRemove);
    rp = malloc(sizeof(net_sSanRemove) + (count - 1) * sizeof(rp->sid[0]));
    if (rp == NULL) return;

    tgt.nid = np->nid;
    tgt.qix = net_cProcHandler;

    for (
        i = 0, ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancRem_lh);
        ol != &np->sancRem_lh;
        ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancRem_lh)
    ) {
        op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

        rp->sid[i] = op->u.c.sanid;
        i++;
        pwr_Assert(op->u.c.flags.b.sancRem);
        pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
        op->u.c.flags.b.sancRem = 0;
        pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
        pwr_Assert(np->sancRem_lc != 0);
        np->sancRem_lc--;
#if 0
        cvolc_TrimObject(op);
#endif
        if (i >= count) {
            rp->count = count;
            gdb_Unlock;
            net_Put(NULL, &tgt, rp, net_eMsg_sanRemove, 0, pwr_Offset(rp, sid[i]), 0);
            gdb_Lock;
            i = 0;
        }
    }

    pwr_Assert(np->sancRem_lc == 0);

    /* Send remaining san removes.  */

    if (i > 0) {
        rp->count = count;
        gdb_Unlock;
        net_Put(NULL, &tgt, rp, net_eMsg_sanRemove, 0, pwr_Offset(rp, sid[i]), 0);
        gdb_Lock;
    }

    free(rp);
}
예제 #17
0
파일: rt_sancm.c 프로젝트: Strongc/proview
void
sancm_FlushNode (
    pwr_tStatus		*status,
    gdb_sNode		*np
)
{
    pool_sQlink		*ol;
    gdb_sObject		*op;

    if (status != NULL) *status = 1;

    gdb_AssumeLocked;

    for (
        ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAdd_lh);
        ol != &np->sancAdd_lh;
        ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAdd_lh)
    ) {
        op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

        pwr_Assert(op->u.c.flags.b.sancAdd);
        pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
        op->u.c.flags.b.sancAdd = 0;
        pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
        pwr_Assert(np->sancAdd_lc != 0);
        np->sancAdd_lc--;
    }
    pwr_Assert(np->sancAdd_lc == 0);

    for (
        ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAct_lh);
        ol != &np->sancAct_lh;
        ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAct_lh)
    ) {
        op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

        pwr_Assert(op->u.c.flags.b.sancAct);
        pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
        op->u.c.flags.b.sancAct = 0;
        pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
        pwr_Assert(np->sancAct_lc != 0);
        np->sancAct_lc--;
    }
    pwr_Assert(np->sancAct_lc == 0);

    for (
        ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancRem_lh);
        ol != &np->sancRem_lh;
        ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancRem_lh)
    ) {
        op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

        pwr_Assert(op->u.c.flags.b.sancRem);
        pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
        op->u.c.flags.b.sancRem = 0;
        pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
        pwr_Assert(np->sancRem_lc != 0);
        np->sancRem_lc--;
    }
    pwr_Assert(np->sancRem_lc == 0);

    return;
}
예제 #18
0
파일: rt_sansm.c 프로젝트: siamect/proview
pwr_tUInt32 sansm_Update(gdb_sNode* np)
{
  static net_sSanUpdate* up = NULL;
  static san_sServer** spl = NULL;
  int i;
  pwr_tStatus sts;
  pwr_tUInt32 gen;
  pool_sQlink* sl;
  san_sServer* sp;
  qcom_sQid tgt;

  gdb_AssumeLocked;

  if (pool_QisEmpty(NULL, gdbroot->pool, &np->sansUpd_lh))
    return 0;

  if (up == NULL) {
    up = malloc(sizeof(*up) + (net_cSanMaxUpdate - 1) * sizeof(up->data[0]));
    spl = malloc(sizeof(san_sServer*) * net_cSanMaxUpdate);
  }

  for (i = 0, sl = pool_Qsucc(NULL, gdbroot->pool, &np->sansUpd_lh);
       sl != &np->sansUpd_lh && i < net_cSanMaxUpdate; i++) {
    sp = pool_Qitem(sl, san_sServer, sansUpd_ll);
    sl = pool_Qsucc(NULL, gdbroot->pool, sl);

    pwr_Assert(sp->flags.b.sansUpd);

    up->data[i].al = sp->al;
    up->data[i].sane = sp->sane;
    spl[i] = sp;
  }

  up->count = i;

  tgt.nid = np->nid;
  tgt.qix = net_cProcHandler;

  gen = np->sans_gen;

  gdb_Unlock;
  net_Put(&sts, &tgt, up, net_eMsg_sanUpdate, 0, pwr_Offset(up, data[i]), 0);
  gdb_Lock;

  if (EVEN(sts))
    return 0;

  if (gen == np->sans_gen) {
    for (i = 0; i < up->count; i++) {
      sp = spl[i];
      pwr_Assert(sp->flags.b.sansUpd);
      pool_Qremove(NULL, gdbroot->pool, &sp->sansUpd_ll);
      sp->flags.b.sansUpd = 0;
    }

  } else {
    for (i = 0; i < up->count; i++) {
      sp = hash_Search(NULL, gdbroot->sans_ht, &up->data[i].sane.sid);
      if (sp != NULL) {
        pwr_Assert(sp->flags.b.sansUpd);
        pool_Qremove(NULL, gdbroot->pool, &sp->sansUpd_ll);
        sp->flags.b.sansUpd = 0;
      }
    }
  }

  return up->count;
}
예제 #19
0
파일: rt_subcm.c 프로젝트: Strongc/proview
void
subcm_Data (
  qcom_sGet		*get
)
{
  pwr_tStatus		sts;
  pwr_tTime		curtim;
  pool_tRef		mr;
  sub_sMessage		*mp;
  pwr_tUInt32		refcount = 0;
  pwr_tInt32		i;
  sub_sClient		*cp;
  pool_tRef		dr;
  net_sSubData		*dp;
  void			*adrs;
  gdb_sNode		*np;
  net_sSubRemove	*rp = NULL;
  qcom_sQid		tgt;
  gdb_sCclass		*ccp;
  ndc_sRemoteToNative	*tbl;
  int                   rsize;
  

  time_GetTime( &curtim);

  gdb_AssumeUnlocked;

  tgt.qix = net_cProcHandler;

  gdb_ScopeLock {

    /* Allocate space for, and store the message in the pool.  */

    mp = pool_Alloc(&sts, gdbroot->pool, sizeof(*mp) - sizeof(mp->msg) + get->size);
    if (mp == NULL) break;
    mr = pool_ItemReference(NULL, gdbroot->pool, mp);

    memcpy(&mp->msg, get->data, get->size);
    pool_Qinit(NULL, gdbroot->pool, &mp->subm_ll);
    pool_QinsertPred(NULL, gdbroot->pool, &mp->subm_ll, &gdbroot->db->subm_lh);
    gdbroot->db->subm_lc++;
    np = hash_Search(&sts, gdbroot->nid_ht, &mp->msg.hdr.nid);


    /* Check if message is corrupt */
    dp = (net_sSubData *)&mp->msg.subdata;
    for ( i=0; i < mp->msg.count; i++) {
      if ( (char *)dp > (char *)&mp->msg + get->size || (char *)dp < (char *)&mp->msg) {
	errh_Error( "Subscription client message corrupt");
	gdb_Unlock;
	return;
      }
      dp = (net_sSubData *)((unsigned long)&dp->data + dp->size);
    }

    /* Walk through every entry in the message buffer.  */
    for (
      i=0,
      dp = (net_sSubData *)&mp->msg.subdata,
      dr = mr + offsetof(sub_sMessage, msg.subdata);

      i < mp->msg.count;

      i++,
      dr += offsetof(net_sSubData, data) + (unsigned long)dp->size,
      dp = (net_sSubData *)((unsigned long)&dp->data + dp->size)
    ) {

      cp = hash_Search(&sts, gdbroot->subc_ht, &dp->sid);
      if (cp == NULL) {
	if (rp == NULL) {
	  rp = pool_Alloc(&sts, gdbroot->pool, sizeof(*rp)
	    + ((mp->msg.count - 1) * sizeof(rp->sid[0])));
	  if (rp == NULL)
	    continue;
	  tgt.nid = mp->msg.hdr.nid;
	}
	rp->sid[rp->count++] = dp->sid;
	continue;
      }

      /* If the client has an earlier reference to a message, then
	 remove that reference.
	 This can cause the old message to get disposed of.  */

      subc_RemoveFromMessage(cp);

      /* Now start filling in the client according to the new
	 information we just received...  */

      memcpy(&cp->lastupdate, &curtim, sizeof(curtim));
      cp->sts = dp->sts;
      cp->count++;

      if (ODD(dp->sts)) {
	cp->old	    = FALSE;	/* There is new, fresh, real data!  */
	cp->submsg  = mr;
	cp->subdata = dr;
	refcount++;

	if (1 || mp->msg.hdr.xdr) {
          if (cp->cclass == pool_cNRef) {
            gdb_sClass		*classp;
            cdh_uTypeId		cid;

            cid.pwr = cp->aref.Body;
            cid.c.bix = 0;	/* To get the class id.  */
            classp = hash_Search(&sts, gdbroot->cid_ht, &cid.pwr);
	    rsize = dp->size;

            if (classp != NULL)
              ndc_ConvertData(&sts, np, classp, &cp->aref, dp->data, dp->data, (pwr_tUInt32 *)&rsize, ndc_eOp_decode, cp->aref.Offset, 0);
	  }
          else {
            cp->old = TRUE;
            ccp = pool_Address(&cp->sts, gdbroot->pool, cp->cclass);
            if (ccp != NULL) {
              tbl = pool_Address(&cp->sts, gdbroot->pool, ccp->rnConv);
              if (tbl != NULL) {
	        rsize = dp->size;
                ndc_ConvertRemoteData(&cp->sts, np, ccp, &cp->raref, dp->data, dp->data, (pwr_tUInt32 *)&rsize, ndc_eOp_decode, cp->raref.Offset, 0);
                if (ODD(cp->sts))
                  cp->old = FALSE;
              }
            }
          }
          
	  /* !!! Todo !!! Error handling. */
	}

	/* If the userdata field contains a valid pool_tRef, then
	   copy the data. This poolref is resolved in RTDB!  */

	if (cp->userdata != pool_cNRef) {
	  adrs = pool_Address(NULL, gdbroot->rtdb, cp->userdata);
	  if (adrs != NULL) {
            if (cp->cclass == pool_cNRef)
              memcpy(adrs, dp->data, MIN(dp->size, cp->usersize));
            else if (!cp->old) {
              pwr_tUInt32  size = cp->usersize;
              pwr_tBoolean first = 1;
              ndc_ConvertRemoteToNativeTable(&cp->sts, ccp, tbl, &cp->raref, &cp->aref, adrs, dp->data, &size, 
                                             cp->aref.Offset, 0, 0, &first, np->nid);
              if (EVEN(cp->sts))
                cp->old = TRUE;
            }
	  }
	}
      }
    }

    /* Fill in count as the # of references in the 'message' header. This
       is the # of references that have to be removed before the 'message'
       can be returned to pool. If there are no references to the 'message'
       just dispose it!  */

    if (refcount != 0) {
      mp->msg.count = refcount;
    } else {
      pool_Qremove(NULL, gdbroot->pool, &mp->subm_ll);
      gdbroot->db->subm_lc--;
      pool_Free(NULL, gdbroot->pool, mp);
    }

  } gdb_ScopeUnlock;

  if (rp != NULL) { 
    tgt = np->handler;
    net_Put(NULL, &tgt, rp, net_eMsg_subRemove, 0, pwr_Offset(rp, sid[rp->count]), 0);
#if 0
    errh_Info("Removed %d subscriptions", rp->count - 1);
#endif
    pool_Free(NULL, gdbroot->pool, rp);
  }
}
예제 #20
0
파일: rt_subc.c 프로젝트: hfuhuang/proview
void
subc_ActivateList (
    pool_sQlink		*lh,
    pwr_tObjid		oid
)
{
    pwr_tStatus		sts;
    tree_sTable		*add;
#if 0
    tree_sTable		*remove;
    sRemove		*rep;
#endif
    net_sSubSpec		*specp;
    qcom_sQid		tgt;
    pool_sQlink		*my_lh;
    pwr_tUInt32		my_subc_lc;
    gdb_sNode		*np;
    gdb_sNode		*old_np;
    sub_sClient		*cp;
    pool_sQlink		*cl;
    sAdd			*aep;


    /* Test each client. If existing object, fill in nid field
       and move the client to the appropriate nodes's subc_lh list. Turn
       on timeouts. Put request in subadd message buffer.

       We must do it all in one pass, since a user can come in during
       a cache query for a later subcli and cancel the subscription
       for an earlier subcli.  */

    add = tree_CreateTable(&sts, sizeof(pwr_tNodeId), offsetof(sAdd, nid),
                           sizeof(sAdd), 10, tree_Comp_nid);
#if 0
    remove = tree_CreateTable(&sts, sizeof(pwr_tNodeId), offsetof(sRemove, nid),
                              sizeof(sRemove), 10, tree_eComp_nid);
#endif

    /* Move all objects to a new, temporary root */

    my_lh = pool_Qalloc(NULL, gdbroot->pool);
    my_subc_lc = 0;

    for (cl = pool_Qsucc(NULL, gdbroot->pool, lh); cl != lh;) {
        cp = pool_Qitem(cl, sub_sClient, subc_ll);
        cl = pool_Qsucc(NULL, gdbroot->pool, cl);

        if (cdh_ObjidIsNull(oid) || cdh_ObjidIsEqual(oid, cp->aref.Objid)) {
            pool_Qremove(NULL, gdbroot->pool, &cp->subc_ll);
            pool_QinsertPred(NULL, gdbroot->pool, &cp->subc_ll, my_lh);
            my_subc_lc++;
        }
    }

    /* Now start testing clients from 'my_lh', and move them to other lists
       Make sure the clients are still there after the test.  */

    for (cl = pool_Qsucc(NULL, gdbroot->pool, my_lh); cl != my_lh; ) {
        cp = pool_Qitem(cl, sub_sClient, subc_ll);
        cl = pool_Qsucc(NULL, gdbroot->pool, cl);

        np = testClient(&sts, cp);

        /* If an error is returned the client doesn't exist anymore. Some
           other user removed it while TestSubcli had the database unlocked.
           Just go on with the next client...  */

        if (np == NULL) continue;

        /* Move the client to the list for the node where the object resides.
           nid = pwr_cNNodeId is used for all objects we don't know.  */

        old_np = hash_Search(&sts, gdbroot->nid_ht, &cp->nid);
        if (old_np == NULL) errh_Bugcheck(GDH__WEIRD, "");

        pool_Qremove(NULL, gdbroot->pool, &cp->subc_ll);
        old_np->subc_lc--;
        pool_QinsertPred(NULL, gdbroot->pool, &cp->subc_ll, &np->subc_lh);
        np->subc_lc++;
        cp->nid = np->nid;

        /* If the object's nid changed, then take the appropriate actions.  */

        if (np != old_np) {
            if (np->nid != pwr_cNNodeId) {  /* Object is known.  */

                activateTimeoutWatch(cp);

                aep = tree_Insert(&sts, add, &np->nid);
                if (aep == NULL) errh_Bugcheck(GDH__WEIRD, "");

                if (aep->msg == NULL) {
                    aep->cnt = MIN(my_subc_lc, net_cSubMaxAdd);
                    aep->msg = malloc(sizeof(net_sSubAdd) + sizeof(net_sSubSpec) * aep->cnt);
                    aep->msg->count = 0;
                } /* If there was no message allocated */

                specp		    = &aep->msg->spec[aep->msg->count];
                specp->sid	    = cp->sid;
                specp->dt	    = cp->dt;
                specp->sub_by_name  = cp->sub_by_name;
                specp->aref	    = cp->cclass != pool_cNRef ? cp->raref : cp->aref;

                if (++aep->msg->count >= aep->cnt) {

                    /* The message buffer is full and must be sent.  */

                    tgt = np->handler;
                    pwr_Assert(tgt.nid != pwr_cNNodeId);

                    gdb_Unlock;

                    net_Put(NULL, &tgt, aep->msg, net_eMsg_subAdd, 0, pwr_Offset(aep->msg, spec[aep->msg->count]), 0);

                    gdb_Lock;

                    aep->msg->count = 0;

                }

            } else {	/* The object became unknown... */

                cancelTimeoutWatch(cp);
                subc_SetOld(cp);	/* Data gets old immediately */

#if 0
                /** @todo Maybe we should unlock the cached class? */
                if (cp->cclass != pwr_cNRefId) {
                    ccp = pool_Address(NULL, gdbroot->pool, cp->cclass);
                    if (ccp == NULL) errh_Bugcheck(GDH__WEIRD, "Cached class address");
                    cmvolc_UnlockClass(NULL, ccp);
                    cp->cclass = pwr_cNRefId;
                }
#endif

#if 0
                if (old_np->nid != pwr_cNNodeId) {
                    rep = tree_Insert(&sts, remove, &old_np->nid);
                    if (rep == NULL) errh_Bugcheck(GDH__WEIRD, "");

                    if (rep->msg == NULL) {
                        rep->nid = old_np->nid;
                        rep->cnt = MIN(my_subc_lc, net_cSubMaxRemove);
                        rep->msg = malloc(sizeof(net_sSubRemove) + sizeof(rep->msg->sid[0]) * rep->cnt);
                        rep->msg->count = 0;
                    }

                    rep->msg->sid[rep->msg->count++] = cp->sid;

                    if (rep->msg->count >= net_cSubMaxRemove) {
                        np = hash_Search(&sts, gdbroot->nid_ht, &old_np->nid);
                        if (np == NULL) errh_Bugcheck(sts, "");
                        tgt.nid = rep->nid;
                        pwr_Assert(tgt.nid != pwr_cNNodeId);

                        gdb_Unlock;

                        net_Put(NULL, &tgt, rep->msg, net_eMsg_subRemove, 0, pwr_Offset(rep->msg, sid[rep->msg->count]), 0);

                        gdb_Lock;

                        rep->msg->count = 0;

                    }
                }
#endif
            }
        }
    }

    pool_Free(NULL, gdbroot->pool, my_lh);

    /* Now walk through the addmsg & remmsg and send all unsent messages.  */

    gdb_Unlock;

#if 0
    for (rep = tree_Minimum(remove); rep != NULL; rep = tree_Successor(remove, rep)) {
        if (rep->msg != NULL) {
            if (rep->msg->count > 0) {
                tgt.nid = rep->nid;
                pwr_Assert(tgt.nid != pwr_cNNodeId);
                net_Put(NULL, &tgt, rep->msg, net_eMsg_subRemove, 0, pwr_Offset(rep->msg, sid[rep->msg->count]), 0);
            }
            free(rep->msg);
        }
    }
#endif
    for (aep = tree_Minimum(&sts, add); aep != NULL; aep = tree_Successor(&sts, add, aep)) {
        if (aep->msg != NULL) {
            if (aep->msg->count > 0) {

                np = hash_Search(&sts, gdbroot->nid_ht, &aep->nid);
                if (np == NULL) errh_Bugcheck(GDH__WEIRD, "");

                tgt = np->handler;
                pwr_Assert(tgt.nid != pwr_cNNodeId);
                net_Put(NULL, &tgt, aep->msg, net_eMsg_subAdd, 0, pwr_Offset(aep->msg, spec[aep->msg->count]), 0);
            }
            free(aep->msg);
        }
    }

    gdb_Lock;

    tree_DeleteTable(&sts, add);
#if 0
    tree_DeleteTable(remove);
#endif
}