예제 #1
0
파일: pctldb.c 프로젝트: noaaport/nbsp
int pctldb_rcv(struct pctldb_st *pctldb, void *p, uint32_t *size, int *dberror){
  int status = 0;
  DBT key, data;
  uint32_t recno;
  uint32_t reclen;
  DB* dbp = pctldb->dbp;

  assert(p != NULL);
  if(p == NULL){
    *dberror = EINVAL;
    return(-1);
  }    
  
  memset(&key, 0 , sizeof(DBT));
  memset(&data, 0 , sizeof(DBT));

  if((status = dbp->get_re_len(dbp, &reclen)) != 0){
    *dberror = status;
    return(-1);
  }

  if(*size < reclen){
    *dberror = EINVAL;
    return(-1);
  }

  key.data = &recno;
  key.ulen = sizeof(recno);
  key.flags = DB_DBT_USERMEM;
  data.data = p;
  data.ulen = reclen;
  data.flags = DB_DBT_USERMEM;

  status = dbp->get(dbp, NULL, &key, &data, DB_CONSUME);
  if(status != 0){
    *dberror = status;
    status = -1;
  }else{
    *size = reclen;
    --pctldb->n;
  }

  return(status);
}
예제 #2
0
파일: qdb.c 프로젝트: noaaport/nbsp
int qdb_rcv(struct nbspq_st *nbspq, void **p, uint32_t *size, int *dberror){
  /*
   * If (*p == NULL), it allocates space for the data. But if *p is not NULL
   * it reuses the space, updating the size to return the true size of the
   * data.
   */
  int status = 0;
  DBT key, data;
  uint32_t recno;
  uint32_t reclen;
  void *p_copy;
  DB* dbp = nbspq->dbp;

  memset(&key, 0 , sizeof(DBT));
  memset(&data, 0 , sizeof(DBT));

  if((status = dbp->get_re_len(dbp, &reclen)) != 0){
    *dberror = status;
    return(-1);
  }

  if(*p == NULL)
    p_copy = malloc(reclen);
  else{
    if(*size < reclen){
      *dberror = EINVAL;
      return(-1);
    }else
      p_copy = *p;
  }

  if(p_copy == NULL){
    *dberror = errno;
    return(-1);
  }

  key.data = &recno;
  key.ulen = sizeof(recno);
  key.flags = DB_DBT_USERMEM;
  data.data = p_copy;
  data.ulen = reclen;
  data.flags = DB_DBT_USERMEM;

  status = dbp->get(dbp, NULL, &key, &data, DB_CONSUME);
  if(status != 0){
    *dberror = status;
    status = -1;
    if(*p == NULL)
      free(p_copy);
  }else{
    if(*p == NULL)
      *p = p_copy;

    *size = reclen;
    --nbspq->n;

    /*
     * The call to truncate() below is added to handle the case of in-memory
     * queues, in which case the page/extent size mechanism for reclaiming
     * unused space does not operate (both calls return errors when the
     * data base is configured as in-memory db). If this is not done here,
     * or somewhere, then the cache is eventually exhasusted and the
     * the next calls to qdb_send return an error (memory cannot be allocated.)
     */
    if(nbspq->f_memory_based && (nbspq->n == 0))
      status = dbp->truncate(dbp, NULL, NULL, 0);
  }

  return(status);
}