By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,732 Members | 1,397 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,732 IT Pros & Developers. It's quick & easy.

Callback high-res timer C++ class

P: n/a
Hi, guys!

I need a C++ class (Linux/POSIX/GNU C++), which can be started and stopped,
and calls a virtual callback instance method (e.g. "expired()") when a
given time has elapsed. High resolution means that expire time should be
measured in microseconds, or at least in milliseconds.

I had a look on Gnu C <sys/time.h>'s functions getitimer and setitimer, but
these all use a signal (SIGALRM) to notify expiration, and I don't know the
way to handle this signal from an instance class method.

So, the questions are the following:

1) Is there a way to safely encapsulate a C signal handler in a not-static
C++ class method?
2) Is there any class library that implements this feature?
3) Is there any, other than signal handling, to implement such a timer?

Thanks in advance for your help,

Dmitri S.

Sep 6 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Dmitri Sologoubenko wrote:
[..]
So, the questions are the following:

1) Is there a way to safely encapsulate a C signal handler in a
not-static C++ class method?
What do you mean by "safely encapsulate"? A non-static member function
cannot be used as a C signal handler (and that's in the FAQ, IIRC).
A static member can, but then you still need an instance of the class
to call a non-static member, AFAIUI. If you only have one instance
(a singleton), it should be no big deal, but if you have more than one,
there is no C solution to this C++ problem.
2) Is there any class library that implements this feature?
Which feature? A signal hander?
3) Is there any, other than signal handling, to implement such a
timer?
I would probably start by asking in a Linux/POSIX/GNU C++ newsgroup.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 6 '06 #2

P: n/a

Victor Bazarov wrote:
Dmitri Sologoubenko wrote:
[..]
So, the questions are the following:

1) Is there a way to safely encapsulate a C signal handler in a
not-static C++ class method?

What do you mean by "safely encapsulate"? A non-static member function
cannot be used as a C signal handler (and that's in the FAQ, IIRC).
A static member can, but then you still need an instance of the class
to call a non-static member, AFAIUI. If you only have one instance
(a singleton), it should be no big deal, but if you have more than one,
there is no C solution to this C++ problem.
I realize this is OT in this newsgroup, but to respond to what you've
answered...

In general most API functions (used for signal registration) allows one
to specify the signal handler and arguments that will get passed to the
handler when the signal occurs. If the instance is known at the time of
the signal handler registration, then the pointer of the instance need
only be translated into the call parameters. This in itself is not a
standard exercise :-), but often as easy as reinterpret casting the
pointer to an integer value. The translation can be abstracted (using a
virtual cast..., so to speak) if one is required to do this cross
platform. Although usually this type of code is so specific already
that abstraction (trying to make it cross platfor) has no added
benefit. The signal handler then translates the argument/s back to the
pointer. The signal handler may know the pointer type expected. A
typical test to verify whether the translation was correct, would be to
hide and additional this pointer in the class, and compare after
translation.
2) Is there any class library that implements this feature?
I'm sure there is. We have implemented similar things for Windows and
VxWorks. Unfortunately our timer is built on a whole callback
(intertask communication) architecture.
3) Is there any, other than signal handling, to implement such a
timer?
We have implemented a timer that fires a callback (cmd pattern style).
The callback is executed in the context of a thread associated with it.
Unfortunately I don't see why you want it to have resolution up to 1
micros. Typically system timers have a resolution of 20 millisecs. If
you are lucky, 1milli. If you want any faster than that, you have to
start doing processor specific things (Posix won't help you there). I
may be wrong though, but that is IME.

Regards,

Werner

Sep 6 '06 #3

P: n/a
werasm wrote:
>
Victor Bazarov wrote:
>Dmitri Sologoubenko wrote:
[..]
So, the questions are the following:

1) Is there a way to safely encapsulate a C signal handler in a
not-static C++ class method?

What do you mean by "safely encapsulate"? A non-static member function
cannot be used as a C signal handler (and that's in the FAQ, IIRC).
A static member can, but then you still need an instance of the class
to call a non-static member, AFAIUI. If you only have one instance
(a singleton), it should be no big deal, but if you have more than one,
there is no C solution to this C++ problem.

I realize this is OT in this newsgroup, but to respond to what you've
answered...

In general most API functions (used for signal registration) allows one
to specify the signal handler and arguments that will get passed to the
handler when the signal occurs. If the instance is known at the time of
the signal handler registration, then the pointer of the instance need
only be translated into the call parameters. This in itself is not a
standard exercise :-), but often as easy as reinterpret casting the
pointer to an integer value. The translation can be abstracted (using a
virtual cast..., so to speak) if one is required to do this cross
platform. Although usually this type of code is so specific already
that abstraction (trying to make it cross platfor) has no added
benefit. The signal handler then translates the argument/s back to the
pointer. The signal handler may know the pointer type expected. A
typical test to verify whether the translation was correct, would be to
hide and additional this pointer in the class, and compare after
translation.
2) Is there any class library that implements this feature?

