#ifndef GHOST_IO_H #define GHOST_IO_H class Read { // TODO: pushback support? public: int fd; CanRead can_read_machine; trigger can_read; Link link_ready; Link link_buffer; Link link_eof; Read(int fd, Buffer& buffer, trigger& eof) : fd(fd), link_buffer(buffer, this, &Read::push_buffer, &Read::pull_buffer), link_ready(can_read, this, &Read::push_can_read, &Read::pull_can_read), link_eof(eof, this, &Read::push_eof, &Read::pull_eof), can_read_machine(fd, can_read) { // make the FD non-blocking } void push_can_read() { // read a block from the fd int n; if ((n = read(fd, link_buffer.o.begin(), link_buffer.o.size())) > 0) { // push the buffer if we can, or at least how much has been read (n bytes) if (1) { //can push the buffer) { link_ready.pull(); } } else if (n == 0) { // EOF link_eof.push(); } else { // check for error - should send an error message on a different link? fatal("socket error"); } } void pull_buffer() { // state transition, possibly push the buffer again } void pull_eof() { // state transition to DONE - can we have multiple EOFs in a stream? no, should be inactive now } void pull_can_read() { fatal("Read: internal error - CanRead PULLed the trigger!"); } void push_buffer() { // pushback? fatal("Read: error - client PUSHed the buffer!"); } void push_eof() { fatal("Read: error - client PUSHed eof!"); } }; #endif