Timer Pulses

I’m trying to configure a timer with the timer_create() function to send a
pulse when it expires. I had read that the value returned from name_open is
equivalent to the coid returned by ConnectAttach. When I use the file
descriptor from name_open to initialize the signal sigevent structure, then
try to run the timer, I don’t receive any of the pulse messages. If I use
the ConnectAttach to init the sigevent, everything works as expected. Is the
help file on name_attach wrong, or am I trying to do something incorrect.

Following is a short test that demonstrates my problem. when _USE_CCT_ATT is
defined, everything works well. When it isn’t, the pulses aren’t received.

Thanks for your help,
David Kuechenmeister

#include <stdio.h>
#include <syslog.h>
#include <sys/neutrino.h>
#include <sys/dispatch.h>

#define _USE_CCT_ATT
#undef _USE_CCT_ATT
#define _PULSE_CODE_STOW_FAIL 10

int main(void)
{
struct _pulse msg;
name_attach_t *attach;

struct itimerspec timerVal;
int coid;
struct sigevent sigEventT1;
timer_t timerT1ID;

int axis = 0;


timerVal.it_value.tv_sec = (long int)10;
timerVal.it_value.tv_nsec = 0;
timerVal.it_interval.tv_sec = (long int)1;
timerVal.it_interval.tv_nsec = 0;

#ifdef _USE_CCT_ATT
int chid = ChannelCreate(0);
coid = ConnectAttach(0,0,chid,_NTO_SIDE_CHANNEL,0);
#else
// create the channel
if ((attach = name_attach(NULL, “testTimer”, 0)) == NULL) {
syslog(LOG_ERR,“name_attach failed…%m”);
}
// get coid for timer
if((coid = name_open(“testTimer”,0) < 0))
{
syslog(LOG_ERR,“name_open failed…%m”);
}
#endif
// Set up the timer
sigEventT1.sigev_notify = SIGEV_PULSE;
sigEventT1.sigev_coid = coid;
sigEventT1.sigev_priority = getprio(0);
sigEventT1.sigev_code = _PULSE_CODE_STOW_FAIL;
sigEventT1.sigev_value.sival_int = axis;

if(timer_create(CLOCK_REALTIME, &sigEventT1, &timerT1ID) < 0)
{
syslog(LOG_ERR,“CStowPed:timer_create failed for T1…%m”);
}
if(timer_settime(timerT1ID, 0, &timerVal, NULL) < 0)
{
syslog(LOG_ERR,“CStowPed::timer_settime failed for T1…%m”);
}


int rcvid;
for(int i=0;i<10;i++)
{
#ifdef _USE_CCT_ATT
rcvid = MsgReceive(chid,&msg,sizeof(msg),NULL);
#else
rcvid = MsgReceive(attach->chid,&msg,sizeof(msg),NULL);
#endif
if(rcvid == 0)
{
if(msg.code == _PULSE_CODE_STOW_FAIL)
{
printf(“Received timer pulse\n”);
}
else
{
printf(“Received some other pulse %d\n”,msg.code);
}
}
else
{
printf(“Received some other message, rcvid = %d\n”,rcvid);
}
}
}

if((coid = name_open(“testTimer”,0) < 0)) should be
if( (coid =nameopen()) < 0 ) …

Weijie

“David Kuechenmeister” <david.kuechenmeister@viasat.com> wrote in message
news:b1engd$410$1@inn.qnx.com

I’m trying to configure a timer with the timer_create() function to send a
pulse when it expires. I had read that the value returned from name_open
is
equivalent to the coid returned by ConnectAttach. When I use the file
descriptor from name_open to initialize the signal sigevent structure,
then
try to run the timer, I don’t receive any of the pulse messages. If I use
the ConnectAttach to init the sigevent, everything works as expected. Is
the
help file on name_attach wrong, or am I trying to do something incorrect.

Following is a short test that demonstrates my problem. when _USE_CCT_ATT
is
defined, everything works well. When it isn’t, the pulses aren’t received.

Thanks for your help,
David Kuechenmeister

