/* Copyright (C) 2001 Marc Casaldaliga Albisu ================================================================ This code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Emacs (which is required to make this stuff work); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ================================================================== */ //g++ -c IONotifier.C `sigc-config --cflags` #include "IONotifier.hxx" //for printf #include //for select #include #include #include //for signals #include using namespace SigC; //for threads #include IONotifier::IONotifier(int fd_) :fd(fd_),againWritableEmited(false),fdIsValid(true) { pthread_mutex_init(&mutex,NULL); pthread_create(&thread,NULL,&IONotifier::watchFor,this); } IONotifier::~IONotifier() { pthread_mutex_lock(&mutex); fdIsValid=false; pthread_mutex_unlock(&mutex); pthread_join(thread,NULL); } void * IONotifier::watchFor( void* arg) { IONotifier* self=(IONotifier *) arg; fd_set rfds, wfds; int retval; //first time: self->againWritableEmited=false; //include the actual fd in the sets checked for reading and writing while(1){ pthread_mutex_lock(&(self->mutex)); if(!self->fdIsValid) break; pthread_mutex_unlock(&(self->mutex)); if(!self->againWritableEmited){ //againWritable has not been emited, so we check both if its readable and writable FD_ZERO(&rfds);FD_ZERO(&wfds); FD_SET(self->fd, &rfds);FD_SET(self->fd, &wfds); retval = select(FD_SETSIZE, &rfds, &wfds, NULL, NULL); }else{ //if againWritable has been emited we don't want to emit if it's writable until something changes. Until then, only check if it's readable FD_ZERO(&rfds);FD_ZERO(&wfds); FD_SET(self->fd, &rfds); retval = select(FD_SETSIZE, &rfds, NULL, NULL, NULL); } if (retval){ // printf("Data is available now.\n"); if(FD_ISSET(self->fd, &rfds)){ //fd is readable self->readable.emit(); //since this new situation: self->againWritableEmited=false; } if(FD_ISSET(self->fd, &wfds)){ //fd is writable self->againWritable.emit(); self->againWritableEmited=true; } }else{ perror("Shouldn't arrive here"); } } // pthread_exit }