Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SIGEV_THREAD causes error in timer_create

992 views
Skip to first unread message

Tom Dillard

unread,
Aug 5, 1999, 3:00:00 AM8/5/99
to
I have been trying to set up a timer in pthreads using the timer_create
function, setting the sigev_notify field to SIGEV_THREAD.

I receive an error indicating "invalid argument" (errno=EINVAL).
It seems like Solaris does not recognize SIGEV_THREAD as valid. As
shown below in the example code, if you use SIGEV_SIGNAL instead the
timer is created OK.

Specifics follow. If you have an example that works on Solaris I would
like to look at it. Thanks for any information you may be able to
provide.

Tom


Here are specifics, if you are still with me:

OS is Solaris7 (SunOS 5.7 Generic_106541-01)

Compile line is:
% /opt/SUNWspro/bin/CC -I./ -g +w +w2 -mt -lrt -lpthread -o TestTimer
TestTimer.C

Output is:
% TestTimer
error: timer_create
errno=22(Invalid argument)


TestTimer.C code is:
// play around with clocks and timers
//
#include <unistd.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <iostream.h>
#include <errno.h>
#include <string.h>

#define A_DESCRIPTIVE_NAME 13

main ()
{
int i;
timer_t timer1;
struct sigevent signal_spec;
//signal_spec.sigev_notify = SIGEV_SIGNAL;
signal_spec.sigev_notify = SIGEV_THREAD;
signal_spec.sigev_signo = SIGRTMIN;
signal_spec.sigev_value.sival_int = A_DESCRIPTIVE_NAME;

i = ::timer_create (CLOCK_REALTIME, // clock id
&signal_spec, // signal event struct to use
&timer1); // timer identifier
if (i != 0)
{
cout << "error: timer_create" << endl;
cout << " errno=" << errno << "(" << strerror (errno) << ")" <<
endl;
}
}

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

Steve Watt

unread,
Aug 10, 1999, 3:00:00 AM8/10/99
to
In article <7od054$vtl$1...@nnrp1.deja.com>,
Tom Dillard <t.di...@santera.com> wrote:
[ ... trying to use SIGEV_THREAD on Solaris 7 ... ]

>I receive an error indicating "invalid argument" (errno=EINVAL).

[ snip! ]

