LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-08-2008, 04:38 AM   #1
LonelyStar
LQ Newbie
 
Registered: Sep 2007
Posts: 11

Rep: Reputation: 0
Determine the event type with select


Hello,

I am currently trying to integrate avahi into some software.
For that, I need to wait for events on sockets avahi gives me.
Avahi also tells me what events to wait for, these are
POLLIN
POLLOUT
POLLERR
POLLHUP

So exactly the events "poll" deals with.
For compatibility reasons I do not want to use poll but select.
So, I put all the POLLOUT event sockets in the "writefds" and all the others in the "readfds".
Select should return on connection closed or connection error for any socket in the "readfds", correct?

But how do I determine the event type? I do I distinguish between POLLIN, POLLERR and POLLHUP without reading from the socket?
I need this to react with the correct event.

Any Ideas?
Thanks!
Nathan
 
Old 08-08-2008, 05:48 AM   #2
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
I don't know anything about avahi, but does each different event come from a different socket descriptor? If so, you can use FD_ISSET(fd, *fdset) after select() returns to find out which descriptors changed status. And thus also determine which event occurred. FD_ISSET will not read or write to the descriptor. (also see "man select" and "man select_tut").

If there are no different socket descriptors for each event types, how do they do it with polling? AFAICS it should be possible to use the same method using select().
 
Old 08-08-2008, 07:49 AM   #3
LonelyStar
LQ Newbie
 
Registered: Sep 2007
Posts: 11

Original Poster
Rep: Reputation: 0
It is possible that for one socket descriptor, different events are requestet. So I can not determine the event type by the socket .
For poll, you give arrays with the socket descriptors and the request events in this structur:
Code:
 struct pollfd {
               int   fd;         /* file descriptor */
               short events;     /* requested events */
               short revents;    /* returned events */
           };
The events that occured is than returned in revents.
That is how they do it with polling...

Nathan
 
Old 08-08-2008, 03:35 PM   #4
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
This might sound ironic, but I think poll is the way to find out what you need to know. poll is as POSIX-conforming as select, so I don't see why compatibility is an issue. They're both from the same POSIX specification.
ta0kira

edit:
If the compatibility problem has to do with pollfd, remember that different implementations might use a different variable order, but you can fix that by explicit initialization using .fd =, etc.

Last edited by ta0kira; 08-08-2008 at 03:38 PM.
 
Old 08-10-2008, 04:33 PM   #5
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
I had a look at it again. And I think it should be possible to determine which of those 4 events have occurred when select() is used instead of poll(). But you you'll have to (try to) write to writable descriptors in order to find out which event occured (BTW you said you don't want to read from a descriptor to find out. Why not?)

If select() flags a read-only descriptor you can be sure that only (the equivalent) for POLLIN occurred since all the other 3 events are for writable descriptors only.

For writable you can find out which event occurred with the following psuedo-ish C-code (here I assumed POLLHUP is equivalent to a socket descriptor for which the other (reading) end closed the connection. I am not 100% sure of this):
Code:
result = write(fd, buf, nbytes);
if (result < 0) {
    if (errno == EPIPE) {
        /* POLLHUP-like condition */
    } else {
        /* POLLERR-like condition */
    }
} else {
    /* POLOUT-like condition */
}
But then I also -like ta0kira- have doubts about the compatibility issues you expect. In "man select_tut" I read:
Quote:
Originally Posted by man select_tut
"The poll(2) system call has the same functionality as select(), and is somewhat more efficient when monitoring sparse file descriptor sets. It is nowadays widely available, but historically was less portable than select()."
So then I think, how many OS's will be there that have historically incompatible poll() implementation but still compile/run avahi cleanly?

I would stick to poll() which seems to be much easier to use with avahi.

Last edited by Hko; 08-11-2008 at 03:02 AM. Reason: fixed few typos
 
Old 08-11-2008, 03:21 AM   #6
LonelyStar
LQ Newbie
 
Registered: Sep 2007
Posts: 11

Original Poster
Rep: Reputation: 0
Hi,

Thanks for the reply.
I do not write nor read from the sockets because these are the sockets avahi uses for its connections. And when I read or write to them I am corrupting avahi data, right?

OK, I really thought select would be more portable.
The other thing is, that I have to integrate avahi into a bunch of programs which use select. And switching to poll in all of them is just more work. But maybe I just have to .

Greetings,
Nathan
 
Old 08-11-2008, 06:32 AM   #7
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Quote:
Originally Posted by LonelyStar View Post
I do not write nor read from the sockets because these are the sockets avahi uses for its connections. And when I read or write to them I am corrupting avahi data, right?
Yes. that makes sense to me now.
I did not realize you were snooping on avahi's internal communication channels. I thought you were trying to code some kind of avahi client. As I said in my first post, I hardly know anything about avahi.

Good luck with your project.
 
Old 08-11-2008, 10:53 AM   #8
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
I'm pretty sure glibc will wrap select instead of poll on systems without a poll system call, also (with the poll library function, that is.)
ta0kira

Last edited by ta0kira; 08-11-2008 at 10:55 AM.
 
Old 09-08-2008, 12:32 AM   #9
vdx
Member
 
Registered: Aug 2007
Location: The Greate INDIA
Distribution: CentOS, RHEL, Fedora
Posts: 102

Rep: Reputation: 24
Talking

hi, LonelyStar

you can use the poll syscall also for ur avahi deamon (if there is no compatibility issues), and select is also fine.

Now as far the guessing of events is concerned I recommends tht when select returns file descriptor set then u can check for the descriptor bits using some kinda '&' operation, like i have the following function in which I am cheking for the POLLHUP and POLLIN events to be occured on set of file descriptors.

Code:
void v_read()
{
        int poll_ret=0,temp=0,len=0;
        struct pollfd array_fd[5];

        while(1)
        {
                poll_ret = poll(array_fd,5,1000);

                if(poll_ret > 0)
                {
                        for(temp = 0;temp < 5;temp++)
                        {
                                if(array_fd[temp].revents & POLLHUP)
                                {
                                        printf("Hangup received\n");
                                        array_fd[temp].fd =-1;
                                        poll_ret--;
                                        if(poll_ret <= 0)
                                                break;
                                }
                                if(array_fd[temp].revents & POLLIN)
                                {
                                        char buff[255];
                                        printf("Read the data\n");
                                        if( (len = recv( array_fd[temp].fd, buff,sizeof(buff),0)) > 0)
                                        {
                                                printf("Len Of Recv bytes %d \n",len);
                                        }
                                                   
                                        poll_ret--; 
                                        if(poll_ret <= 0)
                                                break;
                                }//if over
                        }//for 
                }//if
        }//while
}//end of function
I think u can use same logic for the select also.....
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Determine files type banajah Linux - Newbie 3 10-08-2007 06:00 PM
How to determine memory type? swagger Linux - Hardware 3 04-17-2006 08:15 PM
select on simple data type? Thinking Programming 1 08-20-2005 07:56 PM
How to determine partition type? halturata Linux - General 2 08-11-2005 02:07 PM
How to determine partition type? halturata Linux - General 3 08-11-2005 03:11 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:10 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration