コード例 #1
0
ファイル: rt_subc.c プロジェクト: hfuhuang/proview
void
subc_SetOld (
    sub_sClient		*cp
)
{
    void   *adrs;

    cp->old = TRUE;

    if (cp->userdata != pool_cNRef) {
        adrs = pool_Address(NULL, gdbroot->rtdb, cp->userdata);
        if (adrs != NULL) {
            memset(adrs, 0, cp->usersize);
        }
    }

    subc_RemoveFromMessage(cp);

}
コード例 #2
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);

}
コード例 #3
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);
  }
}