Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

checking value of variable while blocking in a system call
I am trying to write some code that writes to a FIFO (whenever there is
a reader, of course) but can't figure out how I can be able to block in
the call to open() (waiting for a reader), and at the same time check
the value of a variable (sig_atomic_t exit_flag, set to 1 when SIGINT or
SIGTERM is recieved).

I did find one way to do it, but it uses too much CPU polling (adding a
call to sleep(1) does help tremendously but just doesn't seem like The
Right Way to me):

while(!exit_flag) {
..
fd = open(file, O_WRONLY | O_NONBLOCK);
if(fd < 0) {
if(errno == ENXIO)
continue;
..
}
..
}

I thought of possibly using select() (?), but I've never used it before
and it seems complicated from reading the manual page.  I checked in
UNPv2 and got the basic concept of select(), however, Mr. Stevens uses
it in a network context.  From reading the manual page, though, I think
it would still end up blocking somewhere.

I'm out of ideas... can someone spare any?

Thanks
--
"And remember: Evil will always prevail, because Good is dumb." --
Spaceballs

/*  Aaron Walker
*  http://ka0ttic.butsugenjitemple.org/
*/

Report this thread to moderator Post Follow-up to this message
Old Post
Aaron Walker
07-30-04 08:57 PM


Re: checking value of variable while blocking in a system call
Aaron Walker <ka0ttic@butsugenjitemple.org> writes:

> I am trying to write some code that writes to a FIFO (whenever there
> is a reader, of course) but can't figure out how I can be able to
> block in the call to open() (waiting for a reader), and at the same
> time check the value of a variable (sig_atomic_t exit_flag, set to 1
> when SIGINT or SIGTERM is recieved).

Blocking system calls usually return with an errno of EINTR if a
signal arrives.

> I thought of possibly using select() (?), but I've never used it
> before and it seems complicated from reading the manual page.

Just bite the bullet, you'll have to learn how to use select() sooner
or later.

> I checked in UNPv2 and got the basic concept of select(), however,
> Mr. Stevens uses it in a network context.

select() can be used with any file descriptor.

> From reading the manual page, though, I think it would still end up
> blocking somewhere.

Of course, that's the idea with select().  However, select(), unlike
open/read/write etc., allows you to specify a timeout.

--
Måns Rullgård
mru@kth.se

Report this thread to moderator Post Follow-up to this message
Old Post
Måns Rullgård
07-30-04 08:57 PM


Re: checking value of variable while blocking in a system call
Aaron Walker <ka0ttic@butsugenjitemple.org> wrote:
> I am trying to write some code that writes to a FIFO (whenever there is
> a reader, of course) but can't figure out how I can be able to block in
> the call to open() (waiting for a reader), and at the same time check
> the value of a variable (sig_atomic_t exit_flag, set to 1 when SIGINT or
> SIGTERM is recieved).

If I am understanding you correctly you have a signal handler in
the background that sets 'exit_flag' when the signal arrives. If
the signal arrives also the open() call should return and you
get a -1 return value and errno is set to EINTR. Now you can
check if the value of 'exit_flag' has been changed and thus
determine if the signal you were waiting for has arrived. So
I would guess you don't need select() or anything complicated
at all - just call open() in blocking mode and wait for it to
return. If it's because of the signal you'll know because of
the return value and errno being set to EINTR.

Regards, Jens
--
\   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
\__________________________  http://www.toerring.de

Report this thread to moderator Post Follow-up to this message
Old Post
Jens.Toerring@physik.fu-berlin.de
07-30-04 08:57 PM


Re: checking value of variable while blocking in a system call
Måns Rullgård wrote:
> Aaron Walker <ka0ttic@butsugenjitemple.org> writes:
>
> 
>
>

Firstly, thanks for such a quick response.

> Blocking system calls usually return with an errno of EINTR if a
> signal arrives.

That's what I thought too, however, when adding a check for EINTR, into
a normal (blocking) call to open(), nothing happens at all when the
program is thrown a SIGINT or SIGTERM.

>
> 
>
>
> Just bite the bullet, you'll have to learn how to use select() sooner
> or later.

That's what I'm trying to do ;p

>
> 
>
>
> select() can be used with any file descriptor.

I know that, I was just mainly  about one thing.  Wouldn't you
have to open() the descriptor before placing it in a fd_set and calling
select()?  If that's the case then I have the same problem.

>
> 
>
>
> Of course, that's the idea with select().  However, select(), unlike
> open/read/write etc., allows you to specify a timeout.
>

what's the best way of going about choosing a timeout?  I'm clueless here...

Thanks again
--
BOFH Excuse #404: Symin accidentally destroyed pager with a large hammer.

/*  Aaron Walker
*  http://ka0ttic.butsugenjitemple.org/
*/

Report this thread to moderator Post Follow-up to this message
Old Post
Aaron Walker
07-30-04 08:57 PM


Re: checking value of variable while blocking in a system call
Jens.Toerring@physik.fu-berlin.de wrote:
> Aaron Walker <ka0ttic@butsugenjitemple.org> wrote:
> 
>
>
> If I am understanding you correctly you have a signal handler in
> the background that sets 'exit_flag' when the signal arrives. If
> the signal arrives also the open() call should return and you
> get a -1 return value and errno is set to EINTR. Now you can
> check if the value of 'exit_flag' has been changed and thus
> determine if the signal you were waiting for has arrived. So
> I would guess you don't need select() or anything complicated
> at all - just call open() in blocking mode and wait for it to
> return. If it's because of the signal you'll know because of
> the return value and errno being set to EINTR.
>
>                                     Regards, Jens


As I said in my other post a second ago, I tried this, expecting it to
work as well, but it didn't.  Here's the code I had attempting to do this:

sig_atomic_t exit_flag = FALSE;

void
signal_handler(int signal)
{
exit_flag = TRUE;
}

int
main(int argc, char **argv)
{
int fd, exit_status;
struct sigaction sig;
..
sig.sa_handler = &signal_handler;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
..
while(!exit_flag) {
..
fd = open(file, O_WRONLY);
if(fd < 0) {
if(errno == EINTR) {
if(exit_flag)
break;
else continue;
}
perror("open");
exit_status = EXIT_FAILURE;
break;
}
..
}
..
}

Any reason why this wouldn't work?
Thanks again
--
Knocked, you weren't in. -- Opportunity

/*  Aaron Walker
*  http://ka0ttic.butsugenjitemple.org/
*/

Report this thread to moderator Post Follow-up to this message
Old Post
Aaron Walker
07-30-04 08:57 PM


Re: checking value of variable while blocking in a system call
Aaron Walker <ka0ttic@butsugenjitemple.org> wrote:
> As I said in my other post a second ago, I tried this, expecting it to
> work as well, but it didn't.  Here's the code I had attempting to do this:

> sig_atomic_t exit_flag = FALSE;

> void
> signal_handler(int signal)
> {
> 	exit_flag = TRUE;
> }

> int
> main(int argc, char **argv)
> {
> 	int fd, exit_status;
> 	struct sigaction sig;
> 	...
> 	sig.sa_handler = &signal_handler;
> 	sigemptyset(&sig.sa_mask);
> 	sig.sa_flags = 0;
> 	...
> 	while(!exit_flag) {
> 		...
> 		fd = open(file, O_WRONLY);
> 		if(fd < 0) {
> 			if(errno == EINTR) {
> 				if(exit_flag)
> 					break;
> 				else continue;
> 			}
> 			perror("open");
> 			exit_status = EXIT_FAILURE;
> 			break;
> 		}
> 		...
> 	}
> 	...
> }

After filling in the missing pieces (i.e. actually installing the
signal handler etc.) it works perfectly well for me - when I send
it a SIGINT or SIGTERM I can see that errno is set to EINTR and
that 'exit_flag' has been set to 1. I don't know why it isn't
working for you - can you post a complete program that doesn't
interrupts open() on a signal? Otherwise it's going to be hard to
figure out what's wrong.
Regards, Jens
--
\   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
\__________________________  http://www.toerring.de

Report this thread to moderator Post Follow-up to this message
Old Post
Jens.Toerring@physik.fu-berlin.de
07-30-04 08:57 PM


Re: checking value of variable while blocking in a system call
Jens.Toerring@physik.fu-berlin.de wrote:

>
> After filling in the missing pieces (i.e. actually installing the
> signal handler etc.) it works perfectly well for me - when I send
> it a SIGINT or SIGTERM I can see that errno is set to EINTR and
> that 'exit_flag' has been set to 1. I don't know why it isn't
> working for you - can you post a complete program that doesn't
> interrupts open() on a signal? Otherwise it's going to be hard to
> figure out what's wrong.
>                                    Regards, Jens


http://cvs.butsugenjitemple.org/vie....viewcvs-markup

once again, thanks for your help.

Cheers

Report this thread to moderator Post Follow-up to this message
Old Post
Aaron Walker
07-30-04 08:57 PM


Re: checking value of variable while blocking in a system call
Aaron Walker <ka0ttic@butsugenjitemple.org> wrote:
> Jens.Toerring@physik.fu-berlin.de wrote: 

> http://cvs.butsugenjitemple.org/vie....viewcvs-markup

Sorry, but

jens@john:~> ping cvs.butsugenjitemple.org
ping: unknown host cvs.butsugenjitemple.org

Regards, Jens
--
\   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
\__________________________  http://www.toerring.de

Report this thread to moderator Post Follow-up to this message
Old Post
Jens.Toerring@physik.fu-berlin.de
07-30-04 08:57 PM


Re: checking value of variable while blocking in a system call
Jens.Toerring@physik.fu-berlin.de wrote:
> Aaron Walker <ka0ttic@butsugenjitemple.org> wrote:
> 
>
> 
>
>
> Sorry, but
>
> jens@john:~> ping cvs.butsugenjitemple.org
> ping: unknown host cvs.butsugenjitemple.org
>
>                                         Regards, Jens

Hmm... maybe virtual hosting isn't working as well as I thought ;)

This one *should* work:

http://butsugenjitemple.org/viewcvs....viewcvs-markup

Apologies

Aaron

Report this thread to moderator Post Follow-up to this message
Old Post
Aaron Walker
07-30-04 08:57 PM


Re: checking value of variable while blocking in a system call
Aaron Walker <ka0ttic@butsugenjitemple.org> writes:

> Jens.Toerring@physik.fu-berlin.de wrote: 
>
> Hmm... maybe virtual hosting isn't working as well as I thought ;)
>
> This one *should* work:
>
> http://butsugenjitemple.org/viewcvs....viewcvs-markup

Remove these lines:

#ifdef SA_RESTART
sig.sa_flags |= SA_RESTART;
#endif

The SA_RESTART flag tells the OS that you do not want system calls to
return on signals.

--
Måns Rullgård
mru@kth.se

Report this thread to moderator Post Follow-up to this message
Old Post
Måns Rullgård
07-30-04 08:57 PM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

Unix Programming archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 04:27 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.