Beispiel #1
0
// return 1 if chain has been fully sent, 0 otherwise
int
processChain(
  BufferedWriter* self,
  BufferChain* chain
) {
  uint8_t* buf = mbuf_rdptr(chain->mbuf);
  size_t size = mbuf_message_offset(chain->mbuf) - mbuf_read_offset(chain->mbuf);
  size_t sent = 0;
  chain->reading = 1;
  oml_unlock(&self->lock, "processChain"); /* don't keep lock while transmitting */
  MBuffer* meta = self->meta_buf;

  while (size > sent) {
    long cnt = self->writeFunc(self->writeFuncHdl, (void*)(buf + sent), size - sent,
                               meta->rdptr, meta->fill);
    if (cnt > 0) {
      sent += cnt;
    } else {
      /* ERROR: Sleep a bit and try again */
      /* To be on the safe side, we rewind to the beginning of the
       * chain and try to resend everything - this is especially important
       * if the underlying stream needs to reopen and resync.
       */
      mbuf_reset_read(chain->mbuf);
      size = mbuf_message_offset(chain->mbuf) - mbuf_read_offset(chain->mbuf);
      sent = 0;
      sleep(1);
    }
  }
  // get lock back to see what happened while we were busy
  oml_lock_persistent(self);
  mbuf_read_skip(chain->mbuf, sent);
  if (mbuf_write_offset(chain->mbuf) == mbuf_read_offset(chain->mbuf)) {
    // seem to have sent everything so far, reset chain
    //    mbuf_clear2(chain->mbuf, 0);
    mbuf_clear2(chain->mbuf, 1);
    chain->reading = 0;
    return 1;
  }
  return 0;
}
Beispiel #2
0
/** Read the marshalling header information contained in an MBuffer.
 *
 * \param mbuf MBuffer to read from
 * \param header pointer to an OmlBinaryHeader into which the data from the
 *               mbuf should be unmarshalled
 * \return 1 on success, the size of the missing section as a negative number
 *         if the buffer is too short, or 0 if something failed
 */
int
unmarshal_init(MBuffer* mbuf, OmlBinaryHeader* header)
{
  uint8_t header_str[PACKET_HEADER_SIZE + 2];
  uint8_t stream_header_str[STREAM_HEADER_SIZE];
  int result, n;
  OmlValue seqno;
  OmlValue timestamp;

  oml_value_init(&seqno);
  oml_value_init(&timestamp);

  result = mbuf_begin_read (mbuf);
  if (result == -1) {
    logerror("Couldn't start unmarshalling packet (mbuf_begin_read())\n");
    return 0;
  }

  result = mbuf_read (mbuf, header_str, 3);
  if (result == -1) {
    return mbuf_rd_remaining (mbuf) - 3;
  }

  if (! (header_str[0] == SYNC_BYTE && header_str[1] == SYNC_BYTE)) {
    logdebug("Cannot find sync bytes in binary stream, out of sync; first 3 bytes: %#0x %#0x %#0x\n",
        header_str[0], header_str[1], header_str[2]);
    return 0;
  }

  header->type = (OmlBinMsgType)header_str[2];

  if (header->type == OMB_DATA_P) {
    // Read 2 more bytes of the length field
    uint16_t nv16 = 0;
    result = mbuf_read (mbuf, (uint8_t*)&nv16, sizeof (uint16_t));
    if (result == -1) {
      n = mbuf_rd_remaining (mbuf) - 2;
      mbuf_reset_read (mbuf);
      return n;
    }
    header->length = (int)ntohs (nv16);
  } else if (header->type == OMB_LDATA_P) {
    // Read 4 more bytes of the length field
    uint32_t nv32 = 0;
    result = mbuf_read (mbuf, (uint8_t*)&nv32, sizeof (uint32_t));
    if (result == -1) {
      n = mbuf_rd_remaining (mbuf) - 4;
      mbuf_reset_read (mbuf);
      return n;
    }
    header->length = (int)ntohl (nv32);
  } else {
    logwarn ("Unknown packet type %d\n", (int)header->type);
    return 0;
  }

  int extra = mbuf_rd_remaining (mbuf) - header->length;
  if (extra < 0) {
    mbuf_reset_read (mbuf);
    return extra;
  }

  result = mbuf_read (mbuf, stream_header_str, LENGTH (stream_header_str));
  if (result == -1) {
      n = mbuf_rd_remaining (mbuf) - LENGTH (stream_header_str);
      mbuf_reset_read (mbuf);
      return n;
  }

  header->values = (int)stream_header_str[0];
  header->stream = (int)stream_header_str[1];

  if (unmarshal_typed_value (mbuf, "seq-no", OML_INT32_VALUE, &seqno) == -1)
    return 0;

  if (unmarshal_typed_value (mbuf, "timestamp", OML_DOUBLE_VALUE, &timestamp) == -1)
    return 0;

  header->seqno = omlc_get_int32(*oml_value_get_value(&seqno));
  header->timestamp = omlc_get_double(*oml_value_get_value(&timestamp));

  oml_value_reset(&seqno);
  oml_value_reset(&timestamp);

  return 1;
}