#include <stdio.h
#include <syslog.h
#include <sys/neutrino.h
#include <sys/dispatch.h

#define _USE_CCT_ATT
#undef _USE_CCT_ATT
#define _PULSE_CODE_STOW_FAIL 10

int main(void)
{
struct _pulse msg;
name_attach_t *attach;

struct itimerspec timerVal;
int coid;
struct sigevent sigEventT1;
timer_t timerT1ID;

int axis = 0;


timerVal.it_value.tv_sec = (long int)10;
timerVal.it_value.tv_nsec = 0;
timerVal.it_interval.tv_sec = (long int)1;
timerVal.it_interval.tv_nsec = 0;

#ifdef _USE_CCT_ATT
int chid = ChannelCreate(0);
coid = ConnectAttach(0,0,chid,_NTO_SIDE_CHANNEL,0);
#else
// create the channel
if ((attach = name_attach(NULL, “testTimer”, 0)) == NULL) {
syslog(LOG_ERR,“name_attach failed…%m”);
}
// get coid for timer
if((coid = name_open(“testTimer”,0) < 0))
{
syslog(LOG_ERR,“name_open failed…%m”);
}
#endif
// Set up the timer
sigEventT1.sigev_notify = SIGEV_PULSE;
sigEventT1.sigev_coid = coid;
sigEventT1.sigev_priority = getprio(0);
sigEventT1.sigev_code = _PULSE_CODE_STOW_FAIL;
sigEventT1.sigev_value.sival_int = axis;

if(timer_create(CLOCK_REALTIME, &sigEventT1, &timerT1ID) < 0)
{
syslog(LOG_ERR,“CStowPed:timer_create failed for T1…%m”);
}
if(timer_settime(timerT1ID, 0, &timerVal, NULL) < 0)
{
syslog(LOG_ERR,“CStowPed::timer_settime failed for T1…%m”);
}


int rcvid;
for(int i=0;i<10;i++)
{
#ifdef _USE_CCT_ATT
rcvid = MsgReceive(chid,&msg,sizeof(msg),NULL);
#else
rcvid = MsgReceive(attach->chid,&msg,sizeof(msg),NULL);
#endif
if(rcvid == 0)
{
if(msg.code == _PULSE_CODE_STOW_FAIL)
{
printf(“Received timer pulse\n”);
}
else
{
printf(“Received some other pulse %d\n”,msg.code);
}
}
else
{
printf(“Received some other message, rcvid = %d\n”,rcvid);
}
}
}

Thanks, it’s amazing what a parenthesis in the wrong place can do.

Sincerely,
David Kuechenmeister

“Weijie Zhang” <wzhang@qnx.com> wrote in message
news:b1m5d1$4s0$1@nntp.qnx.com

if((coid = name_open(“testTimer”,0) < 0)) should be
if( (coid =nameopen()) < 0 ) …

Weijie

David Kuechenmeister <david.kuechenmeister@viasat.com> wrote:

Note: you don’t need to name_open() again… you can use ConnectAttach()
in the second case as well (it will be cheaper).


#include <stdio.h
#include <syslog.h
#include <sys/neutrino.h
#include <sys/dispatch.h

#define _USE_CCT_ATT
#undef _USE_CCT_ATT
#define _PULSE_CODE_STOW_FAIL 10