I'm sure there is. We have implemented similar things for Windows and
VxWorks. Unfortunately our timer is built on a whole callback

(intertask communication) architecture.
>
3) Is there any, other than signal handling, to implement such a
timer?

We have implemented a timer that fires a callback (cmd pattern style).
The callback is executed in the context of a thread associated with it.
Unfortunately I don't see why you want it to have resolution up to 1
micros. Typically system timers have a resolution of 20 millisecs. If
you are lucky, 1milli. If you want any faster than that, you have to
start doing processor specific things (Posix won't help you there). I
may be wrong though, but that is IME.

Regards,

Werner
I think I have partially solved the problem: see this code:

#include <iostream>
#include <string>
#include <csignal>
#include <list>
#include <map>

using namespace std;

class SignalListener
{
public:
virtual void onSignal(int signal) {}
virtual ~SignalListener();
};

class L: public SignalListener
{
protected:
string name;
public:
L(string n) : name(n) {}
virtual void onSignal(int signal)
{
cout << "L[" << name << "] received SIGNAL[" << signal << "]" << endl;
}
};

class T: public L
{
public:
T(string n) : L(n) {}
virtual void onSignal(int signal)
{
cout << "T[" << name << "] received SIGNAL[" << signal << "]" << endl;
}
};

/************************************************** **
* SIGNAL HANDLER CLASS
************************************************** **/

class SignalHandler
{
protected:
static bool initialized;
static bool mustExit;
static int exitSignal;

static map<int,sighandler_told;
static list<SignalListener*lst;
static list<inthandled;

static void setIgnore(int sig, bool ignore)
{
if (ignore) {
signal(sig, SIG_IGN);
} else {
signal(sig, broadcast);
}
}

public:
static void init(int *signals, int nsignals, int exit_signal=SIGQUIT)
{
if (!initialized) {
initialized = true;
exitSignal = exit_signal;
if (signals && nsignals) {
for (int i=0; i<nsignals; i++) {
cout << "\tsignals[" << i << "] = [" << signals[i] << "]" << endl;
handled.push_back(signals[i]);
old[signals[i]] = signal(signals[i], broadcast);
}
}
}
}

static void destroy()
{
if (initialized) {
initialized = false;
for(list<int>::iterator i=handled.begin(); i!=handled.end(); i++ ) {
cout << "\tsignal(" << *i << "," << old[*i] << ")" << endl;
signal(*i, old[*i]);
}
}
}

static void broadcast(int sig)
{
setIgnore(sig, true);
for(list<SignalListener*>::iterator i=lst.begin(); i!=lst.end(); i++)
if (*i) (*i)->onSignal(sig);
if (sig==exitSignal) mustExit = true;
setIgnore(sig, false);
}

static void addListener(SignalListener *l)
{
lst.push_front(l);
}

static void removeListener(SignalListener *l)
{
lst.remove(l);
}

static bool mustQuit()
{
return mustExit;
}

};

bool SignalHandler::initialized = false;
bool SignalHandler::mustExit = false;
int SignalHandler::exitSignal = 0;
list<SignalListener*SignalHandler::lst;
map<int,sighandler_tSignalHandler::old;
list<intSignalHandler::handled;

SignalListener::~SignalListener()
{
SignalHandler::removeListener(this);
}
int main (int argc, char* argv[])
{
int signals[] = {SIGALRM, SIGQUIT};
SignalHandler::init(signals, 2);

L l1("uno");
L l2("due");
T t1("tiuno");

SignalHandler::addListener(&l1);
SignalHandler::addListener(&l2);
SignalHandler::addListener(&t1);

while (!SignalHandler::mustQuit()) {
sleep(1);
}

SignalHandler::destroy();

exit(0);
}

If you run this and then send via "kill" SIGALRM and SIGQUIT, it works
great.

Another problem: in multi-threaded applications of these classes, have I to
use Mutexes? Is this possible to use Mutexes (posix) to protect static
methods. Will be any side-effect caused by asynchronous (and thread
handling - indipendent) nature of signals?

Thanks a lot.
Dmitri S.
Sep 6 '06 #4

P: n/a

Dmitri Sologoubenko wrote:
I think I have partially solved the problem: see this code:
[snip]

My solution would have involved real time signals that allow arguments
to the callback.

I have looked at the code. I will only comment on it from a std C++
perspective. My first comment is that I noticed that lack of
qualification when using components in the std namespace...
Another problem: in multi-threaded applications of these classes, have I to
use Mutexes? Is this possible to use Mutexes (posix) to protect static
methods. Will be any side-effect caused by asynchronous (and thread
handling - indipendent) nature of signals?
Yes it is...

Refer your questions to comp.programming.threads as it bears no
relevance here.

Kind regards,

Werner

Sep 7 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.