34#ifndef _UTILS_HUBDEVICENONBLOCK_HXX_
35#define _UTILS_HUBDEVICENONBLOCK_HXX_
38#ifdef OPENMRN_FEATURE_FD_CAN_DEVICE
53extern int ioctl(
int fd,
unsigned long int key, ...);
59 HubDeviceNonBlock(HFlow *hub,
const char *path)
60 :
Service(hub->service()->executor())
61 , fd_(::open(path, O_RDWR | O_NONBLOCK))
67 hub_->register_port(write_port());
70 virtual ~HubDeviceNonBlock()
72 hub_->unregister_port(write_port());
80 typename HFlow::port_type *write_port()
94 ReadFlow(HubDeviceNonBlock *device)
98 this->start_flow(
STATE(allocate_buffer));
101 HubDeviceNonBlock *device()
103 return static_cast<HubDeviceNonBlock *
>(this->service());
108 service()->executor()->add(
this, 0);
114 service()->executor()->add_from_isr(
this, 0);
117 Action allocate_buffer()
119 return this->allocate_and_call(device()->hub(),
STATE(try_read));
124 b_ = this->get_allocation_result(device()->hub());
125 b_->data()->skipMember_ = device()->write_port();
126 return this->call_immediately(
STATE(retry_read));
133 ::read(device()->fd(), b_->data()->data(), b_->data()->size());
144 HASSERT((
unsigned)ret == b_->data()->size());
145 device()->hub()->send(b_, 0);
147 return this->call_immediately(
STATE(allocate_buffer));
152 typename HFlow::buffer_type *b_;
156 class WriteFlow :
public WriteFlowBase
159 WriteFlow(HubDeviceNonBlock *dev)
164 HubDeviceNonBlock *device()
166 return static_cast<HubDeviceNonBlock *
>(this->service());
171 this->service()->executor()->add(
this, 0);
176 this->service()->executor()->add_from_isr(
this, 0);
181 bufferPos_ =
static_cast<uint8_t*
>(this->message()->data()->data());
182 len_ = this->message()->data()->size();
183 return this->call_immediately(
STATE(try_write));
188 ssize_t ret = ::write(device()->fd(), bufferPos_, len_);
203 return this->release_and_exit();
207 return this->again();
213 DIE(
"Error writing.");
227 WriteFlow writeFlow_;
int ioctl(int fd, unsigned long int key,...)
Request and ioctl transaction.
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
Lightweight locking class for protecting small critical sections.
Base class of everything with a virtual destructor.
Collection of related state machines that pend on incoming messages.
Return type for a state flow callback.
Base class for state machines.
State flow with a given typed input queue.
#define CAN_IOC_READ_ACTIVE
read active ioctl.
#define CAN_IOC_WRITE_ACTIVE
write active ioctl.
#define OVERRIDE
Function attribute for virtual functions declaring that this funciton is overriding a funciton that s...
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
#define DIE(MSG)
Unconditionally terminates the current process with a message.