views:

156

answers:

2

I have a main loop which is fully data-driven: it has a blocking call to receive data and stores it as the 'most recent' (accessed elsewhere). Each piece of data has an associated lifespan, after which the data timesout and can no longer be considered valid. Each time I receive data I reset the timeout.

Unfortunately I can currently only test the data validity when the main thread is woken by the arrival of new data. I need to be able to trigger an event if/when the data expires, unless I receive new data in the meantime.

Please can anyone suggest a solution?

If it helps, I have Boost v1.33.1 installed - but cannot update to a more recent version.

+2  A: 

Since the expiration of data is an asynchronous event, you'll need to use an asynchronous timer. As you're using boost, you may want to look into Boost.Asio, which provides you with deadline_timer objects that can be used in conjunction with callback handlers. (See here for more information.) The callback handler will be invoked when the timer expires, which will allow you to check the validity of your data.

Edit: Ahh...I just noticed you're stuck with Boost 1.33.1, which doesn't have Asio. Well, if you're allowed to use other libraries you can use the non-boost version of Asio, or else you'll need to rely on OS-specific techniques to implement asynchronous timers. You don't specify your OS, but on POSIX-compliant systems you can use select/poll for timeouts.

Actually, you can also use a background thread which sleeps until the next piece of data expires, then wakes up and checks the state of all the data, and goes back to sleep until the next piece of data expires. You'd just need to be careful that you synchronize everything properly to avoid race conditions.

Charles Salvia
"Actually, you can also use a background thread which sleeps until the next piece of data expires" - I have this at the moment, but it doesn't allow for triggering events as data expires, e.g. the thread is sleeping for data A, data B arrives and times out, thread wakes after data A has expired. Data B never triggered an event.
James
A: 

I would split this into a minimum of two threads. Thread one loads the queue with data. Thread two is in charge of removing data from the queue.

The removal thread would maintain a pointer to the oldest datum. Each datum would have a timestamp. The removal thread starts with the oldest and removes historic data (data older than the current timestamp), then determines the sleep duration. The sleep duration would be the lesser of the duration until the next item to remove or a fixed update period. The thread then sleeps for this duration.

Each datum should have some kind of mutex or lock associated with it, so that the removal thread doesn't destroy data that the processing thread or the reader thread are using.

Thomas Matthews