From c65f81bf467facfafa67df53a6c8c6fa94bbdc9d Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Mon, 8 May 2017 13:11:12 +0300 Subject: [PATCH] Remove sigio implementation from FileHandle Make FileHandle more of an interface class, by requiring implementers to provide the sigio() functionality themselves. sigio() and poll() remain parallel independent mechanisms, so FileHandle implementations must trigger both on state changes. --- platform/BufferedSerial.cpp | 26 +++++++++++++++++++++++--- platform/BufferedSerial.h | 7 +++++++ platform/FileHandle.cpp | 13 ------------- platform/FileHandle.h | 16 +++++----------- platform/mbed_poll.cpp | 3 --- platform/mbed_poll.h | 4 +++- 6 files changed, 38 insertions(+), 31 deletions(-) diff --git a/platform/BufferedSerial.cpp b/platform/BufferedSerial.cpp index 5568491192..99ca8527f0 100644 --- a/platform/BufferedSerial.cpp +++ b/platform/BufferedSerial.cpp @@ -40,7 +40,7 @@ BufferedSerial::~BufferedSerial() void BufferedSerial::DCD_IRQ() { - _poll_change(this); + wake(); } void BufferedSerial::set_data_carrier_detect(PinName DCD_pin, bool active_high) @@ -94,6 +94,18 @@ int BufferedSerial::sync() return 0; } +void BufferedSerial::sigio(Callback func) { + core_util_critical_section_enter(); + _sigio_cb = func; + if (_sigio_cb) { + short current_events = poll(0x7FFF); + if (current_events) { + _sigio_cb(); + } + } + core_util_critical_section_exit(); +} + ssize_t BufferedSerial::write(const void* buffer, size_t length) { size_t data_written = 0; @@ -164,6 +176,14 @@ bool BufferedSerial::hup() const return _dcd && _dcd->read() != 0; } +void BufferedSerial::wake() +{ + _poll_change(this); + if (_sigio_cb) { + _sigio_cb(); + } +} + short BufferedSerial::poll(short events) const { short revents = 0; @@ -213,7 +233,7 @@ void BufferedSerial::rx_irq(void) /* Report the File handler that data is ready to be read from the buffer. */ if (was_empty && !_rxbuf.empty()) { - _poll_change(this); + wake(); } } @@ -237,7 +257,7 @@ void BufferedSerial::tx_irq(void) /* Report the File handler that data can be written to peripheral. */ if (was_full && !_txbuf.full() && !hup()) { - _poll_change(this); + wake(); } } diff --git a/platform/BufferedSerial.h b/platform/BufferedSerial.h index 6a8cfe17ec..998a30d359 100644 --- a/platform/BufferedSerial.h +++ b/platform/BufferedSerial.h @@ -64,8 +64,11 @@ public: virtual int set_blocking(bool blocking) { _blocking = blocking; return 0; } + virtual void sigio(Callback func); + void set_data_carrier_detect(PinName DCD_pin, bool active_high=false); + private: /** Software serial buffers @@ -76,6 +79,8 @@ private: PlatformMutex _mutex; + Callback _sigio_cb; + bool _blocking; bool _tx_irq_enabled; InterruptIn *_dcd; @@ -95,6 +100,8 @@ private: void tx_irq(void); void rx_irq(void); + void wake(void); + void DCD_IRQ(void); }; } //namespace mbed diff --git a/platform/FileHandle.cpp b/platform/FileHandle.cpp index 09d5e0834d..df72616993 100644 --- a/platform/FileHandle.cpp +++ b/platform/FileHandle.cpp @@ -32,19 +32,6 @@ off_t FileHandle::size() seek(off, SEEK_SET); return size; } - -void FileHandle::sigio(Callback func) { - core_util_critical_section_enter(); - _callback = func; - if (_callback) { - short current_events = poll(0x7FFF); - if (current_events) { - _callback(); - } - } - core_util_critical_section_exit(); -} - std::FILE *fdopen(FileHandle *fh, const char *mode) { return mbed_fdopen(fh, mode); diff --git a/platform/FileHandle.h b/platform/FileHandle.h index bc3d31d685..5123cbde2b 100644 --- a/platform/FileHandle.h +++ b/platform/FileHandle.h @@ -181,7 +181,9 @@ public: * The input parameter can be used or ignored - the could always return all events, * or could check just the events listed in events. * Call is non-blocking - returns instantaneous state of events. - * Whenever an event occurs, the derived class must call _poll_change(). + * Whenever an event occurs, the derived class must call _poll_change() (as well as + * the sigio() callback). + * * @param events bitmask of poll events we're interested in - POLLIN/POLLOUT etc. * * @returns @@ -230,18 +232,10 @@ public: * * @param func Function to call on state change */ - void sigio(Callback func); - - /** Issue sigio to user - used by mbed::_poll_change */ - void _send_sigio() + virtual void sigio(Callback func) { - if (_callback) { - _callback(); - } + //Default for real files. Do nothing for real files. } - -private: - Callback _callback; }; /** Not a member function diff --git a/platform/mbed_poll.cpp b/platform/mbed_poll.cpp index ffe426533b..41e4bf1f22 100644 --- a/platform/mbed_poll.cpp +++ b/platform/mbed_poll.cpp @@ -75,9 +75,6 @@ int poll(pollfh fhs[], unsigned nfhs, int timeout) void _poll_change(FileHandle *fh) { // TODO, will depend on how we implement poll - - // Also, do the user callback - fh->_send_sigio(); } } // namespace mbed diff --git a/platform/mbed_poll.h b/platform/mbed_poll.h index fd360ba620..3aea995d6e 100644 --- a/platform/mbed_poll.h +++ b/platform/mbed_poll.h @@ -49,7 +49,9 @@ struct pollfh { */ int poll(pollfh fhs[], unsigned nfhs, int timeout); -/** To be called by device when poll state changes - must be called for poll() and sigio() to work +/** To be called by device when poll state changes - must be called for poll() to work + * This must be called in addition to the user-provided callback. + * * @param fh A pointer to the file handle*/ void _poll_change(FileHandle *fh);