aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys/common
diff options
context:
space:
mode:
authorMikael Pettersson <[email protected]>2010-05-12 12:03:32 +0200
committerBjörn Gustavsson <[email protected]>2010-05-15 10:09:32 +0200
commit3e645422ef452ae8c1051c4fdffa97df21e918ce (patch)
tree25011e2eb7925fa274ab5c705e27f34a712e64e6 /erts/emulator/sys/common
parent85ae127bea4098f4ca61b51e02fbc06ba50bdd34 (diff)
downloadotp-3e645422ef452ae8c1051c4fdffa97df21e918ce.tar.gz
otp-3e645422ef452ae8c1051c4fdffa97df21e918ce.tar.bz2
otp-3e645422ef452ae8c1051c4fdffa97df21e918ce.zip
fix livelock in erts_poll_info_kp()
erts_poll_info_kp() [defined in erts/emulator/sys/common/erl_poll.c via some name-mangling trickery] contains a code path that can end up in an infinite loop, causing a livelock. There is a block of code inside #if ERTS_POLL_USE_UPDATE_REQUESTS_QUEUE that is supposed to iterate over a linked list of ErtsPollSetUpdateRequestsBlocks and update two variables based on the sizes of these blocks. The bug is that the loop forgets to advance the list pointer to the next element, so if the loop is entered at all (the initial list pointer is non-NULL), the thread falls into an infinite loop. This patch, against R13B03 but applies fine to today's git, fixes the bug by adding a statement to advance the list pointer in the loop. All other loops over this list appear to be correct. Thanks to Chetan Ahuja for the original report of a livelock problem in erts_poll_info_kp().
Diffstat (limited to 'erts/emulator/sys/common')
-rw-r--r--erts/emulator/sys/common/erl_poll.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index 5cca33d7eb..d268547e1a 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -2405,6 +2405,7 @@ ERTS_POLL_EXPORT(erts_poll_info)(ErtsPollSet ps, ErtsPollInfo *pip)
while (urqbp) {
size += sizeof(ErtsPollSetUpdateRequestsBlock);
pending_updates += urqbp->len;
+ urqbp = urqbp->next;
}
}
#endif