473,396 Members | 1,996 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Re: SIGALRM in a class member?

On Aug 13, 5:32 am, Jack Klein <jackkl...@spamcop.netwrote:
On Tue, 12 Aug 2008 23:58:11 GMT, Ron Eggler <unkn...@example.com>
wrote in comp.lang.c++:
While you've made a number of important points:

[...]
Note the reference to the C signal handler definition, which states:
"If the signal occurs other than as the result of calling the
abort or raise function, the behavior is undefined if the
signal handler calls any function in the standard library
other than the signal function itself (with a first argument
of the signal number corresponding to the signal that caused
the invocation of the handler) or refers to any object with
static storage duration other than by assigning a value to a
static storage duration variable of type volatile
sig_atomic_t. Furthermore, if such a call to the signal
function results in a SIG-ERR return, the value of errno is
indeterminate."
Then, in a footnote, the C standard adds:
"If any signal is generated by an asynchronous signal handier,
the behavior is undefined."
In other words, according to the C standard, any signal
generated by SIGALRM is undefined behavior. That's true, but if
he's requesting a SIGALRM, he's working under an OS and with a
compiler which supports it, and defines some of the behavior the
C and C++ standards leave undefined. If he's on a Posix
system, what he can and cannot do is defined by the Posix
standard. And while it's still very limited, it is a little bit
more than just setting a sig_atomic_t and calling signal().
Be very, very careful trying to use library functions, file
i/o, memory allocation, or just about anything else inside a
signal handler invoked asynchronously (other than by a call to
raise()). The C++ library, the underlying C library, and
maybe even the operating system can be in a state where there
are severe limits on what they can do.
Yes. He really has to ask in a group specialized for his OS to
find out exactly what he can do. (The usual solution under Unix
is to run a special timer thread, and handle the signal
there---Posix allows a signal to unblock a normal thread, rather
than just invoke a signal handler, and you can then do just
about anything you could normally do in a thread.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 13 '08 #1
4 2965
James Kanze wrote:
On Aug 13, 5:32 am, Jack Klein <jackkl...@spamcop.netwrote:
>On Tue, 12 Aug 2008 23:58:11 GMT, Ron Eggler <unkn...@example.com>
wrote in comp.lang.c++:

While you've made a number of important points:

[...]
>Note the reference to the C signal handler definition, which states:
>"If the signal occurs other than as the result of calling the
abort or raise function, the behavior is undefined if the
signal handler calls any function in the standard library
other than the signal function itself (with a first argument
of the signal number corresponding to the signal that caused
the invocation of the handler) or refers to any object with
static storage duration other than by assigning a value to a
static storage duration variable of type volatile
sig_atomic_t. Furthermore, if such a call to the signal
function results in a SIG-ERR return, the value of errno is
indeterminate."
>Then, in a footnote, the C standard adds:
>"If any signal is generated by an asynchronous signal handier,
the behavior is undefined."

In other words, according to the C standard, any signal
generated by SIGALRM is undefined behavior.
What does undefined behaviour in this matter mean exactly? It's been raised
properly for me. I don't see the problem as long as I check in the actual
timer function what kind of signal i got it seems to work nicely.
That's true, but if
he's requesting a SIGALRM, he's working under an OS and with a
compiler which supports it, and defines some of the behavior the
C and C++ standards leave undefined. If he's on a Posix
system, what he can and cannot do is defined by the Posix
standard. And while it's still very limited, it is a little bit
more than just setting a sig_atomic_t and calling signal().
I don't need more than what this is offering me.
>Be very, very careful trying to use library functions, file
i/o, memory allocation, or just about anything else inside a
signal handler invoked asynchronously (other than by a call to
raise()). The C++ library, the underlying C library, and
maybe even the operating system can be in a state where there
are severe limits on what they can do.
What do you mean by "be careful"? I believe it could end up in a stack
overflow if the actual timer function takes too much time. Is this what you
are referring to?
Yes. He really has to ask in a group specialized for his OS to
find out exactly what he can do. (The usual solution under Unix
is to run a special timer thread, and handle the signal
there---Posix allows a signal to unblock a normal thread, rather
than just invoke a signal handler, and you can then do just
about anything you could normally do in a thread.)
Alright the software I'm writing here is working on an embedded Linux
platform - not POSIX tho. It's just a customized distribution built on
ulibC.
Why would having an independent thread make more sense than just raising a
timer signal SIGALRM? I don't quite see the problem...

For my application it makes sense just doing it this way I believe -Trying
to keep memory usage minimal as well as not wasting any CPU ressources
(thread running in idle).

Ron

--
weeks of software enineering safe hours of planing ;)
Aug 13 '08 #2
I also replaced my atoi(string from XML parser) to this:

istringstream buffer(INITSource::XMLread(inBufstr,"Cyclic"));
buffer >HeartBeatTime;
HeartBeatTime=float(float(HeartBeatTime)/100*90);
alarm(HeartBeatTime);

What do you think to this, is this better? This should work properly as well
and is C++ conform, any other suggestions or hints regarding this
conversion?

Thanks,
Ron
Aug 13 '08 #3
On Wed, 13 Aug 2008 22:26:29 GMT, Ron Eggler <un*****@example.com>
wrote in comp.lang.c++:
James Kanze wrote:
On Aug 13, 5:32 am, Jack Klein <jackkl...@spamcop.netwrote:
On Tue, 12 Aug 2008 23:58:11 GMT, Ron Eggler <unkn...@example.com>
wrote in comp.lang.c++:
While you've made a number of important points:

[...]
Note the reference to the C signal handler definition, which states:
"If the signal occurs other than as the result of calling the
abort or raise function, the behavior is undefined if the
signal handler calls any function in the standard library
other than the signal function itself (with a first argument
of the signal number corresponding to the signal that caused
the invocation of the handler) or refers to any object with
static storage duration other than by assigning a value to a
static storage duration variable of type volatile
sig_atomic_t. Furthermore, if such a call to the signal
function results in a SIG-ERR return, the value of errno is
indeterminate."
Then, in a footnote, the C standard adds:
"If any signal is generated by an asynchronous signal handier,
the behavior is undefined."
In other words, according to the C standard, any signal
generated by SIGALRM is undefined behavior.

What does undefined behaviour in this matter mean exactly? It's been raised
properly for me. I don't see the problem as long as I check in the actual
timer function what kind of signal i got it seems to work nicely.
Neither C nor C++ guarantees nor defines reentrancy, although C++ is
moving in that direction for the future. But even then, these
features are generally defined for threading, and have certain
limitations.

Depending on your platform and quite a few other things, signals might
actually be generated by hardware interrupts at times that are
completely unpredictable to not only your program, but the C++ and C
libraries underneath them.

Suppose, just for example, that your code is in the middle of another
operation on the same object of the INITSource class. It might be in
a state where a new call in the middle of the old one causes
overwriting of some state operation. A function that reads data from
a buffer, whether it is a buffer from a file or not, might have read
some data but not yet stored the updated pointer or index into the
internal housekeeping.

For example, the FILE structure controlling a C stream generally
maintains a pointer or index into the buffer. A C++ stream
implementation might or might not be built on top of the C FILE
structure.

Typically, there is something like this pseudo code in a read call,
for example:

if (struct.index < BUFF_SIZE)
{
ch = struct.buffer[struct.index++];
}
else
{
/* call OS read function to fill the buffer again */
ch = struct.buffer[0];
struct.index = 1;
}
return ch;

So what happens if the call has just executed the if statement, then
it is preempted by a signal. A function invoked by a signal than
calls the read function on the same object with the same underlying
stream, which reads some bytes. When the signal function ends and the
interrupted code is resumed, it now starts reading where the signal
handler stopped reading.

Even worse is if the function called during signal handling happened
to read all the remaining bytes in the buffer, leaving the index
member exactly equal to BUFF_SIZE. The resumed code, having already
checked that index was less than BUFF_SIZE, cheerfully tries to read
the byte as one past the end of the array. This may or may not cause
a memory fault of some kind, but certainly returns incorrect data.

The point is that operating systems, which are not defined or
controller by the C or C++ standards, vary greatly and have evolved
over time. On some early platforms, a hardware interrupt could be
dispatched to a signal handler even if the OS kernel itself was in
some sort of non-reentrant critical section. So any OS call at all
from a signal handling function could crash the whole system if the
timing was just right, or should I say wrong. Most modern operating
systems are smarter than that, for sure.
That's true, but if
he's requesting a SIGALRM, he's working under an OS and with a
compiler which supports it, and defines some of the behavior the
C and C++ standards leave undefined. If he's on a Posix
system, what he can and cannot do is defined by the Posix
standard. And while it's still very limited, it is a little bit
more than just setting a sig_atomic_t and calling signal().

I don't need more than what this is offering me.
Be very, very careful trying to use library functions, file
i/o, memory allocation, or just about anything else inside a
signal handler invoked asynchronously (other than by a call to
raise()). The C++ library, the underlying C library, and
maybe even the operating system can be in a state where there
are severe limits on what they can do.

