resetting boost::deadline_timer in handler causing crash - boost-asio

Below is sample code of Timer I am using in my server. It is a multithreaded process that process loads of data. Once timer triggers it does some operation on processed data and reset itself for new time
class MyTimer
{
public:
MyTimer(boost::asio::io_service& ios):strand_(ios)
{
for (int i = 0; i < 10; i++)
{
std::auto_ptr<boost::thread> thread(
new boost::thread(boost::bind(&boost::asio::io_service::run,
&ios_)));
thread_pool_.push_back(thread.get());
thread.release();
}
boost::posix_time::seconds expTime(10);
eodTimer_.reset(new boost::asio::deadline_timer(ios));
eodTimer_->expires_from_now(expTime);
eodTimer_->async_wait(boost::bind(&MyTimer::onTimer, this));
};
~MyTimer()
{
ThreadPool::iterator it(thread_pool_.begin());
for (; it != thread_pool_.end(); ++it)
{
(*it)->join();
delete *it;
}
}
void onTimer()
{
//do some stuff...
// reset timer
boost::posix_time::seconds expTime(10);
eodTimer_->expires_from_now(expTime);
eodTimer_->async_wait(boost::bind(&MyTimer::onTimer, this));
}
private:
boost::asio::io_service ios;
boost::asio::strand strand_;
boost::scoped_ptr<boost::asio::deadline_timer> eodTimer_;
};
So far I do not see any issue with this code. But after running from some hours my Server crashes. Stack trace points me to ::onTimer callback handler.
#0 0x0a446c06 in boost::asio::detail::timer_queue<boost::asio::time_traits<boost::posix_time::ptime> >::cancel_timer (this=0xe3be0bc,
timer_token=0xe9877ec) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/timer_queue.hpp:141
#1 0x0a445791 in boost::asio::detail::epoll_reactor<false>::cancel_timer<boost::asio::time_traits<boost::posix_time::ptime> > (this=0xe49f498,
timer_queue=..., token=0xe9877ec) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/epoll_reactor.hpp:424
#2 0x0a444197 in boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::detail:: epoll_reactor<false> >::cancel (this=0xe3be0a8, impl=..., ec=...) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/deadline_timer_service.hpp:104 #3 0x0a443f31 in boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::detail:: epoll_reactor<false> >::expires_at (this=0xe3be0a8, impl=..., expiry_time=..., ec=...)
at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/deadline_timer_service.hpp:120
#4 0x0a441e92 in boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::detail:: epoll_reactor<false> >::expires_from_now (this=0xe3be0a8, impl=..., expiry_time=..., ec=...)
at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/deadline_timer_service.hpp:137
#5 0x0a43f895 in boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> >:: expires_from_now (
this=0xe49f438, impl=..., expiry_time=..., ec=...) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/deadline_timer_service.hpp: 144
#6 0x0a451d64 in boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime>, boost::asio:: deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >::expires_from_now (this=0xe9877e8, expiry_time=...)
at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/basic_deadline_timer.hpp:297
#7 0x0a44e941 in fxpay::AggregatorRouter::Impl::MyTimer::onTimer (this=0xe987e48) at MyTimer.cpp:183
Is there something wrong the way I am using boost::dead_line timer? (I am using 1.39 boost version)

You're running 10 threads and there is no synchronization of access to eodTimer.
The deadline_timer object is not threadsafe, so you get Undefined Behaviour because of the data race.
Did you mean to run the timer on a strand?

Related

Use UART events with Simplelink in Contiki-ng

