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; }
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; }
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); }
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 (); }
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 (); }