Unix™ Systems Programming [Electronic resources] : Communication, Concurrency, and Threads نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Unix™ Systems Programming [Electronic resources] : Communication, Concurrency, and Threads - نسخه متنی

Prentice Hall

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










4.5 The poll Function


The poll function is similar to select, but it organizes the information by file descriptor rather than by type of condition. That is, the possible events for one file descriptor are stored in a struct pollfd. In contrast, select organizes information by the type of event and has separate descriptor masks for read, write and error conditions. The poll function is part of the POSIX:XSI Extension and has its origins in UNIX System V.

The poll function takes three parameters: fds, nfds and timeout. The fds is an array of struct pollfd, representing the monitoring information for the file descriptors. The nfds parameter gives the number of descriptors to be monitored. The timeout value is the time in milliseconds that the poll should wait without receiving an event before returning. If the timeout value is 1, poll never times out. If integers are 32 bits, the maximum timeout period is about 30 minutes.


SYNOPSIS
#include <poll.h>
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
POSIX:XSI

The poll function returns 0 if it times out. If successful, poll returns the number of descriptors that have events. If unsuccessful, poll returns 1 and sets errno. The following table lists the mandatory errors for poll.

errno

cause

EAGAIN

allocation of internal data structures failed, but a subsequent request may succeed

EINTR

a signal was caught during poll

EINVAL

nfds is greater than OPEN_MAX

The struct pollfd structure includes the following members.


int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */

The fd is the file descriptor number, and the events and revents are constructed by taking the logical OR of flags representing the various events listed in Program 4.14. The select call modifies the file descriptor sets that are passed to it, and the program must reset these descriptor sets each time it calls select. The poll function uses separate variables for input and return values, so it is not necessary to reset the list of monitored descriptors after each call to poll. The poll function has a number of advantages. The masks do not need to be reset after each call. Unlike select, the poll function treats errors as events that cause poll to return. The timeout parameter is easier to use, although its range is limited. Finally, poll does not need a max_fd argument.

Program 4.17 monitorpoll.c

A function to monitor an array of file descriptors by using poll.


#include <errno.h>
#include <poll.h>
#include <stdlib.h>
#include <stropts.h>
#include <unistd.h>
#include "restart.h"
#define BUFSIZE 1024
void docommand(char *, int);
void monitorpoll(int fd[], int numfds) {
char buf[BUFSIZE];
int bytesread;
int i;
int numnow = 0;
int numready;
struct pollfd *pollfd;
for (i=0; i< numfds; i++) /* initialize the polling structure */
if (fd[i] >= 0)
numnow++;
if ((pollfd = (void *)calloc(numfds, sizeof(struct pollfd))) == NULL)
return;
for (i = 0; i < numfds; i++) {
(pollfd + i)->fd = *(fd + i);
(pollfd + i)->events = POLLRDNORM;
}
while (numnow > 0) { /* Continue monitoring until descriptors done */
numready = poll(pollfd, numfds, -1);
if ((numready == -1) && (errno == EINTR))
continue; /* poll interrupted by a signal, try again */
else if (numready == -1) /* real poll error, can't continue */
break;
for (i = 0; i < numfds && numready > 0; i++) {
if ((pollfd + i)->revents) {
if ((pollfd + i)->revents & (POLLRDNORM | POLLIN) ) {
bytesread = r_read(fd[i], buf, BUFSIZE);
numready--;
if (bytesread > 0)
docommand(buf, bytesread);
else
bytesread = -1; /* end of file */
} else if ((pollfd + i)->revents & (POLLERR | POLLHUP))
bytesread = -1;
else /* descriptor not involved in this round */
bytesread = 0;
if (bytesread == -1) { /* error occurred, remove descriptor */
r_close(fd[i]);
(pollfd + i)->fd = -1;
numnow--;
}
}
}
}
for (i = 0; i < numfds; i++)
r_close(fd[i]);
free(pollfd);
}


    / 276