I'm actually trying to receive serial line message using the UART0 of a CC1310 with Contiki-ng.
I have implemented a uart callback function with will group all the characters received into a single variable, and stop collecting when it receives a "\n" character.
int uart_handler(unsigned char c)
{
if (c == '\n')
{
end_of_string = 1;
index = 0;
}
else
{
received_message_from_uart[index] = c;
index++;
}
return 0;
}
The uart0 is initialised at the main and only process of the system and then it waits in a infinite while loop until the flag end_of_string
PROCESS_THREAD(udp_client_process, ev, data)
{
PROCESS_BEGIN();
uart0_init();
uart0_set_callback(uart_handler);
while (1)
{
//wait for uart message
if (end_of_string == 1 && received_message_from_uart[0] != 0)
{
LOG_INFO("Received mensaje\n");
index = 0;
end_of_string = 0;
// Delete received message from uart
memset(received_message_from_uart, 0, sizeof received_message_from_uart);
}
etimer_set(&timer, 0.1 * CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
}
PROCESS_END();
}
As you can see, the while loop stops at each iteration with a minimum time timer event. Although this method works, I think it is a bad way to do it, as I have read that there are uart events that can be used, but I have not been able to find anything for the CC1310.
Is it possible to use the CC1310 (or any other simplelink platform) UART with events and stop doing unnecessary iterations until a message has reached the device?

Null pointer Exception at the end of draw processing3

I get a Null Pointer Exception, and the trace tells me it is inside a function that I have. This function runs every frame and does some calculations and stuff. Anyway, the problem is that when I go to debug, stepping through each line, the function runs fine, and the error only comes up at the end of the draw loop.
This error only recently came up, and the changes I made don't have much to do with the function in question so...
The function mentioned in the trace detects if the object touches something, and acts on it.
Also, the trace gives a line number that does not exist, I'm guessing that's because of the Processing compiling.
I am using Processing 4 if that matters.
Here's the trace:
java.lang.NullPointerException
at ants$Ant.sense(ants.java:190)
at ants$Ant.go(ants.java:220)
at ants.draw(ants.java:44)
at processing.core.PApplet.handleDraw(PApplet.java:2201)
at processing.awt.PSurfaceAWT$10.callDraw(PSurfaceAWT.java:1422)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:354)
Thanks!
Edit:
More info: This is an ant simulator, and it crashes at food pickup. This used to work and broke while adding (seemingly) unrelated stuff. It crashes at food pickup, which is managed by the sense() function. The Food class only has a position and a render function.
Here is some code:
void sense() { // The problematic function
if (!detectFood && !carryFood) {
float closest = viewRadius;
Food selected = null;
for (Food fd : foods){
float foodDist = position.dist(fd.position);
if(foodDist <= viewRadius) {
if(foodDist < closest) {
selected = fd;
closest = foodDist;
}
}
}
if (selected != null){
detectFood = true;
foodFocused = selected;
}
} else {
if(position.dist(foodFocused.position) < 2*r) {
takeFood();
detectFood = false;
}
}
}
void draw() { // draw loop
background(51);
for (Food food : foods) {
food.render();
}
for (Ant ant : ants) {
ant.go();
}
for (int i=0; i < trails.size(); i++) {
Trail trail = trails.get(i);
if (trail.strenght <= 0)
trails.remove(trail);
else
trail.go();
}
}
The problem is not the trail, as it still crashes without it,

UART Transmit failing after UART Receive thread starts in STM32 HAL Library

I am using STM32F1 (STM32F103C8T6) in order to develop a project using FreeRTOS.
The following is my GPIO and USART1 interface configuration:
__GPIOA_CLK_ENABLE();
__USART1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;//115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
HAL_UART_Init(&huart1);
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
The question is: Why does UART transmit work before threads start but not after threads started or from threads? I want to transmit data from threads. i.e
int main(void)
{
Initializations();
//THIS WORKS!!
uart_transmit_buffer[0] = 'H';
uart_transmit_buffer[1] = 'R';
uart_transmit_buffer[2] = '#';
uint8_t nums_in_tr_buf = 0;
nums_in_tr_buf = sizeof(uart_transmit_buffer)/sizeof(uint8_t);
state = HAL_UART_Transmit(&huart1, uart_transmit_buffer, nums_in_tr_buf, 5000);
StartAllThreads();
osKernelStart();
for (;;);
}
static void A_Random_Thread(void const *argument)
{
for(;;)
{
if (conditionsMet()) //Executed once when a proper response received.
{
//BUT NOT THIS :(!!
uart_transmit_buffer[0] = 'H';
uart_transmit_buffer[1] = 'R';
uart_transmit_buffer[2] = '#';
uint8_t nums_in_tr_buf = 0;
nums_in_tr_buf = sizeof(uart_transmit_buffer)/sizeof(uint8_t);
state = HAL_UART_Transmit(&huart1, uart_transmit_buffer, nums_in_tr_buf, 5000);
}
}
}
I have made sure no thread is in deadlock. The problem is UART_HAL_Transmit gives HAL_BUSY state.
Furthermore, I have dedicated one thread to receiving and parsing information from UART RX and I suspect this might be a cause of the problem. The following is the code:
static void UART_Receive_Thread(void const *argument)
{
uint32_t count;
(void) argument;
int j = 0, word_length = 0;
for (;;)
{
if (uart_line_ready == 0)
{
HAL_UART_Receive(&huart1, uart_receive_buffer, UART_RX_BUFFER_SIZE, 0xFFFF);
if (uart_receive_buffer[0] != 0)
{
if (uart_receive_buffer[0] != END_OF_WORD_CHAR)
{
uart_line_buffer[k] = uart_receive_buffer[0];
uart_receive_buffer[0] = 0;
k++;
}
else
{
uart_receive_buffer[0] = 0;
uart_line_ready = 1;
word_length = k;
k = 0;
}
}
}
if (uart_line_ready == 1)
{
//osThreadSuspend(OLEDThreadHandle);
for (j = 0; j <= word_length; j++)
{
UART_RECEIVED_COMMAND[j] = uart_line_buffer[j];
}
for (j = 0; j <= word_length; j++)
{
uart_line_buffer[j] = 0;
}
uart_line_ready = 0;
RECEIVED_COMMAND = ParseReceivedCommand(UART_RECEIVED_COMMAND);
if (RECEIVED_COMMAND != _ID_)
{
AssignReceivedData (word_length); //Results in uint8_t * RECEIVED_DATA
}
//osThreadResume(OLEDThreadHandle);
}
//Should be no delay in order not to miss any data..
}
}
Another cause to the problem I suspect could be related to interrupts of the system (Also please notice initialization part, I configured NVIC):
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
Any help or guidance to this issue would be highly appreciated. Thanks in advance.
From what I can see HAL_UART_Transmit would've worked with the F4 HAL (v1.4.2) if it weren't for __HAL_LOCK(huart). The RX thread would lock the handle and then the TX thread would try to lock as well and return HAL_BUSY. HAL_UART_Transmit_IT and HAL_UART_Receive_IT don't lock the handle for the duration of the transmit/receive.
Which may cause problems with the State member, as it is non-atomically updated by the helper functions UART_Receive_IT and UART_Transmit_IT. Though I don't think it would affect operation.
You could modify the function to allow simultaneous RX and TX. You'd have to update this every time they release a new version of the HAL.
The problem is that the ST HAL isn't meant to be used with an RTOS. It says so in the definition of the macro __HAL_LOCK. Redefining it to use the RTOS's mutexes might worth trying as well. Same with HAL_Delay() to use the RTOS's thread sleep function.
In general though, sending via a blocking function in a thread should be fine, but I would not receive data using a blocking function in a thread. You are bound to experience overrun errors that way.
Likewise, if you put too much processing in the receive interrupt you might also run into overrun errors. I prefer using DMA for reception, followed by interrupts if I've run out of DMA streams. The interrupt only copies the data to a buffer, similarly to the DMA. A processRxData thread is then used to process the actual data.
When using FreeRTOS, you have to set interrupt priority to 5 or above, because below 5 is reserved for the OS.
So change your code to set the priority to:
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
The problem turned out to be something to do with blocking statements.
Since UART_Receive_Thread has HAL_UART_Receive inside and that is blocking the thread until something is received, that results in a busy HAL (hence, the HAL_BUSY state).
The solution was using non-blocking statements without changing anything else.
i.e. using HAL_UART_Receive_IT and HAL_UART_Transmit_IT at the same time and ignoring blocking statements worked.
Thanks for all suggestions that lead to this solution.

