3

I have some code that reads the serial port on my pinguin box. Code is like:

while ( 1 )  
if ( select( handle + 1, &h, NULL, NULL, &tm ) > 0 )  
{  
    if( read( handle, &msg, 1 ) > 0 )  
    {  
        ... tips and trixes  
    }  
    if ( gotWhatINeed ) break;  

Code runs for pretty long time okay, but if I try to stress it a little I start to get errno 11 (EAGAIN) constantly, even after the stress completed. And now I am wondering what I misunderstand, from man 2 select I can understand select returns the number of bytes availible from the handle.

Maybe it is of interest that the code always runs in a detached thread.

Based on the comments, I now post more details of the code.

In main I have

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

int main ( int argc, char **argv )
{
    pthread_t scan_01
    signal( 11, OnSignal );
    pthread_mutex_init( &mut, NULL );
    .....
    pthread_create(&scan_01, NULL, (void *)readDevice, NULL);
    pthread_detach(scan_01);

And the method where the device is read. TGM is a structure to hold the data read. OnSignal is just logging the signal. _note: ques

void *readDevice(void)
{
    int r;
    char  b[256];
    struct TGM tgm;
    pthread_t new, self;
    pthread_mutex_lock( &mut );
    self = pthread_self( );
    while( 1 )
    {
        FD_ZERO( &out );
        FD_SET( fOut, &out );
        tm.tv_sec = LOOP_DELAY;
        tm.tv_usec = com_scan_time;

        if ( select( fOut + 1, & out, NULL, NULL, &tm ) > 0 )
        {
            r = readPort( fOut, 10, b, 1 );
            pthread_mutex_unlock( &mut );
            pthread_create( &new, NULL, (void *)readDevice, NULL );
            pthread_detach( new );
            iThreads++;
            ...
            break;

        }    
    }
    self = pthread_self();
    iThreads--;
    pthread_exit( & self );

readPort is like, main task is "just" to translate bits and bytes to a TGM.

int readPort(const int handle, char terminator, char b[256], int crc)
{
    char    msg;
    fd_set  h;
    struct  timeval tm;

    do
    {
        FD_ZERO( &h );
        FD_SET( handle, &h );
        tm.tv_sec  = LOOP_DELAY;
        tm.tv_usec = com_scan_time;

        if ( select( handle + 1, &h, NULL, NULL, &tm ) > 0 )
        {
            if( read( handle, &msg, 1 ) > 0 )
            {

                if( msg == 3 ) // marks end of message
                ....
            }
            else
            {
                log( ERRLOG, "FAILED to read port (%d) %s\n", 
                    errno, 
                    strerror( errno ) );
                return -1;
            }

Now where is my failure :D The output I get when injecting, after some 30 messages ( means after aprox. 30 threads - sometimes a little more, and sometimes a little less is ) FAILED to read port (11) Resource temporarily unavailable _Signal 11_

Thank you for using some time on me, I am very grateful.

MPelletier
  • 16,256
  • 15
  • 86
  • 137
Morten The Dane
  • 31
  • 1
  • 1
  • 4
  • `select()` returns the number of available *file descriptors*; `read()` returns the number of *bytes* consumed. – chrisaycock Apr 12 '11 at 15:22
  • Also, why are you only reading one byte at a time? Note that `EAGAIN` generally indicates you've attempted to read from a non-blocking socket, so something else is screwed-up there. – chrisaycock Apr 12 '11 at 15:30
  • 1
    You mean *errno code* `EAGAIN`, not *signal* 11 (`SIGSEGV`), right? Those are two completely unrelated things and would indicate completely different problems. (Aside: **never** refer to errno codes by their numeric value, only their `strerror` text or their `errno.h` name. The numbers are not consistent across platforms or even across CPUs with the same kernel (unlike the smaller signal numbers)). – zwol Apr 12 '11 at 17:09
  • Zack: I guess both. read returns 11 and according man 2 read that's the again. but signal 11 is in this case also raised. – Morten The Dane Apr 12 '11 at 18:13
  • Chrisaycock: like in case that two threads at same time is reading the same port? – Morten The Dane Apr 12 '11 at 18:14
  • Okay, as some already wrote my question was not relevant to my problem. I lost the train. – Morten The Dane Apr 14 '11 at 20:02
  • You seem to be somewhat confused -- signal 11 is `SIGSEGV`. `EAGAIN` ins't a signal at all, its an errno code, and while it happens to also be 11, it has nothing to do with signals. – Chris Dodd Apr 21 '11 at 23:18

1 Answers1

3

Do you have 30 threads all blocked on select() that all race to read fOut when it becomes readable---then the losers give you EAGAIN when the buffer is drained?

John Kelly
  • 31
  • 2