[asterisk-commits] juggie: branch juggie/NoLossCDR r84113 - /team/juggie/NoLossCDR/main/cdr.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Sep 28 17:01:21 CDT 2007
Author: juggie
Date: Fri Sep 28 17:01:21 2007
New Revision: 84113
URL: http://svn.digium.com/view/asterisk?view=rev&rev=84113
Log:
fix a race condition
Modified:
team/juggie/NoLossCDR/main/cdr.c
Modified: team/juggie/NoLossCDR/main/cdr.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/main/cdr.c?view=diff&rev=84113&r1=84112&r2=84113
==============================================================================
--- team/juggie/NoLossCDR/main/cdr.c (original)
+++ team/juggie/NoLossCDR/main/cdr.c Fri Sep 28 17:01:21 2007
@@ -715,21 +715,27 @@
ast_set_flag(cdr, AST_CDR_FLAG_POSTED);
if (ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED))
return;
+ /* add a ref to make sure we dont have a weird race condition */
+ ast_atomic_fetchadd_int(&cdr->usecount, +1);
AST_RWLIST_RDLOCK(&be_list);
AST_RWLIST_TRAVERSE(&be_list, i, list) {
AST_LIST_LOCK(&i->cdr_queue);
ast_debug(1, "cdr inserted into queue/list for: %s\n", i->name);
/* increment usecount of this cdr record */
ast_atomic_fetchadd_int(&cdr->usecount, +1);
- //ast_update_use_count();
/* increment cdr counter for this queue */
ast_atomic_fetchadd_int(&i->waiting_cdrs, +1);
- //ast_update_use_count();
AST_LIST_INSERT_TAIL(&i->cdr_queue, cdr, list);
ast_cond_signal(&i->cdr_pending_cond);
AST_LIST_UNLOCK(&i->cdr_queue);
}
AST_RWLIST_UNLOCK(&be_list);
+ ast_atomic_fetchadd_int(&cdr->usecount, -1);
+ if (ast_atomic_fetchadd_int(&cdr->usecount, -1) == 1) {
+ ast_debug(1, "cdr record no longer in any queue, so lets free it\n");
+ ast_cdr_free(cdr);
+ }
+
}
void ast_cdr_reset(struct ast_cdr *cdr, struct ast_flags *_flags)
@@ -855,6 +861,9 @@
ast_atomic_fetchadd_int(&i->waiting_cdrs, -1);
/* depracate uses of this cdr record
free if no one is using it*/
+ /* there is a race condition here, if one thread finishes working on the cdr before
+ it is posted to all the backends, then it will delete the cdr before we are actually
+ finished with it and an explosion occurs */
if (ast_atomic_fetchadd_int(&cdr->usecount, -1) == 1) {
ast_debug(1, "cdr record no longer in any queue, so lets free it\n");
ast_cdr_free(cdr);
More information about the asterisk-commits
mailing list