[asterisk-commits] twilson: trunk r332337 - in /trunk: ./ res/res_timing_timerfd.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Aug 17 13:31:42 CDT 2011
Author: twilson
Date: Wed Aug 17 13:31:39 2011
New Revision: 332337
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=332337
Log:
Merged revisions 332321 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/10
................
r332321 | twilson | 2011-08-17 13:09:49 -0500 (Wed, 17 Aug 2011) | 17 lines
Merged revisions 332320 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8
........
r332320 | twilson | 2011-08-17 12:35:27 -0500 (Wed, 17 Aug 2011) | 10 lines
Don't read from a disarmed or invalid timerfd
Numerous isues have been reported for deadlocks that are caused by
a blocking read in res_timing_timerfd on a file descriptor that will
never be written to. This patch adds some checks to make sure that
the timerfd is both valid and armed before calling read().
Should fix: ASTERISK-1842, ASTERISK-18166, ASTERISK-18197, AST-486,
AST-495, AST-507 and possibly others.
........
................
Modified:
trunk/ (props changed)
trunk/res/res_timing_timerfd.c
Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-10-merged' - no diff available.
Modified: trunk/res/res_timing_timerfd.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_timing_timerfd.c?view=diff&rev=332337&r1=332336&r2=332337
==============================================================================
--- trunk/res/res_timing_timerfd.c (original)
+++ trunk/res/res_timing_timerfd.c Wed Aug 17 13:31:39 2011
@@ -162,8 +162,32 @@
{
uint64_t expirations;
int read_result = 0;
+ struct timerfd_timer *our_timer, find_helper = {
+ .handle = handle,
+ };
+
+ if (!(our_timer = ao2_find(timerfd_timers, &find_helper, OBJ_POINTER))) {
+ ast_log(LOG_ERROR, "Couldn't find a timer with handle %d\n", handle);
+ return;
+ }
+
+ ao2_lock(our_timer);
do {
+ struct itimerspec timer_status;
+
+ if (timerfd_gettime(handle, &timer_status)) {
+ ast_log(LOG_ERROR, "Call to timerfd_gettime() error: %s\n", strerror(errno));
+ expirations = 0;
+ break;
+ }
+
+ if (timer_status.it_value.tv_sec == 0 && timer_status.it_value.tv_nsec == 0) {
+ ast_debug(1, "Avoiding read on disarmed timerfd %d\n", handle);
+ expirations = 0;
+ break;
+ }
+
read_result = read(handle, &expirations, sizeof(expirations));
if (read_result == -1) {
if (errno == EINTR || errno == EAGAIN) {
@@ -175,6 +199,9 @@
}
} while (read_result != sizeof(expirations));
+ ao2_unlock(our_timer);
+ ao2_ref(our_timer, -1);
+
if (expirations != quantity) {
ast_debug(2, "Expected to acknowledge %u ticks but got %llu instead\n", quantity, (unsigned long long) expirations);
}
More information about the asterisk-commits
mailing list