My .c program create threads. But one of them is killed by system after 10 min running time. How to protect this thread?

My .c program create threads. But one of them is killed by system after 10 min running time. How to protect this thread?
I creates some threads do period work. But one of them is killed by system. I notice this because the this thread does not print the period information after about 10 min running time.
How to protect this thread from being killed? Anybody met this before?
int main(void){
/* threads */
pthread_t thrid_up;
pthread_t thrid_down;
pthread_create( &thrid_up, NULL, (void * (*)(void *))thread_up, NULL);
pthread_create( &thrid_down, NULL, (void * (*)(void *))thread_down, NULL);
while (!exit_sig && !quit_sig) {
//statistics
...
}
}
void thread_up(void) {
while (!exit_sig && !quit_sig) {
//deal interrupt and send the messages to the server
...
}
}
void thread_down(void) {
while (!exit_sig && !quit_sig) {
//deal the messages sent by the server
...
}
}
The thread_up thread is killed by the system everytime when this program runs about 10 min long. But thread_down works well all the time.

Cancelling dispatch_io_read

I'm parsing a very large CSV file using GCD functions (please see code below).
If I encounter an error I'd like to cancel dispatch_io_read. Is there a way to do that?
dispatch_io_read(channel,
0,
Int.max,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0))
{ (done, data, error) in
guard error == 0 else {
print("Read Error: \(error)")
return
}
if done {
lineBuffer.dealloc(bufferSize)
}
dispatch_data_apply(data)
{ (region, offset, buffer, size) -> Bool in
print(size)
let bytes = UnsafePointer<UInt8>(buffer)
for var i = 0; i < size; i++ {
switch bytes[i] {
case self.cr: // ignore \r
break
case self.lf: // newline
lineBuffer[bufferLength] = 0x00 // Null terminated
line(line: String(UTF8String: lineBuffer)!)
bufferLength = 0
case _ where bufferLength < (bufferSize - 1): // Leave space for null termination
lineBuffer[bufferLength++] = CChar(bytes[i])
default:
return false // Overflow! I would like to stop reading the file here.
}
}
return true
}
}
Calling dispatch_io_close(DISPATCH_IO_STOP) will cause running dispatch_io_read operations to be interrupted and their handlers to be passed to ECANCELED error (along with partial results), see the dispatch_io_close(3) manpage.
Note that this does not interrupt the actual I/O system calls, it just prevents additional I/O system calls from being entered, so you may have to set an I/O channel high watermark to ensure the appropriate level of I/O granularity for your application.