I/O Multiplexing & Scalable Socket Servers
by Ian Barile


Example 1:
(a)
#ifdef	__cplusplus
}
#endif

(b)
#endif /* defined(_KERNEL) || defined(_KMEMUSER) */



Listing One
// Get Handle to the /dev/poll device
if ((fd = open("/dev/poll", O_RDWR)) < 0) {
        return EPERM;
}
//create a pollfd structure large enough to hold all file 
//                                   descriptors that will be watched
pollfd = (struct pollfd* )malloc(sizeof(struct pollfd) * MAXBUF);
if (pollfd == NULL) {
        close(fd);
        return ENOMEM;
}
// Setup dev poll to watch for I/O events from file descriptors
for (i = 0; i < nFileDescriptorCount; i++) {
        pollfd[i].fd = fds[i];
        pollfd[i].events = POLLIN;
        pollfd[i].revents = 0;
} 
if (write(fd, &pollfd[0], sizeof(struct pollfd) * MAXBUF) !=
                sizeof(struct pollfd) * MAXBUF) {
        perror("failed to write register file descriptor with /dev/poll");
        close (fd);
        free(pollfd);
        return EBADF;
}
// Get I/O and events from the 
dopoll.dp_timeout = -1;
dopoll.dp_nfds = MAXBUF;
dopoll.dp_fds = pollfd;
nDescriptorsSignalled = ioctl(wfd, DP_POLL, &dopoll);
if (nDescriptorsSignalled < 0) {
        perror("/dev/poll ioctl DP_POLL failed");
        close (fd);
        free(pollfd);
        return EINVAL;
}
while( nDescriptorsSignalled-- ) {
        read(dopoll.dp_fds[i].fd, rbuf, STRLEN);
}


Listing Two
//create initial I/O completion port with the number of worker threads
hCompletionPort = CreateIoCompletionPort(INVALID_FILE_HANDLE, 
                                                 NULL, 0, nWorkerThreads);
if( hCompletionPort == NULL){
    return GetLastError();
}
//Add a file handle for the I/O completion to watch
hCompletionPort1 = CreateIoCompletionPort( hFile, hCompletionPort, 
                                            dwCompletionKey, nWorkerThreads);
if( hCompletionPort1 == NULL ){
    return GetLastError();
}
//perform Non-Blocking read so GetQueuedCompletionStatus can notify 
//                                             us when the read has completed.
nRet = WSARecv(hFile, lpBuffers, dwBuffCount, &dwBytesReceived, 
                                               &dwFlags, &OverLapped, NULL);
if( nRet != 0 ){
   return WSAGetLastError();
}
//block on GetQueuedCompletionStatus until the I/O operation completes.  
// The I/O will be in the buffer specified supplied in WSARecv
nRet = GetQueuedCompletionStatus(hCompletionPort, &dwBytesReceived, 
                                   &dwCompletionKey, &OverLapped, TIME_OUT);
if( nRet == 0 && GetLastError() != WAIT_TIMEOUT){
    return GetLastError();
}








2


