[Asterisk-Dev] ForkCDR and hangups
Cees de Groot
cg at tric.nl
Thu Dec 30 04:06:57 MST 2004
Hi,
As there's little response on the -users list, I'm taking this here. To
recap, I had problems when I introduced ForkCDR in my dial plan - now and
then, Asterisk threads would go bezerk, eat 100% CPU time. DDD quickly
told me that this was always when doing one of the cdr->next loops in
cdr.c...
The only place that cdr->next is handled, is in ast_cdr_append where -
IMHO - some tricky stuff appears with the CDR linked list. As far as my
setup is concerned, this is called from ForkCDR and the Zap transfer
function (which I presume is used when doing a Dial - the system at hand
lets users dial a 0900 (special rate) number and dial out international
numbers again).
Indeed, the cdr->next->next == cdr in DDD, ergo an endless loop.
I quickly patched it up:
Index: cdr.c
===================================================================
RCS file: /var/lib/cvsroot/breezz/lib/asterisk/cdr.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 cdr.c
--- cdr.c16 Nov 2004 16:57:07 -00001.1.1.1
+++ cdr.c30 Dec 2004 10:55:33 -0000
@@ -532,6 +532,11 @@
while(cdr->next)
cdr = cdr->next;
cdr->next = newcdr;
+/* Stopgap measure to remove circularities
+ * that can occur when ForkCDR() is used...
+ */
+if (newcdr->next == cdr)
+newcdr->next = NULL;
} else {
ret = newcdr;
}
But next day, I had some threads in 100% CPU mode again. DDD showed me
that now, I had *three* CDR's, where cdr == cdr->next->next->next, a case
my stopgap hack didn't catch of course. Sifting through the dialplan I
noticed indeed that it was possible to call ForkCDR multiple times, and
indeed it would be preferrable to have it that way (one CDR for the
inbound leg, one CDR for each outbound attempt. If an outbound attempt
fails, the user is transported back to the IVR main menu). I patched my
dialplan so it goes through ForkCDR only once (which is sufficient for now
- we mostly want to catch the outbound leg's billable seconds, but later
one we might want to register the failed outbound attempts as well, or
even change the menu that the user stays in the IVR after a
succesful call), and since then Asterisk is running.
I haven't got a clue what all the CDR 'stitching' in
chan_zap.c:attempt_transfer() should accomplish (to be frank, I haven't
really really studied that code), but something there is quite
incompatible with ForkCDR, it seems.
Anyone who can shed some light on this? Wrt code quality, should all the
loops in cdr.c be rewritten so that they detect endless loops? (probably
by replacing all the while statements by some industrial quality iteration
function ;-)). I really want to be able to use ForkCDR multiple times in a
single call...
TIA,
Cees
More information about the asterisk-dev
mailing list