Module: sip-router
Branch: sr_3.0
Commit: 311b29d5e73720050f2bc56c36432b2eb45bbe83
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=311b29d…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)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;