[sr-dev] git:sr_3.0: io_wait: don't update FD watched status on error

Andrei Pelinescu-Onciul andrei at iptel.org
Thu Aug 19 16:10:03 CEST 2010


Module: sip-router
Branch: sr_3.0
Commit: 311b29d5e73720050f2bc56c36432b2eb45bbe83
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=311b29d5e73720050f2bc56c36432b2eb45bbe83

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Fri Jun 18 09:48:21 2010 +0200

io_wait: don't update FD watched status on error

If the syscall to change the events or delete a watched FD fails,
don't update/delete the FD status in fd_hash.
For /dev/poll if a change fails when re-adding the FD, delete it
from the hash (in the /dev/poll case to change the events a FD is
watched for one has to remove it and re-add it with the new
events).
The syscalls should never fail in an un-handled way, but in the
unlikely event that it happens this change will make the code more
robust.

(cherry picked from commit 2d8cd170ab867ab15296b30f0b784abe1adc1bca)

---

 io_wait.h |   15 +++++++++------
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/io_wait.h b/io_wait.h
index 93f1426..01df1e6 100644
--- a/io_wait.h
+++ b/io_wait.h
@@ -627,7 +627,6 @@ inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags)
 		goto error;
 	}
 	events=e->events;
-	unhash_fd_map(e);
 	
 	switch(h->poll_method){
 		case POLL_POLL:
@@ -647,7 +646,6 @@ inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags)
 #endif
 #ifdef HAVE_SIGIO_RT
 		case POLL_SIGIO_RT:
-			fix_fd_array;
 			/* the O_ASYNC flag must be reset all the time, the fd
 			 *  can be changed only if  O_ASYNC is reset (if not and
 			 *  the fd is a duplicate, you will get signals from the dup. fd
@@ -667,6 +665,7 @@ inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags)
 								" failed: %s [%d]\n", strerror(errno), errno); 
 					goto error; 
 				} 
+			fix_fd_array; /* only on success */
 			break;
 #endif
 #ifdef HAVE_EPOLL
@@ -737,6 +736,7 @@ again_devpoll:
 					h->poll_method);
 			goto error;
 	}
+	unhash_fd_map(e); /* only on success */
 	h->fd_no--;
 	return 0;
 error:
@@ -808,14 +808,14 @@ inline static int io_watch_chg(io_wait_h* h, int fd, short events, int idx )
 	
 	add_events=events & ~e->events;
 	del_events=e->events & ~events;
-	e->events=events;
 	switch(h->poll_method){
 		case POLL_POLL:
+			fd_array_chg(events
 #ifdef POLLRDHUP
-			/* listen to POLLRDHUP by default (if POLLIN) */
-			events|=((int)!(events & POLLIN) - 1) & POLLRDHUP;
+							/* listen to POLLRDHUP by default (if POLLIN) */
+							| (((int)!(events & POLLIN) - 1) & POLLRDHUP)
 #endif /* POLLRDHUP */
-			fd_array_chg(events);
+						);
 			break;
 #ifdef HAVE_SELECT
 		case POLL_SELECT:
@@ -921,6 +921,8 @@ again_devpoll2:
 					LOG(L_ERR, "ERROR: io_watch_chg: re-adding fd to "
 								"/dev/poll failed: %s [%d]\n", 
 								strerror(errno), errno);
+					/* error re-adding the fd => mark it as removed/unhash */
+					unhash_fd_map(e);
 					goto error;
 				}
 				break;
@@ -931,6 +933,7 @@ again_devpoll2:
 					h->poll_method);
 			goto error;
 	}
+	e->events=events; /* only on success */
 	return 0;
 error:
 	return -1;




More information about the sr-dev mailing list