int main(void)
{
struct _pulse msg;
name_attach_t *attach;

struct itimerspec timerVal;
int coid;
struct sigevent sigEventT1;
timer_t timerT1ID;

int axis = 0;



timerVal.it_value.tv_sec = (long int)10;
timerVal.it_value.tv_nsec = 0;
timerVal.it_interval.tv_sec = (long int)1;
timerVal.it_interval.tv_nsec = 0;

#ifdef _USE_CCT_ATT
int chid = ChannelCreate(0);
coid = ConnectAttach(0,0,chid,_NTO_SIDE_CHANNEL,0);
#else
// create the channel
if ((attach = name_attach(NULL, “testTimer”, 0)) == NULL) {
syslog(LOG_ERR,“name_attach failed…%m”);
}
// get coid for timer

Use ConnectAttach() instead of name_open() as you don’t need to locate
the pid & chid – you know them.

coid = ConnectAttach(0, 0, attach->chid, _NTO_SIDE_CHANNEL, 0 );

if(coid < 0)
{
syslog(LOG_ERR,“name_open failed…%m”);
}

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

In the final version, the name_open function is used in a process other than
the one that calls name_attach. I don’t know any other way to make the
channel than name_open, in that case.

In what sense is it “cheaper”? I establish message queues once, during the
program initialization, so time doesn’t matter. On a micro/millisecond
scale, anyway.

Thanks,

]“David Gibbs” <dagibbs@qnx.com> wrote in message
news:b1n21g$lg0$3@nntp.qnx.com

David Kuechenmeister <> david.kuechenmeister@viasat.com> > wrote:

Note: you don’t need to name_open() again… you can use ConnectAttach()
in the second case as well (it will be cheaper).


#include <stdio.h
#include <syslog.h
#include <sys/neutrino.h
#include <sys/dispatch.h

#define _USE_CCT_ATT
#undef _USE_CCT_ATT
#define _PULSE_CODE_STOW_FAIL 10