>#define A_DESCRIPTIVE_NAME 13
>
>main ()
>{
> int i;
> timer_t timer1;
> struct sigevent signal_spec;
> //signal_spec.sigev_notify = SIGEV_SIGNAL;
> signal_spec.sigev_notify = SIGEV_THREAD;
> signal_spec.sigev_signo = SIGRTMIN;
> signal_spec.sigev_value.sival_int = A_DESCRIPTIVE_NAME;

OK, here's part of the problem: If you use SIGEV_THREAD, you must set
the sigev_notify_function member to a function pointer, and the sigev_value
will be passed to that function in a new thread. The thread's attributes
are specified by the sigev_notify_attributes member. There's no point to
specifying a signal number, because there's no signal, it's a thread.

So the above might want to look like

signal_spec.sigev_notify = SIGEV_THREAD;
signal_spec.sigev_notify_function = a_function_that_has_C_linkage;
signal_spec.sigev_notify_attributes = NULL; // means create detached


> i = ::timer_create (CLOCK_REALTIME, // clock id
> &signal_spec, // signal event struct to use
> &timer1); // timer identifier

It is, of course, possible that Solaris doesn't implement SIGEV_THREAD, but
that seems unlikely to me.

--
Steve Watt KD6GGD PP-ASEL-IA ICBM: 121W 56' 58.1" / 37N 20' 14.2"
Internet: steve @ Watt.COM Whois: SW32
Free time? There's no such thing. It just comes in varying prices...

Tom Dillard

unread,
Aug 10, 1999, 3:00:00 AM8/10/99
to
In article <FG9L5...@Watt.COM>,

st...@Watt.COM (Steve Watt) wrote:
> In article <7od054$vtl$1...@nnrp1.deja.com>,
> Tom Dillard <t.di...@santera.com> wrote:
> [ ... trying to use SIGEV_THREAD on Solaris 7 ... ]
> >I receive an error indicating "invalid argument" (errno=EINVAL).
>
> [ snip! ]
>
> >#define A_DESCRIPTIVE_NAME 13
> >
> >main ()
> >{
> > int i;
> > timer_t timer1;
> > struct sigevent signal_spec;
> > //signal_spec.sigev_notify = SIGEV_SIGNAL;
> > signal_spec.sigev_notify = SIGEV_THREAD;
> > signal_spec.sigev_signo = SIGRTMIN;
> > signal_spec.sigev_value.sival_int = A_DESCRIPTIVE_NAME;
>
> OK, here's part of the problem: If you use SIGEV_THREAD, you must set
> the sigev_notify_function member to a function pointer, and the
> sigev_value will be passed to that function in a new thread. The
> thread's attributes are specified by the sigev_notify_attributes
> member. There's no point to specifying a signal number, because
> there's no signal, it's a thread.

Good catch; in my attempt to pare down the code to the problem,
I left that out.

> So the above might want to look like
>
> signal_spec.sigev_notify = SIGEV_THREAD;
> signal_spec.sigev_notify_function = a_function_that_has_C_linkage;
> signal_spec.sigev_notify_attributes = NULL; // means create
detached
>
> > i = ::timer_create (CLOCK_REALTIME, // clock id
> > &signal_spec, // signal event struct to use
> > &timer1); // timer identifier
>
> It is, of course, possible that Solaris doesn't implement
> SIGEV_THREAD, but that seems unlikely to me.

Thanks for the response.

I made the suggested changes and now the timer_create still returns
with errno=22, suggesting that something is still not quite right.
Supposedly this error indicates the clock id is incorrect, but
POSIX requires CLOCK_REALTIME to be supported.

Any more suggestions from anyone, esp. Solaris users?
At this point I'd really like to know if this even works on
Solaris.

Thanks,

Tom

Dave Butenhof

unread,
Aug 11, 1999, 3:00:00 AM8/11/99
to
Steve Watt wrote:

> It is, of course, possible that Solaris doesn't implement SIGEV_THREAD, but
> that seems unlikely to me.

If you'd said "Solaris 7", I'd agree. But then, "unlikely" doesn't help anyone
much. As a coworker is fond of quoting (from "Princess Bride") whenever
someone utters the similarly oft-misused word "inconceivable", "I don't think
that word means what you think it means". ;-)

SIGEV_THREAD is a relatively obscure capability of POSIX 1003.1c-1995, and
rarely used. Both Solaris 2.5 and Digital UNIX 4.0 omitted it from their
initial implementations of POSIX threads. Nobody (or, "hardly anybody")
noticed. (At least, for Digital UNIX, I can confidently state that nobody
bothered to complain, or even to comment, on the omission.) Digital
implemented SIGEV_THREAD for the Digital UNIX 4.0D update. I discovered (with
more than a little amusement) that Solaris had also omitted the function in
2.5, while writing my book. I discussed the issue with Solaris developers, and
was told that it would be supported in 2.6. I've never seen any confirmation
that it was, however, and I have no access to a 2.6 system. Tom's experiences
imply that perhaps it has not been implemented. (Note that he previously asked
me about this in private mail, and, despite the errors you pointed out in the
smaller example he posted here, I saw no errors in his original sample code,
and it runs as expected on Digital/Tru64 UNIX.)

/---------------------------[ Dave Butenhof ]--------------------------\
| Compaq Computer Corporation David.B...@compaq.com |
| 110 Spit Brook Rd ZKO2-3/Q18 http://members.aol.com/drbutenhof |
| Nashua NH 03062-2698 http://www.awl.com/cseng/titles/0-201-63392-2/ |
\-----------------[ Better Living Through Concurrency ]----------------/


Steve Watt

unread,
Aug 12, 1999, 3:00:00 AM8/12/99
to
Dave Butenhof wrote:
>Steve Watt wrote:
>
>> It is, of course, possible that Solaris doesn't implement SIGEV_THREAD, but
>> that seems unlikely to me.
>
>If you'd said "Solaris 7", I'd agree.

Well, I thought it real loud, since you almost heard it. ;) Just didn't
type it...

>SIGEV_THREAD is a relatively obscure capability of POSIX 1003.1c-1995, and
>rarely used.

It's one of the first things that I fixated on as a cool feature. Not to
mention a few dozen customers. Probably a difference in our markets; I
get real-time and embedded people bashing on me. They're a lot more used
to threads.

The next thing that lots o' folks ask for is the ability to set up a signal
handler so it always runs as a created thread. Just an SA_THREAD flag
in the struct sigaction, and an sa_thread_arg member.

All of a sudden, signal handling stops hurting so bad in threaded programs.

Only catch is, synchronous signals are still gross. I haven't figured out
a pleasant way to cope with that, yet.

> [ ... ] despite the errors you pointed out in the


>smaller example he posted here, I saw no errors in his original sample code,
>and it runs as expected on Digital/Tru64 UNIX.

I guess that means that it doesn't work under Solaris 7. Pity I don't have
access to one of those... Interestingly, docs.sun.com doesn't find
SIGEV_THREAD in the Solaris 7 docs. "If it's not in the doc, it ain't
there." Or at least that's what tech support's supposed to say.

Interesting.

Tom Dillard

unread,
Aug 12, 1999, 3:00:00 AM8/12/99
to

> Dave Butenhof wrote:
>SIGEV_THREAD is a relatively obscure capability of POSIX
> 1003.1c-1995, and rarely used.

(at least I think Dave said the above)

Why would this be so obscure? It seems to be exactly what I was looking
for: a way to set up a timer to execute some code when it fires off, and
without having to deal with signals in a threaded environment.

It is is so obscure, and if it is not support (yet) in Solaris 7 (and I
am not certain about that yet; sure would be nice to hear from someone
at Sun ... maybe I'll write a bug report), then what is the recommended
method of setting up timers in a threaded environment? I need several
(more than one, probably less than 50 or so) timers, firing at different
intervals.

Any further comments would be apprciated.

Tom

PS I do believe this must be fairly obscure since only the three of us
seem to be keeping this thread alive (for now :)

Dave Butenhof

unread,
Aug 13, 1999, 3:00:00 AM8/13/99
to
Tom Dillard wrote:

> > Dave Butenhof wrote:
> >SIGEV_THREAD is a relatively obscure capability of POSIX
> > 1003.1c-1995, and rarely used.
>
> (at least I think Dave said the above)

So do I. (But we could both be wrong ;-) )

> Why would this be so obscure? It seems to be exactly what I was looking
> for: a way to set up a timer to execute some code when it fires off, and
> without having to deal with signals in a threaded environment.

It's obscure, not useless. There's a difference. It's obscure because it's
a new capability that hasn't been widely advertised, and is not something a
"traditional UNIX programmer" would tend to discover by accident. (Of
course one reason it was never widely advertised may be that the first two
vendors to implement POSIX threads didn't get around to coding SIGEV_THREAD
in the first pass.) It may also be obscure because SIGEV_THREAD was a "last
minute" addition to the standard. Many people have been working with old
draft implementations for nearly 10 years, and know "all the basics". Most
of that experience carries over pretty well to the standard interface, with
minor adjustments. That experience includes sigwait and family, but not
SIGEV_THREAD.

> It is is so obscure, and if it is not support (yet) in Solaris 7 (and I
> am not certain about that yet; sure would be nice to hear from someone
> at Sun ... maybe I'll write a bug report), then what is the recommended
> method of setting up timers in a threaded environment? I need several
> (more than one, probably less than 50 or so) timers, firing at different
> intervals.

You could just use POSIX timers with realtime signals. You could have a
thread sit around and snap them up with sigwaitinfo(). Creating a thread
for each timer event is probably overkill anyway. (Although most
implementations probably WON'T actually create a new thread, the
alternative generally means that the timer events are received in series
just as for a sigwaitinfo loop. Which probably doesn't matter anyway unless
your processing of each is really long and the timer interval is really
short.)

> Any further comments would be apprciated.

/* */ C comment
// C++ comment
# Shell comment
(* *) Pascal comment

Any more comments?

(OK, I've spent too long trying to (ab)use Communicator to move folders
from one IMAP server to another this morning, and after too many crashes
and missed messages, I fear I'm getting punchy.)

> PS I do believe this must be fairly obscure since only the three of us
> seem to be keeping this thread alive (for now :)

Exactly. Too bad some "in the know" Sun person hasn't joined in. (You could
try over at comp.unix.solaris and see what happens.)

Bill Segall

unread,
Aug 15, 1999, 3:00:00 AM8/15/99
to
As a person who's trying to program a server to accept lots of connections
and packets via thread pools I was hoping to use aio_*() with SIGEV_THREAD.
The fact that it's not widely available makes it usefulness on those
platforms that do support it dubious because I can't rely on this for my
comms and have to write my code for other platforms anyway (even if this
wsa my preferred option).

If Solaris and TRU64 both support it, it's likely to appear in Linux
because of porting requirements (although aio isn't really there in a
meaningful sense) and with win32 offering similar functionality we can
rely on the other vendors to come into line in time.

I thought it was a nice and useful abastraction throwing much of the work
back to the kernel where it can be efficiently reentrant. My point is that
it's obscure because it's obscure. Build it and they will come :-)

Bill.

Andi Kleen

unread,
Aug 15, 1999, 3:00:00 AM8/15/99
to
bi...@dstc.edu.au (Bill Segall) writes:

> If Solaris and TRU64 both support it, it's likely to appear in Linux
> because of porting requirements (although aio isn't really there in a
> meaningful sense) and with win32 offering similar functionality we can
> rely on the other vendors to come into line in time.

What do you mean? glibc 2.1 aio seems to work reasonably.

-Andi

--
This is like TV. I don't like TV.

Dave Butenhof

unread,
Aug 16, 1999, 3:00:00 AM8/16/99
to
Bill Segall wrote:

> As a person who's trying to program a server to accept lots of connections
> and packets via thread pools I was hoping to use aio_*() with SIGEV_THREAD.
> The fact that it's not widely available makes it usefulness on those
> platforms that do support it dubious because I can't rely on this for my
> comms and have to write my code for other platforms anyway (even if this
> wsa my preferred option).

All true. But so what? There's nothing I can do about it. SIGEV_THREAD is not
an option. It is required for any implementation to even claim to pretend to
conform to POSIX threads. Any "POSIX threads" that doesn't correctly support
SIGEV_THREAD is broken, to the point where claiming to be "POSIX threads" is a
blatent lie.

Everyone knows that lies are quite common in this world. There're also big
gray areas. (If someone tried, but failed, is it "not POSIX threads", or just
"POSIX threads with a bug"?) There was never any validation suite for POSIX
threads, and many implementors didn't understand the standard any more than
many users. Software developers have a wide range of conflicting pressures,
and it's not always to do everyone one might wish. (I did not wish to release
a "POSIX threads" that wasn't complete for Digital UNIX 4.0; but given
available time and resources, the real decisions are a lot more complicated
than that.)

The bottom line, though, is that any "POSIX threads" without SIGEV_THREAD is
broken. If you find that it doesn't work on some system, report the bug. There
are all sorts of reasons (noble and otherwise) why it might not get fixed
unless someone complains. (Such as, "we've shipped 3 major releases with this
feature completely broken, and nobody's complained, so clearly nobody cares,
and we'd be far better off putting our limited engineering resources into
other work".)

0 new messages