What do you mean by "be careful"? I believe it could end up in a stack
overflow if the actual timer function takes too much time. Is this what you
are referring to?
Yes. He really has to ask in a group specialized for his OS to
find out exactly what he can do. (The usual solution under Unix
is to run a special timer thread, and handle the signal
there---Posix allows a signal to unblock a normal thread, rather
than just invoke a signal handler, and you can then do just
about anything you could normally do in a thread.)

Alright the software I'm writing here is working on an embedded Linux
platform - not POSIX tho. It's just a customized distribution built on
ulibC.
Why would having an independent thread make more sense than just raising a
timer signal SIGALRM? I don't quite see the problem...
Because the POSIX standard requires a conforming OS to make sure it is
in a state where it can accept certain system calls, such as the call
to unblock another thread, as Keith mentioned. So when the unblocked
thread is actually run, the entire system is back in the normal
foreground context, not in the asynchronous interrupted status.
For my application it makes sense just doing it this way I believe -Trying
to keep memory usage minimal as well as not wasting any CPU ressources
(thread running in idle).
My understanding of multi-tasking operating systems in general is that
a thread idling wastes uses exactly zero CPU resources, but I can't
guarantee that this applies to any, let alone all, Linux kernels.

What I was trying to say, and Keith said perhaps more succinctly, is
that you really need a platform specific group. Now that you've
mentioned your platform, I'd suggest something in the comp.os.linux.*
family, and/or comp.arch.embedded.

You will probably need to provide more information. Features and
limitations of Linux depend very heavily on the exact kernel version,
for example, and other limitations might be affected by the specific
library you are using, as opposed to the standard one.

You just need to realize that true asynchronous multi-tasking is a
complex thing, and need to be approached with some understanding of
its limitations. My original answer was absolutely correct as to what
the C and C++ language standards actually guarantee. What you want to
do is specifically the sort of thing that the C++ standard calls
"implementation-defined", so you need to check with the experts for
your implementation.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Aug 14 '08 #4
On Aug 14, 12:38 am, Ron Eggler <unkn...@example.comwrote:
I also replaced my atoi(string from XML parser) to this:
istringstream buffer(INITSource::XMLread(inBufstr,"Cyclic"));
buffer >HeartBeatTime;
HeartBeatTime=float(float(HeartBeatTime)/100*90);
alarm(HeartBeatTime);
What do you think to this, is this better?
If it is in a signal handler, it's undefined behavior.
This should work properly as well and is C++ conform, any
other suggestions or hints regarding this conversion?
You can't do anything this complicated in a signal handler
without incurring undefined behavior.

Note that C++ is even trickier with regards to signal handlers,
since Posix makes no guarantees concerning C++. In general, you
can count on being able to do anything you could do from a
signal handler in C, but nothing more. You cannot do *anything*
which uses any of the iostream stuff, or FILE*. You cannot call
any of the functions defined in the C++ standard. Of the
functions defined in the C standard, I think time(), rename(),
signal() and abort() are the only ones allowed (unless I've
missed one).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 14 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Jian H. Li | last post by:
Hello, What's the essential differences between the two ways of "class::member" & "object.member"(or object_pointer->member)? class C{ public: void f() {} int i; };
3
by: DanielBradley | last post by:
Hello all, I have recently been porting code from Linux to cygwin and came across a problem with static const class members (discussed below). I am seeking to determine whether I am programming...
7
by: Lionel B | last post by:
Greetings. The following code compiles ok and does what I'd expect it to do: ---------- START CODE ---------- // test.cpp
9
by: baumann | last post by:
hi all, to implement a singleton class, one has define a static function in the singleton class, class A{ public: static A* getInstance() { static A a; return &a;
5
by: kuvpatel | last post by:
Hi I want to refer a class called LogEvent, and use one of its methods called WriteMessage without actually having to create an instance of Logevent. I have tried using the word sealed with...
5
by: Andy | last post by:
Hi all, I have a site with the following architecture: Common.Web.dll - Contains a CommonPageBase class which inherits System.Web.UI.Page myadd.dll - Contains PageBase which inherits...
14
by: Dave Booker | last post by:
It looks like the language is trying to prevent me from doing this sort of thing. Nevertheless, the following compiles, and I'd like to know why it doesn't work the way it should: public class...
15
by: akomiakov | last post by:
Is there a technical reason why one can't initialize a cost static non- integral data member in a class?
2
by: R Samuel Klatchko | last post by:
Ron Eggler wrote: You can do this with a forwarding function that is a static member (you can also do it with a non-member function). Because signal does not give you a way to attach some...
2
by: Paul Rubin | last post by:
I'm trying to run a command on a remote host, something like: result = os.popen('ssh otherhost mycommand').read() It is possible that the other host is down, in which case the ssh command...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.