1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
9 #include <anna/comm/internal/Poll.hpp>
11 //-----------------------------------------------------------------------------------
12 // RECORDAR QUE ESTA CLASE SOLO SE USA EN LA VERSION SINGLE-THREAD DEL
14 //-----------------------------------------------------------------------------------
18 void comm::Poll::setTimeout(const Millisecond &timeout)
20 if((a_timeout.tv_sec = timeout / 1000) == 0)
21 a_timeout.tv_usec = timeout * 1000;
23 a_timeout.tv_usec = 0;
25 a_ptrTimeout = (a_timeout.tv_sec != 0 || a_timeout.tv_usec != 0) ? &a_timeout : NULL;
28 //--------------------------------------------------------------------------------------------
29 // Si a_ptrTimeout != NULL => se devuelve el tiempo que ha sobrado de la espera maxima
30 // establecida (en Solaris este puntero no se modifica para nada)
32 // Para las dos implementacion el NULL => espera hasta que llegue un mensaje.
33 //--------------------------------------------------------------------------------------------
34 void comm::Poll::waitMessage()
35 throw(RuntimeException) {
36 if(a_ptrTimeout == NULL)
37 a_pollr = select(a_maxfd, (fd_set*) anna_memcpy(&a_fdset, &a_fdmask, sizeof(fd_set)), NULL);
40 timeval timeout(a_timeout);
41 a_pollr = select(a_maxfd, (fd_set*) anna_memcpy(&a_fdset, &a_fdmask, sizeof(fd_set)), &timeout);
43 a_pollr = select(a_maxfd, (fd_set*) anna_memcpy(&a_fdset, &a_fdmask, sizeof(fd_set)), a_ptrTimeout);
48 //-----------------------------------------------------------------------------------------
49 // Se ha detectado una condicion de error. Se recibe trafico por fd = { 16, 19} y el
50 // tramiento de 16 => cierre de 19 mediante comm::Communicator::attach => el a_ifd no
51 // llegaba nunca a tratar al 19, porque el a_maxfd ha sido modificado con 16, pero el a_pollr
52 // sigue indicado que queda un fd por tratar. ver Poll::erase
54 // (1) Una vez que ha tratado detectado la activada desactiva el indicador
55 //-----------------------------------------------------------------------------------------
56 int comm::Poll::fetch()
61 if(FD_ISSET(a_ifd, &a_fdset)) {
62 FD_CLR(a_ifd, &a_fdset); // (1)
72 if(++ a_ifd > a_maxfd)
79 void comm::Poll::insert(const int fd)
81 FD_SET(fd, &a_fdmask);
83 if(a_maxfd < fd) a_maxfd = fd;
89 //---------------------------------------------------------------------------------------
90 // Hay que comprobar que el 'fd' que vamos a eliminar de la lista no este en la lista
91 // de pendientes de tratar.
92 //---------------------------------------------------------------------------------------
93 void comm::Poll::erase(const int fd)
95 FD_CLR(fd, &a_fdmask);
97 if(FD_ISSET(fd, &a_fdset) && a_pollr > 0) { // (1)
102 if(fd == a_maxfd || fd == a_minfd) {
103 const int max = a_maxfd;
107 for(int ifd = 0; ifd <= max; ifd ++) {
108 if(FD_ISSET(ifd, &a_fdmask)) {
109 if(a_maxfd < ifd) a_maxfd = ifd;
111 if(ifd < a_minfd) a_minfd = ifd;