views:

139

answers:

3

Hi all,

I have to monitor a serial port and process its data. As a test program I was using select for just one port. The run function is as follows:

void <ProtocolClass>::run()
{
    int fd = mPort->GetFileDescriptor();
    fd_set readfs;
    int maxfd=1;
    int res;
    FD_ZERO(&readfs);
   FD_SET(fd,&readfs); 
    struct timeval Timeout;
    Timeout.tv_usec=0;
    Timeout.tv_sec=3;


   //BYTE  ack_message_frame[ACKNOWLEDGE_FRAME_SIZE];
   while(true)
   {
     usleep(10);
     res=select(maxfd,&readfs,NULL,NULL,NULL);
     if(res<0)
        perror("\nselect failed");
     else if( res==0)
       puts("TIMEOUT");
     else if(FD_ISSET(fd,&readfs))
     {//IF INPUT RECEIVED
      qDebug("************RECEIVED DATA****************");
        FlushBuf();
        qDebug("\nReading data into a read buffer");
        int bytes_read=mPort->ReadPort(mBuf,1000);
        mFrameReceived=false;
        for(int i=0;i<bytes_read;i++)
        {
            qDebug("%x",mBuf[i]);
        }



        //if complete frame has been received, write the acknowledge message frame to the port.
        if(bytes_read>0)
        {
         qDebug("\nAbout to Process Received bytes");
            ProcessReceivedBytes(mBuf,bytes_read);
            qDebug("\n Processed Received bytes");
            if(mFrameReceived)
     {
        int no_bytes=mPort->WritePort(mAcknowledgeMessage,ACKNOWLEDGE_FRAME_SIZE);
            }//if frame received
        }//if bytes read > 0
        } //if input received
    }//end while
}

But the problem is it doesn't seemed to work as nothing happens. Can somebody suggest the correct way to do it. I want to use select per thread. Is this feasible. Can you give me a sample code to do it. I have searched the net but the examples are very basic involving just the main function. There are no C++ specific examples. I am using Qt threads by the way.

Thanks

+2  A: 

First thing I noticed: maxfds must be fd + 1. Would this help?

stefaanv
tried that man, it didn't work
rocknroll
it worked coupled with the suggestion given below. Thanks stefaanv
rocknroll
+4  A: 

i think i know what's the problem.

FD_ZERO(&readfs);
FD_SET(fd,&readfs);

The above lines should be inside the while loop. Because, select call will reset the 'fd' bit position in the readFs structure. So, the next time when select is called, it does know what while file descriptors to poll, as all are reset here.

The correction suggested by stefaanv should also be included

Warrior
thanks man, it worked. But why is this so??????????
rocknroll
Is select call is blocking in-definitely ? i dont think so, it that's the case the code should have worked with the solution form stefaanv for one read atleast can you test it ?The reason for havig FD_SET in the while loop is; select call will manipulate the readFs structure and can reset the bit position corresponding to fd if there is no data available, so the next time select is called the bit position corresponding to fd will be off. i.e means the select will not poll your fd.
Warrior
+1  A: 

I agree with stefaanv, you should pass in the file descriptor +1 to select(). Because of this, it isn't even monitoring your file descriptor for data. Also, I noticed that you never passed in your timeout value to select(), so it is just blocking indefinitely until something is available.

Joe M