I/O Multiplexing: I/O Multiplexing: select and poll select and poll function function
I/O Multiplexing:I/O Multiplexing:select and poll functionselect and poll function
abstractabstract
IntroductionIntroduction I/O ModelsI/O Models Synchronous I/O versus Asynchronous I/OSynchronous I/O versus Asynchronous I/O select functionselect function shutdown functionshutdown function pselect functionpselect function poll functionpoll function
IntroductionIntroduction TCP client is handling two inputs : standard TCP client is handling two inputs : standard
input and a TCP socketinput and a TCP socket– when the client was blocked in a call to read, the when the client was blocked in a call to read, the
server process was killedserver process was killed– server TCP sends FIN to the client TCP, but the server TCP sends FIN to the client TCP, but the
client never see FIN since the client is blocked client never see FIN since the client is blocked reading from standard inputreading from standard input
=> the capability to tell the kernel that we want to be => the capability to tell the kernel that we want to be notified if one or more I/O conditions are ready.notified if one or more I/O conditions are ready.
: I/O multiplexing (select and poll): I/O multiplexing (select and poll)
When: When: – client is handling multiple descriptors (interactive client is handling multiple descriptors (interactive
input and a network socket).input and a network socket).– Client to handle multiple sockets(rare)Client to handle multiple sockets(rare)– TCP server handles both a listening socket and its TCP server handles both a listening socket and its
connected socket.connected socket.– Server handle both TCP and UDP.Server handle both TCP and UDP.– Server handles multiple services and multiple Server handles multiple services and multiple
protocolsprotocols
I/O ModelsI/O Models Blocking I/OBlocking I/O Nonblocking I/ONonblocking I/O I/O multiplexing(select and poll)I/O multiplexing(select and poll) signal driven I/O(SIGIO)signal driven I/O(SIGIO) asynchronous I/O(posix.1 aio_ functions)asynchronous I/O(posix.1 aio_ functions)
Two distinct phases for an input operationsTwo distinct phases for an input operations
1. Waiting for the data to be ready1. Waiting for the data to be ready
2. Copying the data from the kernel to the process2. Copying the data from the kernel to the process
Blocking I/OBlocking I/O
application
recvfrom
Processdatagram
System call
Return OK
No datagram ready
Datagram readycopy datagram
Copy complete
kernel
Process blocks in a call to recvfrom
Wait for data
Copy datafrom kernel to user
nonblocking I/Ononblocking I/Oapplication
recvfrom
Processdatagram
System call
Return OK
No datagram ready
copy datagram
application
kernel
Wait for data
EWOULDBLOCK
recvfrom No datagram readyEWOULDBLOCK
System call
recvfrom datagram readySystem call
Copy datafrom kernel to user
Process repeatedlycall recvfromwating for an OK return(polling)
I/O multiplexing(select and poll)I/O multiplexing(select and poll)
application
select
Processdatagram
System call
Return OK
No datagram ready
Datagram readycopy datagram
Copy complete
kernel
Wait for data
Return readable
recvfrom
Copy datafrom kernel to user
Process blockin a call toselect waitingfor one ofpossibly manysockets tobecome readable
Process blockswhile data copiedinto applicationbuffer
System call
We first enable the socket for signal-driven I/O and install a signal handler We first enable the socket for signal-driven I/O and install a signal handler using the sigaction system call. using the sigaction system call.
The return from this system call is immediate and our process continues; it is The return from this system call is immediate and our process continues; it is not blocked. not blocked.
When the datagram is ready to be read, the SIGIO signal is generated for our When the datagram is ready to be read, the SIGIO signal is generated for our process. We can either read the datagram from the signal handler by calling process. We can either read the datagram from the signal handler by calling recvfrom and then notify the main loop that the data is ready to be processed recvfrom and then notify the main loop that the data is ready to be processed
or we can notify the main loop and let it read the datagram.or we can notify the main loop and let it read the datagram.
Advantage: Advantage: we are not blocked while waiting for the datagram to arrive. we are not blocked while waiting for the datagram to arrive. The main loop can continue executing and just wait to be notified by the The main loop can continue executing and just wait to be notified by the
signal handler that either the data is ready to process or the datagram is ready signal handler that either the data is ready to process or the datagram is ready to be read.to be read.
signal driven I/O(SIGIO)signal driven I/O(SIGIO)
application
Establish SIGIO
Processdatagram
System call
Return OK
Datagram readycopy datagram
Copy complete
kernel
Wait for data
Deliver SIGIO
recvfrom Copy datafrom kernel to user
Process continues executing
Process blockswhile data copiedinto applicationbuffer
Sigaction system call
Return Signal handler
Signal handler
asynchronous I/Oasynchronous I/O We call aio_read and pass the kernel the descriptor, buffer pointer, buffer size ,file We call aio_read and pass the kernel the descriptor, buffer pointer, buffer size ,file
offset, and how to notify us when the entire operation is complete. offset, and how to notify us when the entire operation is complete.
This system call returns immediately and our process is not blocked while waiting This system call returns immediately and our process is not blocked while waiting for the I/O to complete. for the I/O to complete.
We assume in this example that we ask the kernel to generate some signal when We assume in this example that we ask the kernel to generate some signal when the operation is complete. the operation is complete.
This signal is not generated until the data has been copied into our application This signal is not generated until the data has been copied into our application buffer, which is different from the signal-driven I/O model.buffer, which is different from the signal-driven I/O model.
Signal-driven I/O , the kernel tells us when an I/O operation can be Signal-driven I/O , the kernel tells us when an I/O operation can be initiatedinitiated, but , but with asynchronous I/O, the kernel tells us when an I/O operation is with asynchronous I/O, the kernel tells us when an I/O operation is completecomplete. .
asynchronous I/Oasynchronous I/O
application
aio_read
Signal handlerProcessdatagram
System call
Deliver signal
No datagram ready
Datagram readycopy datagram
Copy complete
kernel
Process continues
executing
Wait for data
Copy datafrom kernel to user
Return
Specified in aio_read
Comparison of the I/O ModelsComparison of the I/O Models
blocking nonblocking I/O multiplexing
signal-drivenI/O
asynchronous I/O
initiate
complete
check check check check check check
complete
blocked
check
blocked
readyinitiate blocked
complete
notificationinitiate blocked
complete
initiate
notification
wait fordata
copy datafrom kernelto user
1st phase handled differently,2nd phase handled the same
handles both phases
Synchronous I/O , Asynchronous I/OSynchronous I/O , Asynchronous I/O
Synchronous I/O : cause the requesting process to be blocked until Synchronous I/O : cause the requesting process to be blocked until that I/O operation (recvfrom) completes.that I/O operation (recvfrom) completes.
(blocking, nonblocking, I/O multiplexing, signal-driven I/O)(blocking, nonblocking, I/O multiplexing, signal-driven I/O)
Asynchronous I/O : does not cause the requesting process to be Asynchronous I/O : does not cause the requesting process to be blockedblocked
(asynchronous I/O) (asynchronous I/O)
Select functionSelect function
Allows the process to instruct the kernel to wait for any one of Allows the process to instruct the kernel to wait for any one of multiple events to occur and to wake up the process only when multiple events to occur and to wake up the process only when one or more of these events occurs or when a specified amount one or more of these events occurs or when a specified amount of time has passed.of time has passed.
(readable ,writable , expired time)(readable ,writable , expired time)
#include <sys/select.h>#include <sys/select.h>
#include <sys/time.h>#include <sys/time.h>
int select (int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, int select (int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *);const struct timeval *);
Returns: positive count of ready descriptors, 0 on timeout, –1 on errorReturns: positive count of ready descriptors, 0 on timeout, –1 on error
struct timevalstruct timeval
{{
long tv_sec; /* seconds */long tv_sec; /* seconds */
long tv_usec; /* microseconds */long tv_usec; /* microseconds */
}}
Condition of select functionCondition of select function Wait forever : return only descriptor is Wait forever : return only descriptor is
ready(timeval = NULL)ready(timeval = NULL) wait up to a fixed amount of time:wait up to a fixed amount of time: Do not wait at all : return immediately after Do not wait at all : return immediately after
checking the descriptors(timeval = 0)checking the descriptors(timeval = 0)
wait: normally interrupt if the process catches a wait: normally interrupt if the process catches a signal and returns from the signal handlersignal and returns from the signal handler
Readset => descriptor for checking readableReadset => descriptor for checking readable writeset => descriptor for checking writablewriteset => descriptor for checking writable exceptset => descriptor for checking exceptset => descriptor for checking
two exception conditionstwo exception conditions
:arrival of out of band data for a socket:arrival of out of band data for a socket
:the presence of control status information to be :the presence of control status information to be read from the master side of a pseudo terminalread from the master side of a pseudo terminal
Descriptor setsDescriptor sets Array of integers : each bit in each integer Array of integers : each bit in each integer
correspond to a descriptor.correspond to a descriptor.
fd_set: an array of integers, with each bit in each integer corresponding to a fd_set: an array of integers, with each bit in each integer corresponding to a descriptor. descriptor.
Void FD_ZERO(fd_set *fdset); /* clear all bits in fdset */Void FD_ZERO(fd_set *fdset); /* clear all bits in fdset */ Void FD_SET(int fd, fd_set *fdset); /* turn on the bit for fd in fdset */Void FD_SET(int fd, fd_set *fdset); /* turn on the bit for fd in fdset */ Void FD_CLR(int fd, fd_set *fdset); /* turn off the bit for fd in fdset*/Void FD_CLR(int fd, fd_set *fdset); /* turn off the bit for fd in fdset*/ int FD_ISSET(int fd, fd_set *fdset);/* is the bit for fd on in fdset ? */int FD_ISSET(int fd, fd_set *fdset);/* is the bit for fd on in fdset ? */
Example of Descriptor sets Example of Descriptor sets functionfunction
fd_set rset;fd_set rset;
FD_ZERO(&rset);/*all bits off : initiate*/FD_ZERO(&rset);/*all bits off : initiate*/
FD_SET(1, &rset);/*turn on bit fd 1*/FD_SET(1, &rset);/*turn on bit fd 1*/
FD_SET(4, &rset); /*turn on bit fd 4*/FD_SET(4, &rset); /*turn on bit fd 4*/
FD_SFD_SET(5, &rset); /*turn on bit fd 5*/T(5, &rset); /*turn on bit fd 5*/
specifies the number of descriptors to be specifies the number of descriptors to be tested.tested.
Its value is the maximum descriptor to be Its value is the maximum descriptor to be tested, plus one.(hence our name of tested, plus one.(hence our name of maxfdp1)(example:fd1,2,5 => maxfdp1: 6)maxfdp1)(example:fd1,2,5 => maxfdp1: 6)
constant FD_SETSIZE defined by constant FD_SETSIZE defined by including <sys/select.h>, is the number of including <sys/select.h>, is the number of descriptors in the fd_set datatype.(1024)descriptors in the fd_set datatype.(1024)
Maxfdp1 argument
socket is ready for reading : any one conditions is truesocket is ready for reading : any one conditions is true
– The number of bytes of data in the socket receive buffer is greater than or equal The number of bytes of data in the socket receive buffer is greater than or equal to the current size of the low-water mark for the socket receive buffer. A read to the current size of the low-water mark for the socket receive buffer. A read operation on the socket will not block and will return a value greater than 0. operation on the socket will not block and will return a value greater than 0.
Set low-water mark : SO_RCVLOWAT socket option (defaults 1 :TCP and UDP)Set low-water mark : SO_RCVLOWAT socket option (defaults 1 :TCP and UDP)
– The read half of the connection is closed. The read half of the connection is closed.
– The socket is a listening socket and the number of completed connections is The socket is a listening socket and the number of completed connections is nonzero. nonzero.
– A socket error is pending. A read operation on the socket will not block and will A socket error is pending. A read operation on the socket will not block and will return an error (–1) with errno set to the specific error condition. return an error (–1) with errno set to the specific error condition.
These These pending errorspending errors can also be fetched and cleared by calling getsockopt and specifying the can also be fetched and cleared by calling getsockopt and specifying the SO_ERROR socket option.SO_ERROR socket option.
socket is ready for writing : any one conditions is truesocket is ready for writing : any one conditions is true
– The number of bytes of available space in the socket send buffer is greater than or The number of bytes of available space in the socket send buffer is greater than or equal to the current size of the low-water mark for the socket send buffer equal to the current size of the low-water mark for the socket send buffer andand either: either:
(i) the socket is connected(i) the socket is connected
(ii) the socket does not require a connection(ii) the socket does not require a connection This means that if we set the socket to nonblocking, a write operation will not block and will return This means that if we set the socket to nonblocking, a write operation will not block and will return
a positive value. We can set this low-water mark using the SO_SNDLOWAT socket option. low-a positive value. We can set this low-water mark using the SO_SNDLOWAT socket option. low-water mark defaults to 2048 for TCP and UDP.water mark defaults to 2048 for TCP and UDP.
– The write half of the connection is closed. The write half of the connection is closed.
– A socket using a non-blocking connect has completed the connection.A socket using a non-blocking connect has completed the connection.
– A socket error is pending. A write operation on the socket will not block and will A socket error is pending. A write operation on the socket will not block and will return an error (–1) with errno set to the specific error condition. return an error (–1) with errno set to the specific error condition.
These These pending errorspending errors can also be fetched and cleared by calling getsockopt with the SO_ERROR can also be fetched and cleared by calling getsockopt with the SO_ERROR socket option.socket option.
A socket has an exception condition pending if there is out-of-band data for A socket has an exception condition pending if there is out-of-band data for the socket or the socket is still at the out-of-band mark.the socket or the socket is still at the out-of-band mark.
The purpose of the receive and send low-water marks is to give the application The purpose of the receive and send low-water marks is to give the application control over control over
how much data must be available for reading how much data must be available for reading how much space must be available for writing how much space must be available for writing For example, if we know that our application has nothing productive to do For example, if we know that our application has nothing productive to do
unless at least 64 bytes of data are present, we can set the receive low-water unless at least 64 bytes of data are present, we can set the receive low-water mark to 64 to prevent select from waking us up if less than 64 bytes are ready mark to 64 to prevent select from waking us up if less than 64 bytes are ready for reading.for reading.
Condition that cause a socket to Condition that cause a socket to be ready for be ready for selectselect
Condition Readable? writable? Exception?
Data to readread-half of the connection closednew connection ready for listening socket
Space available for writingwrite-half of the connection closed
•••
••
• •
•
Pending error
TCP out-of-band data
could be blocked in the call to fgets when could be blocked in the call to fgets when something happened on the socketsomething happened on the socket
blocks in a call to select instead, waiting for blocks in a call to select instead, waiting for either standard input or the socket to be either standard input or the socket to be readable.readable.
Condition handled by select in str_cliCondition handled by select in str_cli
Condition handled by select in str_cliCondition handled by select in str_cli
Data of EOF
client
• stdinSocket•
error EOF
RST
TCP
data FIN
Select for readability on either standard input or socket
Three conditions are handled with the socketThree conditions are handled with the socket
Peer TCP send a data, the socket become readable and Peer TCP send a data, the socket become readable and readread returns greater returns greater than 0than 0
Peer TCP send a FIN(peer process terminates), the socket become readable Peer TCP send a FIN(peer process terminates), the socket become readable and and readread returns 0(end-of-file) returns 0(end-of-file)
Peer TCP send a RST(peer host has crashed and rebooted), the socket Peer TCP send a RST(peer host has crashed and rebooted), the socket become readable and returns -1 and become readable and returns -1 and errnoerrno contains the specific error code contains the specific error code
Implimentation of str_cli function using Implimentation of str_cli function using selectselect
Void str_cli(FILE *fp, int sockfd){
int maxfdp1;fd_set rset;char sendline[MAXLINE], recvline[MAXLINE];
FD_ZERO(&rset);for ( ; ; ) {
FD_SET(fileno(fp), &rset);FD_SET(sockfd, &rset);maxfdp1 = max(fileno(fp), sockfd) + 1;Select(maxfdp1, &rset, NULL, NULL, NULL);
Continue…..
if (FD_ISSET(sockfd, &rset)) { /* socket is readable */if (Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("str_cli: server terminated prematurely");
Fputs(recvline, stdout);}
if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */if (Fgets(sendline, MAXLINE, fp) == NULL)
return; /* all done */Writen(sockfd, sendline, strlen(sendline));
}}//for
}//str_cli
Stop and waitStop and waitsends a line to the server sends a line to the server and then waits for the replyand then waits for the reply
request
request
serverrequest
request
serverreply
reply
reply
reply
client
time1
time2
time3
time4
time5
time6
time7
time0
Batch inputBatch input
request8 request7 request6 request5
reply1 reply2 reply3 reply4
Time 7:
request9 request8 request7 request6
reply2 reply3 reply4 reply5
Time 7:
The problem with our revised str_cli functionThe problem with our revised str_cli function– After the handling of an end-of-file on input, the send After the handling of an end-of-file on input, the send
function returns to the main function, that is, the program is function returns to the main function, that is, the program is terminated.terminated.
– However, in batch mode, there are still other requests and However, in batch mode, there are still other requests and replies in the pipe.replies in the pipe.
A way to close one-half of the TCP connectionA way to close one-half of the TCP connection– send a FIN to the server, telling it we have finished sending send a FIN to the server, telling it we have finished sending
data, but leave the socket descriptor open for reading <= data, but leave the socket descriptor open for reading <= shutdown functionshutdown function
Shutdown functionShutdown function Close one half of the TCP connectionClose one half of the TCP connection
(example:send FIN to server, but leave the (example:send FIN to server, but leave the socket descriptor open for reading)socket descriptor open for reading)
Close function : decrements the descriptor’s reference count and closes the socket only if the count reaches 0, terminate both direction(reading and writing)
Shutdown function : just one of them(reading or writing)
Calling shutdown to close half of a TCP connection
client serverdata
data
FIN
Ack of data and FIN
data
dataFIN
Ack of data and FIN
Read returns > 0
Read returns > 0
Read returns 0
writewriteclose
write
writeshutdown
Read returns > 0
Read returns > 0
Read returns 0
#include<sys/socket.h>#include<sys/socket.h>
int shutdown(int sockfd, int howto);int shutdown(int sockfd, int howto);
/* return : 0 if OK, -1 on error *//* return : 0 if OK, -1 on error */
howto argumenthowto argument SHUT_RD : read-half of the connection closedSHUT_RD : read-half of the connection closed
SHUT_WR : write-half of the connection closedSHUT_WR : write-half of the connection closed
SHUT_RDWR : both closedSHUT_RDWR : both closed
Str_cli function using Str_cli function using select select and and shutdownshutdown
#include "unp.h"void str_cli(FILE *fp, int sockfd){
int maxfdp1, stdineof;fd_set rset;char sendline[MAXLINE], recvline[MAXLINE];
stdineof = 0;FD_ZERO(&rset);for ( ; ; ) {
if (stdineof == 0) // select on standard input for readabilityFD_SET(fileno(fp), &rset);
FD_SET(sockfd, &rset);maxfdp1 = max(fileno(fp), sockfd) + 1;Select(maxfdp1, &rset, NULL, NULL, NULL);
Continue…..
if (FD_ISSET(sockfd, &rset)) { /* socket is readable */if (Readline(sockfd, recvline, MAXLINE) == 0) {
if (stdineof == 1)return; /* normal termination */
elseerr_quit("str_cli: server terminated prematurely");
}Fputs(recvline, stdout);
}if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */
if (Fgets(sendline, MAXLINE, fp) == NULL) {
stdineof = 1;Shutdown(sockfd, SHUT_WR); /* send FIN */FD_CLR(fileno(fp), &rset);continue;
}Writen(sockfd, sendline, strlen(sendline));
}}
}
TCP echo serverTCP echo server Rewrite the server as a single process that uses Rewrite the server as a single process that uses
select to handle any number of clients, instead select to handle any number of clients, instead of forking one child per client.of forking one child per client.
Data structure TCP server(1)Data structure TCP server(1)
Client[][0]
[1]
[2]
-1
-1
-1
-1[FD_SETSIZE -1]
rset:
fd0 fd1 fd2 fd3
0 0 0 1
Maxfd + 1 = 4
fd:0(stdin),1(stdout),2(stderr)fd:3 => listening socket fd
Before first client has established a connection
Data structure TCP server(2)Data structure TCP server(2)
Client[][0]
[1]
[2]
4
-1
-1
-1[FD_SETSIZE -1]
rset:
fd0 fd1 fd2 fd3
0 0 0 1
Maxfd + 1 = 5
* fd3 => listening socket fd
fd4
1
*fd4 => client socket fd
After first client connection is established
Client[][0]
[1]
[2]
4
5
-1
-1[FD_SETSIZE -1]
rset:
fd0 fd1 fd2 fd3
0 0 0 1
Maxfd + 1 = 6
* fd3 => listening socket fd
fd4
1
* fd4 => client1 socket fd
fd5
1
* fd5 => client2 socket fd
Data structure TCP server(3)Data structure TCP server(3)
After second client connection is established
Data structure TCP server(4)Data structure TCP server(4)
Client[][0]
[1]
[2]
-1
5
-1
-1[FD_SETSIZE -1]
rset:
fd0 fd1 fd2 fd3
0 0 0 1
Maxfd + 1 = 6
* fd3 => listening socket fd
fd4
0
* fd4 => client1 socket fd deleted
fd5
1
* fd5 => client2 socket fd
*Maxfd does not change
After first client terminates its connection
TCP echo server using single TCP echo server using single processprocess
#include"unp.h"int main(int argc, char **argv){
int i, maxi, maxfd, listenfd, connfd, sockfd;int nready, client[FD_SETSIZE];ssize_t n;fd_set rset, allset;char line[MAXLINE];socklen_t clilen;struct sockaddr_in cliaddr, servaddr;listenfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));Listen(listenfd, LISTENQ);
maxfd = listenfd; /* initialize */maxi = -1; /* index into client[] array */for (i = 0; i < FD_SETSIZE; i++)
client[i] = -1; /* -1 indicates available entry */FD_ZERO(&allset);FD_SET(listenfd, &allset);
for ( ; ; ) {rset = allset; /* structure assignment */nready = Select(maxfd+1, &rset, NULL, NULL, NULL);
if (FD_ISSET(listenfd, &rset)) { /* new client connection */clilen = sizeof(cliaddr);connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
for (i = 0; i < FD_SETSIZE; i++)if (client[i] < 0)
{client[i] = connfd; /* save descriptor */break;
}if (i == FD_SETSIZE)
err_quit("too many clients");
FD_SET(connfd, &allset); /* add new descriptor to set */if (connfd > maxfd)
maxfd = connfd; /* for select */if (i > maxi)
maxi = i; /* max index in client[] array */
if (--nready <= 0)continue; /* no more readable descriptors */
}
for (i = 0; i <= maxi; i++) { /* check all clients for data */
if ( (sockfd = client[i]) < 0)continue;
if (FD_ISSET(sockfd, &rset)) {if ( (n = Read(sockfd, line, MAXLINE)) == 0) {
/*4connection closed by client */Close(sockfd);FD_CLR(sockfd, &allset);client[i] = -1;
} elsewrite(sockfd, line, n);
if (--nready <= 0)break; /* no more readable descriptors */
}}
}}
Denial of service attacksDenial of service attacks
If Malicious client connect to the server, If Malicious client connect to the server, send 1 byte of data(other than a newline), send 1 byte of data(other than a newline), and then goes to sleep.and then goes to sleep.
=>call readline, server is blocked.=>call readline, server is blocked.
Solution Solution use nonblocking I/Ouse nonblocking I/O have each client serviced by a separate thread of have each client serviced by a separate thread of
control (spawn a process or a thread to service control (spawn a process or a thread to service each client)each client)
place a timeout on the I/O operationplace a timeout on the I/O operation
Poll functionPoll function Similar to select, but provide additional Similar to select, but provide additional
information when dealing with streams devicesinformation when dealing with streams devices #include <poll.h>#include <poll.h>
int poll(struct pollfd *fdarray, unsigned long int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);nfds, int timeout);
/*return : count of ready descriptors, 0 on timeout, /*return : count of ready descriptors, 0 on timeout, -1 on error*/-1 on error*/
Struct pollfd{Struct pollfd{
int fd; /* descriptor to check */int fd; /* descriptor to check */
short events; /* events of interest on fd */short events; /* events of interest on fd */
short revents;/*events that occurred on fd*/short revents;/*events that occurred on fd*/
}}
specifies the conditions to be tested for a given specifies the conditions to be tested for a given descriptor fddescriptor fd
events: the conditions to be testedevents: the conditions to be tested
revents:the status of that descriptorrevents:the status of that descriptor
Input Input eventsevents and returned and returned reventsrevents for for pollpoll
ConstantInput to events ?
Result from revents ?
Description
POLLINPOLLRDNORMPOLLRDBANDPOLLPRI
• • • •
• • • •
Normal or priority band data can be readnormal data can be readpriority band data can be readhigh-priority data can be read
POLLOUTPOLLWRNORMPOLLWRBAND
POLLERRPOLLHUPPOLLNVAL
• • •
• • •
normal data can be writtennormal data can be written priority band data can be written
• • •
An error has occurredhangup has occurreddescriptor is not an open file
Timeout value for Timeout value for pollpoll
Timeout value Description
INFTIM
0
>0
Wait forever
Return immediately, do not block
Wait specified number of milliseconds
If we are no longer interested in particular descriptor, just set the fd member of the pollfd structure
Specifies how long the function is to wait before returning