Thread: Signal generation and handling

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    7

    Signal generation and handling

    Hi,

    I'm using
    Code:
     int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
    to register my realtime signal and the
    Code:
             void     (*sa_sigaction)(int, siginfo_t *, void *);
    callback handler to detect the availabilty of input data (si_code==POLL_IN) on my file descriptor(a serial port).

    My question is how often is the POLL_IN (i.e a SIGPOLL type) event generated by the kernel and is there someway i can suspend the signal generation for a certain time out? The problem that I'm facing is that the signal seems to be generated for every single character received on my port and my read() in the callback always reads only a byte or two.

    I don't want this to happen as i want to read a chunk of data in one go (which i KNOW is available for sure once the fist byte becomes available).

    Thanks.
    Ravi
    Last edited by itisravi; 03-22-2010 at 02:00 AM.

  2. #2
    Registered User
    Join Date
    Jan 2010
    Posts
    7
    Been reading up on signals. I gather that once inside the handler,by default, the signal which called the handler is blocked from triggering again until the handler completes. So i called sleep() (which is guaranteed to be reentrant inside the handler) in it
    Code:
    void (*sa_sigaction)(int i, siginfo_t * t, void * p){
      //blah blah
      sleep(1);//1 second
      numbytes=read(fd,buffer,255);
      //blah blah
    }
    This seems to work fine but I'm wondering if this a right approach.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I'd just use a static buffer with a write pointer into it and do it with the POLL calls, ie, adding a few characters at a time -- this way it will be sure to complete, and in parallel with the actual events.

    Unless you are sure 1 second or whatever is always going to be long enough.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Jan 2010
    Posts
    7
    Hello MK27,

    Thanks for the reply. Looked into POLL. I want something that's asynchronous. If i were to achieve asynchronous notification using POLL, may be i need to run an infinite loop on POLL as a separate thread...

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I've never used a signal handler inside a thread, but if it works (it should, it's still the same process*) that's a good idea, then you can just use a mutex on the global buffer, so you can read from as necessary in the main thread. A pretty standard producer/consumer task.

    *I guess the question is: will registering a signal handler in a thread count? Try it out.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > I don't want this to happen as i want to read a chunk of data in one go (which i KNOW is available for sure once the fist byte becomes available).
    So why aren't you using either poll() or select() to wait for the file descriptor to have some data?

    > This seems to work fine but I'm wondering if this a right approach.
    Signal handlers should do the minimum amount of work in the least amount of time you can get away with.
    Calling sleep() for a whole second doesn't sound right to me at all.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jan 2010
    Posts
    7
    Quote Originally Posted by Salem View Post
    >
    So why aren't you using either poll() or select() to wait for the file descriptor to have some data?
    select and poll are functions that block (with timeout options). Now if i want to _continuously_ monitor the files for input, i need to call these functions inside a while loop.This means my program is stuck up in this event loop.The _only_ way to do other things is to run this loop as a separate thread.Is my understanding right?
    Thanks.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    How many file descriptors are you monitoring?

    - you can watch the fd's for your serial port
    - you can watch fd's for network sockets
    - you can even watch the fd for stdin
    - you can even have the timeout as noted.

    With all this, you call select(). When it returns, you examine the FD_SET to see what actually happened and you read all the fd's with something useful to report.

    And if you want to make sure you can do things in case there is no input at all, that is what you use the timeout for.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Jan 2010
    Posts
    7
    @Salem
    I'm actually monitoring only one fd (my serial port). My question is: Is threading the only way to go, because i want to continuously monitor for any input data on the port (and read it if it's available).This monitoring should happen all the time the program is running. I want to do other things in parallel irrespective of the fd being available for a read. With the sigaction, i did not have to do this continuous monitoring (the system did it for me and promptly notified my callback when the data was available).Hope I'm conveying my thoughts.

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You may want to have a look at this:

    IO Channels

    Probably you will need to read the entire page, etc, but I've used that function before, it's great -- it does not block execution, it monitors a "GIOChannel" (a registered file descriptor) and calls the "GIOfunc" (any function with a specific prototype) when there is data waiting to be read. You may need to use it in the context of a glib event loop, so you will have to study glib a bit which is probably worth it if you are programming on linux, since glib is standard on all normative linux systems and used extensively by it and various standard apps. Alot of useful things in glib.

    eg.
    Code:
            g_io_add_watch_full(remote,2,G_IO_IN,(GIOFunc)sortCall,NULL,NULL);
            g_io_add_watch_full(remote,1,G_IO_HUP,(GIOFunc)pipeBroke,NULL,NULL);
    This is two watches on the same channel, one to respond to G_IO_IN, and one to G_IO_HUP -- which occurs if a connection unexpectedly breaks.
    Last edited by MK27; 03-23-2010 at 07:03 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    With either the sigaction or threads, you have the problem of how to announce to the rest of the application that the data is available and complete.

    I'm not sure what you mean by "continuous" though. You have a sleep(1) in there, so is that really any different from calling poll() once a second, then reading the whole data?

    What is the "rest of the program" doing (a short description)?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed