ssize_t UARTSerial::read(void* buffer, size_t length) { size_t data_read = 0; char *ptr = static_cast<char *>(buffer); api_lock(); while (_rxbuf.empty()) { if (!_blocking) { api_unlock(); return -EAGAIN; } api_unlock(); wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ? api_lock(); } while (data_read < length && !_rxbuf.empty()) { _rxbuf.pop(*ptr++); data_read++; } api_unlock(); return data_read; }
int UARTSerial::sync() { api_lock(); while (!_txbuf.empty()) { api_unlock(); // Doing better than wait would require TxIRQ to also do wake() when becoming empty. Worth it? wait_ms(1); api_lock(); } api_unlock(); return 0; }
status_t AAH_RXPlayer::pause() { AutoMutex api_lock(&api_lock_); stopWorkThread(); CHECK(sock_fd_ < 0); is_playing_ = false; return OK; }
_R sync(_Function& work, const _Args&... args) { if (std::this_thread::get_id() != thread_.get_id()) { std::lock_guard<std::recursive_mutex> api_lock(api_mutex_); if (!is_running_) { throw std::runtime_error("Not running"); } std::promise<_R> promise; { std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back([&promise, &work, &args...]() { try { promise.set_value(work(args...)); } catch (...) { promise.set_exception(std::current_exception()); } }); workable_.notify_all(); } // Make sync return promise.get_future().get(); } else { if (!is_running_) { throw std::runtime_error("Not running"); } return work(args...); } }
status_t AAH_RXPlayer::start() { AutoMutex api_lock(&api_lock_); if (is_playing_) { return OK; } status_t res = startWorkThread(); is_playing_ = (res == OK); return res; }
void stop() { std::lock_guard<std::recursive_mutex> api_lock(api_mutex_); if (!is_running_) { return; } if (thread_.joinable()) { async([&]() { requires_stop_ = true; }); thread_.join(); } is_running_ = false; }
void start() { std::lock_guard<std::recursive_mutex> api_lock(api_mutex_); if (is_running_) { return; } is_running_ = true; requires_stop_ = false; // Clear all works { std::lock_guard<std::mutex> lock(works_mutex_); works_.clear(); } thread_ = std::thread(&serial_dispatcher::execute, this); }
ssize_t UARTSerial::read(void* buffer, size_t length) { size_t data_read = 0; char *ptr = static_cast<char *>(buffer); api_lock(); while (_rxbuf.empty()) { if (!_blocking) { api_unlock(); return -EAGAIN; } api_unlock(); wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ? api_lock(); } while (data_read < length && !_rxbuf.empty()) { _rxbuf.pop(*ptr++); data_read++; } core_util_critical_section_enter(); if (!_rx_irq_enabled) { UARTSerial::rx_irq(); // only read from hardware in one place if (!_rxbuf.full()) { SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq); _rx_irq_enabled = true; } } core_util_critical_section_exit(); api_unlock(); return data_read; }
ssize_t UARTSerial::write(const void* buffer, size_t length) { size_t data_written = 0; const char *buf_ptr = static_cast<const char *>(buffer); api_lock(); while (_txbuf.full()) { if (!_blocking) { api_unlock(); return -EAGAIN; } api_unlock(); wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ? api_lock(); } while (data_written < length && !_txbuf.full()) { _txbuf.push(*buf_ptr++); data_written++; } core_util_critical_section_enter(); if (!_tx_irq_enabled) { UARTSerial::tx_irq(); // only write to hardware in one place if (!_txbuf.empty()) { SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq); _tx_irq_enabled = true; } } core_util_critical_section_exit(); api_unlock(); return data_written; }
void async(std::function<void(void)>&& work) { if (std::this_thread::get_id() != thread_.get_id()) { std::lock_guard<std::recursive_mutex> api_lock(api_mutex_); if (!is_running_) { return; } std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back(work); workable_.notify_all(); } else { if (!is_running_) { return; } std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back(work); workable_.notify_all(); } }
std::future<void> async(_Function&& work, _Args&&... args) { auto promise_ptr = std::make_shared<std::promise<void>>(); do { if (std::this_thread::get_id() != thread_.get_id()) { std::lock_guard<std::recursive_mutex> api_lock(api_mutex_); if (!is_running_) { throw std::runtime_error("Not running"); } std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back([=]() { try { work(args...); promise_ptr->set_value(); } catch (...) { promise_ptr->set_exception(std::current_exception()); } }); workable_.notify_all(); } else { if (!is_running_) { throw std::runtime_error("Not running"); } std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back([=]() { try { work(args...); promise_ptr->set_value(); } catch (...) { promise_ptr->set_exception(std::current_exception()); } }); workable_.notify_all(); } } while (0); return promise_ptr->get_future(); }
status_t AAH_RXPlayer::setDataSource( const char *url, const KeyedVector<String8, String8> *headers) { AutoMutex api_lock(&api_lock_); uint32_t a, b, c, d; uint16_t port; if (data_source_set_) { return INVALID_OPERATION; } if (NULL == url) { return BAD_VALUE; } if (5 != sscanf(url, "%*[^:/]://%u.%u.%u.%u:%hu", &a, &b, &c, &d, &port)) { ALOGE("Failed to parse URL \"%s\"", url); return BAD_VALUE; } if ((a > 255) || (b > 255) || (c > 255) || (d > 255) || (port == 0)) { ALOGE("Bad multicast address \"%s\"", url); return BAD_VALUE; } ALOGI("setDataSource :: %u.%u.%u.%u:%hu", a, b, c, d, port); a = (a << 24) | (b << 16) | (c << 8) | d; memset(&listen_addr_, 0, sizeof(listen_addr_)); listen_addr_.sin_family = AF_INET; listen_addr_.sin_port = htons(port); listen_addr_.sin_addr.s_addr = htonl(a); data_source_set_ = true; return OK; }
void UARTSerial::set_flow_control(Flow type, PinName flow1, PinName flow2) { api_lock(); SerialBase::set_flow_control(type, flow1, flow2); api_unlock(); }
void UARTSerial::set_format(int bits, Parity parity, int stop_bits) { api_lock(); SerialBase::format(bits, parity, stop_bits); api_unlock(); }
status_t AAH_RXPlayer::reset() { AutoMutex api_lock(&api_lock_); reset_l(); return OK; }
bool AAH_RXPlayer::isPlaying() { AutoMutex api_lock(&api_lock_); return is_playing_; }