int main(void)
{
struct _pulse msg;
name_attach_t *attach;

struct itimerspec timerVal;
int coid;
struct sigevent sigEventT1;
timer_t timerT1ID;

int axis = 0;


timerVal.it_value.tv_sec = (long int)10;
timerVal.it_value.tv_nsec = 0;
timerVal.it_interval.tv_sec = (long int)1;
timerVal.it_interval.tv_nsec = 0;

#ifdef _USE_CCT_ATT
int chid = ChannelCreate(0);
coid = ConnectAttach(0,0,chid,_NTO_SIDE_CHANNEL,0);
#else
// create the channel
if ((attach = name_attach(NULL, “testTimer”, 0)) == NULL) {
syslog(LOG_ERR,“name_attach failed…%m”);
}
// get coid for timer

Use ConnectAttach() instead of name_open() as you don’t need to locate
the pid & chid – you know them.

coid = ConnectAttach(0, 0, attach->chid, _NTO_SIDE_CHANNEL, 0 );

if(coid < 0)
{
syslog(LOG_ERR,“name_open failed…%m”);
}

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Kuechenmeister <david.kuechenmeister@viasat.com> wrote:

In the final version, the name_open function is used in a process other than
the one that calls name_attach. I don’t know any other way to make the
channel than name_open, in that case.

No, you need name_open() in that case.

But…you’re saying you want to create a timer in one process that
automatically delivers pulses to a different process? Or was the
timer stuff also just “sample” stuff, not real? Cause, I don’t think
that will work. You can get pulses sent to yourself by a timer,
but not to some other process.

Whereas if you are doing a timer, then you can use ConnectAttach().

In what sense is it “cheaper”?

name_open() has to do all the name lookup stuff talking to proc to
look up the name and find the server, then basically do a
ConnectAttach().

Probably about an order of magnitude longer to do name_open() than
ConnectAttach(), but ConnectAttach() is probably order of magnitude
10 us, so name_open() order of magnitude 100 us.

I establish message queues once, during the
program initialization, so time doesn’t matter. On a micro/millisecond
scale, anyway.

Both would, I expect, be sub-millisecond, just how big a fraction.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Hi David,

David Gibbs a écrit:

David Kuechenmeister <> david.kuechenmeister@viasat.com> > wrote:


In the final version, the name_open function is used in a process other than
the one that calls name_attach. I don’t know any other way to make the
channel than name_open, in that case.



No, you need name_open() in that case.

But…you’re saying you want to create a timer in one process that
automatically delivers pulses to a different process? Or was the
timer stuff also just “sample” stuff, not real? Cause, I don’t think
that will work.

…cut…

Why not? a pulse is able to go from a process to another, if the coid is
well defined, I don’t see what could prevent it.

regards,
Alain

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:b1s3ie$6f9$4@nntp.qnx.com

David Kuechenmeister <> david.kuechenmeister@viasat.com> > wrote:
In the final version, the name_open function is used in a process other
than
the one that calls name_attach. I don’t know any other way to make the
channel than name_open, in that case.

No, you need name_open() in that case.

But…you’re saying you want to create a timer in one process that
automatically delivers pulses to a different process? Or was the
timer stuff also just “sample” stuff, not real? Cause, I don’t think
that will work. You can get pulses sent to yourself by a timer,
but not to some other process.

My example was completely artificial. The example I posted was extracted

from a real system, but only served to demonstrate my inability to manage
parentheses. After the correction, the system works as expected. Pulses go
where they are supposed to.

Regards,

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

Hi David,

David Gibbs a écrit:

David Kuechenmeister <> david.kuechenmeister@viasat.com> > wrote:


In the final version, the name_open function is used in a process other than
the one that calls name_attach. I don’t know any other way to make the
channel than name_open, in that case.



No, you need name_open() in that case.

But…you’re saying you want to create a timer in one process that
automatically delivers pulses to a different process? Or was the
timer stuff also just “sample” stuff, not real? Cause, I don’t think
that will work.

…cut…

Why not? a pulse is able to go from a process to another,

Not always. (See below, or docs for MsgSendPulse()).

if the coid is well defined, I don’t see what could prevent it.

Actually, it does work. I tested it.

I don’t think it SHOULD work, though, for a couple reasons.

  1. style

With timers, you can only deliver a signal to yourself, the
pulses were intended as an extention of the notification type,
but not of the “where to target”.

  1. security

The rules for MsgSendPulse() do not allow you to send a pulse to
a server unless you are same userid or sender is root. (same rules
as for signal delivery). For signals, so you can’t kill other people…
for pulses, so you can’t deliver arbitary pulses.

So…

fd = open("/tmp/…");// point to devb-eide, filesystem
SIGEV_PULSE_INIT ( &ev, fd, 63, _PULSE_CODE_UNBLOCK, rcvid_of_someone_else );
timer_create(&ev);
timer_settime();

Oops… we are now unblocking someone else from the filesystem, cause
the timer chain can deliver pulses anywhere.

I am going to issue a PR against this.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Hop,Hop,Hop!!! Don’t know what is a PR but just think of what you are
going to do first!
I’m not sure to have well understood everything.
Maybe you could take care of what kind of pulse you are going to send
somewhere but don’t prevent it or I’m affraid that I will put all my
developments for 3 years ashore!

regards,
Alain.

David Gibbs a écrit:

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:


Hi David,





David Gibbs a écrit:





David Kuechenmeister <> david.kuechenmeister@viasat.com> > wrote:




In the final version, the name_open function is used in a process other than
the one that calls name_attach. I don’t know any other way to make the
channel than name_open, in that case.




No, you need name_open() in that case.

But…you’re saying you want to create a timer in one process that
automatically delivers pulses to a different process? Or was the
timer stuff also just “sample” stuff, not real? Cause, I don’t think
that will work.



…cut…





Why not? a pulse is able to go from a process to another,



Not always. (See below, or docs for MsgSendPulse()).



if the coid is well defined, I don’t see what could prevent it.



Actually, it does work. I tested it.

I don’t think it SHOULD work, though, for a couple reasons.

  1. style

With timers, you can only deliver a signal to yourself, the
pulses were intended as an extention of the notification type,
but not of the “where to target”.

  1. security

The rules for MsgSendPulse() do not allow you to send a pulse to
a server unless you are same userid or sender is root. (same rules
as for signal delivery). For signals, so you can’t kill other people…
for pulses, so you can’t deliver arbitary pulses.

So…

fd = open("/tmp/…");// point to devb-eide, filesystem
SIGEV_PULSE_INIT ( &ev, fd, 63, _PULSE_CODE_UNBLOCK, rcvid_of_someone_else );
timer_create(&ev);
timer_settime();

Oops… we are now unblocking someone else from the filesystem, cause
the timer chain can deliver pulses anywhere.

I am going to issue a PR against this.

-David