Exemplo n.º 1
0
size_t i2c::command(uint8_t slaveaddr,
                    uint8_t cmd,
                    const uint8_t* data_addr,
                    size_t data_size)
{
    reset_txfer_done();
    set_slave_address(slaveaddr);
    set_data_len(1 + data_size);
    initiate_write();
    write_byte(cmd);
    size_t bytes_sent=1;
    while (data_size>0)
    {
        if (write_byte(*data_addr))
        {
            data_addr++;
            data_size--;
            bytes_sent++;
        }
        // TODO check for error conditions
    }
    wait_for_done();
    clear_fifo();
    return bytes_sent;
}
Exemplo n.º 2
0
static int win_write(w_stm_t stm, const void *buf, int size) {
  struct win_handle *h = stm->handle;
  struct write_buf *wbuf;

  EnterCriticalSection(&h->mtx);
  if (h->file_type != FILE_TYPE_PIPE && h->blocking && !h->write_head) {
    DWORD bytes;
    stream_debug("blocking write of %d\n", size);
    if (WriteFile(h->h, buf, size, &bytes, NULL)) {
      LeaveCriticalSection(&h->mtx);
      return bytes;
    }
    h->errcode = GetLastError();
    h->error_pending = true;
    errno = map_win32_err(h->errcode);
    SetEvent(h->waitable);
    stream_debug("write failed: %s\n", win32_strerror(h->errcode));
    LeaveCriticalSection(&h->mtx);
    return -1;
  }

  wbuf = malloc(sizeof(*wbuf) + size - 1);
  if (!wbuf) {
    return -1;
  }
  wbuf->next = NULL;
  wbuf->cursor = wbuf->data;
  wbuf->len = size;
  memcpy(wbuf->data, buf, size);

  if (h->write_tail) {
    h->write_tail->next = wbuf;
  } else {
    h->write_head = wbuf;
  }
  h->write_tail = wbuf;

  if (!h->write_pending) {
    initiate_write(h);
  }

  LeaveCriticalSection(&h->mtx);

  return size;
}
Exemplo n.º 3
0
static void CALLBACK write_completed(DWORD err, DWORD bytes,
    LPOVERLAPPED olap) {
  // Reverse engineer our handle from the olap pointer
  struct overlapped_op *op = (void*)olap;
  struct win_handle *h = op->h;
  struct write_buf *wbuf = op->wbuf;

  stream_debug("WriteFileEx: completion callback invoked: bytes=%d %s\n",
      (int)bytes, win32_strerror(err));

  EnterCriticalSection(&h->mtx);
  if (h->write_pending == op) {
    h->write_pending = NULL;
  }

  if (err == 0) {
    wbuf->cursor += bytes;
    wbuf->len -= bytes;

    if (wbuf->len == 0) {
      // Consumed this buffer
      free(wbuf);
    } else {
      w_log(W_LOG_FATAL, "WriteFileEx: short write: %d written, %d remain\n",
          bytes, wbuf->len);
    }
  } else {
    stream_debug("WriteFilex: completion: failed: %s\n",
        win32_strerror(err));
    h->errcode = err;
    h->error_pending = true;
    SetEvent(h->waitable);
  }

  // Send whatever else we have waiting to go
  initiate_write(h);

  LeaveCriticalSection(&h->mtx);

  // Free the prior struct after possibly initiating another write
  // to minimize the change of the same address being reused and
  // confusing the completion status
  free(op);
}
Exemplo n.º 4
0
int
Sender::handle_output (ACE_HANDLE h)
{
  ACE_Guard<ACE_Recursive_Thread_Mutex> locker (mutex_);

  ACE_Time_Value tv = ACE_Time_Value::zero;
  ACE_Message_Block *mb = 0;

  int     err=0;
  ssize_t res=0;
  size_t  bytes=0;

  int     qcount = this->getq (mb , & tv);

  if (mb != 0)  // qcount >= 0
    {
      bytes = mb->length ();
      res = this->peer ().send (mb->rd_ptr (), bytes);

      this->total_w_++;

      if (res < 0)
        err = errno ;
      else
        this->total_snd_ += res;

      if (loglevel == 0 || res <= 0 || err!= 0)
        {
          LogLocker log_lock;

          ACE_DEBUG ((LM_DEBUG, "**** Sender::handle_output () SessionId=%d****\n", index_));
          ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_to_write", bytes));
          ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "handle", h));
          ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_transferred", res));
          ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "error", err));
          ACE_DEBUG ((LM_DEBUG, "%s = %s\n", "message_block", mb->rd_ptr ()));
          ACE_DEBUG ((LM_DEBUG, "**** end of message ****************\n"));
        }
    }

  ACE_Message_Block::release (mb);

  if (err != 0  || res < 0)
    return -1;

  int rc = 0;

  if (qcount <= 0)  // no more message blocks in queue
    {
      if (duplex != 0 &&   // full duplex, continue write
          (this->total_snd_ - this->total_rcv_ ) < 1024*32 )  // flow control
        rc = initiate_write ();
      else
        rc = terminate_io (ACE_Event_Handler::WRITE_MASK);

      if (rc == -1)
        return -1;
    }

  rc = initiate_io (ACE_Event_Handler::READ_MASK);
  if (rc == -1)
    return -1;

  return check_destroy ();
}
Exemplo n.º 5
0
int
Sender::handle_input (ACE_HANDLE h)
{
  ACE_Guard<ACE_Recursive_Thread_Mutex> locker (mutex_);

  ACE_Message_Block *mb = 0;
  ACE_NEW_RETURN (mb,
                  ACE_Message_Block (BUFSIZ),
                  -1);

  int     err = 0;
  ssize_t res = this->peer ().recv (mb->rd_ptr (),
                                    BUFSIZ-1);
  this->total_r_++;

  if (res >= 0)
    {
      mb->wr_ptr (res);
      this->total_rcv_ += res;
    }
  else
    err = errno ;

  mb->wr_ptr ()[0] = '\0';

  if (loglevel == 0 || res <= 0 || err!= 0)
    {
      LogLocker log_lock;

      ACE_DEBUG ((LM_DEBUG, "**** Sender::handle_input () SessionId=%d****\n", index_));
      ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_to_read", BUFSIZ));
      ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "handle", h));
      ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_transferred", res));
      ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "error", err));
      ACE_DEBUG ((LM_DEBUG, "%s = %s\n", "message_block", mb->rd_ptr ()));
      ACE_DEBUG ((LM_DEBUG, "**** end of message ****************\n"));
    }

  ACE_Message_Block::release (mb);

  if (err == EWOULDBLOCK)
    {
      err=0;
      res=0;
      return check_destroy ();
    }

  if (err !=0  || res <= 0)
    return -1;

  int rc = 0;

  if (duplex != 0)  // full duplex, continue read
    rc = initiate_io (ACE_Event_Handler::READ_MASK);
  else
    rc = terminate_io (ACE_Event_Handler::READ_MASK);

  if (rc != 0)
    return -1 ;

  rc = initiate_write ();
  if (rc != 0)
    return -1;

  return check_destroy ();
}