[asterisk-commits] murf: branch murf/bug11210 r91889 - in /team/murf/bug11210: apps/ channels/ f...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Dec 7 17:00:44 CST 2007
Author: murf
Date: Fri Dec 7 17:00:43 2007
New Revision: 91889
URL: http://svn.digium.com/view/asterisk?view=rev&rev=91889
Log:
OK, a good checkpoint. Every object that is created, gets destroyed. (plus a few get mult. destroys now). The ast_sched_ stuff is the secret.
Modified:
team/murf/bug11210/apps/app_queue.c
team/murf/bug11210/channels/chan_iax2.c
team/murf/bug11210/channels/chan_sip.c
team/murf/bug11210/funcs/func_dialgroup.c
team/murf/bug11210/include/asterisk/astobj2.h
team/murf/bug11210/main/astobj2.c
team/murf/bug11210/main/config.c
team/murf/bug11210/main/manager.c
team/murf/bug11210/utils/hashtest2.c
Modified: team/murf/bug11210/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/apps/app_queue.c?view=diff&rev=91889&r1=91888&r2=91889
==============================================================================
--- team/murf/bug11210/apps/app_queue.c (original)
+++ team/murf/bug11210/apps/app_queue.c Fri Dec 7 17:00:43 2007
@@ -107,6 +107,8 @@
char *file, int line, const char *funcname);
#define ao2_find(arg1,arg2,arg3) ao2_find_debug((arg1), (arg2), (arg3), "app_queue", __FILE__, __LINE__, __PRETTY_FUNCTION__)
void *ao2_find_debug(struct ao2_container *c, void *arg, enum search_flags flags, char *tag, char *file, int line, const char *funcname);
+#define ao2_iterator_next(arg1) ao2_iterator_next_debug((arg1), "app_queue", __FILE__, __LINE__, __PRETTY_FUNCTION__)
+void *ao2_iterator_next_debug(struct ao2_iterator *a, char *tag, char *file, int line, const char *funcname);
enum {
QUEUE_STRATEGY_RINGALL = 0,
Modified: team/murf/bug11210/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/chan_iax2.c?view=diff&rev=91889&r1=91888&r2=91889
==============================================================================
--- team/murf/bug11210/channels/chan_iax2.c (original)
+++ team/murf/bug11210/channels/chan_iax2.c Fri Dec 7 17:00:43 2007
@@ -97,8 +97,11 @@
void *ao2_alloc_debug(const size_t data_size, ao2_destructor_fn destructor_fn, char *tag, char *file, int line, const char *funcname);
#define ao2_container_alloc(arg1,arg2,arg3) ao2_container_alloc_debug((arg1), (arg2), (arg3), "IAX", __FILE__, __LINE__, __PRETTY_FUNCTION__)
struct ao2_container *ao2_container_alloc_debug(const uint n_buckets,
- ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
- char *tag, char *file, int line, const char *funcname);
+ ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
+ char *tag, char *file, int line, const char *funcname);
+#define ao2_iterator_next(arg1) ao2_iterator_next_debug((arg1), "IAX", __FILE__, __LINE__, __PRETTY_FUNCTION__)
+void *ao2_iterator_next_debug(struct ao2_iterator *a, char *tag, char *file, int line, const char *funcname);
+
#define ao2_callback(arg1,arg2,arg3,arg4) ao2_callback_debug((arg1), (arg2), (arg3), (arg4), "IAX", __FILE__, __LINE__, __PRETTY_FUNCTION__)
void *ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
ao2_callback_fn *cb_fn, void *arg, char *tag,
Modified: team/murf/bug11210/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/chan_sip.c?view=diff&rev=91889&r1=91888&r2=91889
==============================================================================
--- team/murf/bug11210/channels/chan_sip.c (original)
+++ team/murf/bug11210/channels/chan_sip.c Fri Dec 7 17:00:43 2007
@@ -1203,6 +1203,25 @@
* functions so we keep track of the refcounts.
* To simplify the code, we allow a NULL to be passed to dialog_unref().
*/
+#ifdef REF_DEBUG
+#define dialog_ref(arg1,arg2) dialog_ref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define dialog_unref(arg1,arg2) dialog_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+static struct sip_pvt *dialog_ref_debug(struct sip_pvt *p, char *tag, char *file, int line, const char *func)
+{
+ if (p)
+ ao2_ref_debug(p,1,tag,file,line,func);
+ else
+ ast_log(LOG_ERROR,"Attempt to Ref a null pointer\n");
+ return p;
+}
+
+static struct sip_pvt *dialog_unref_debug(struct sip_pvt *p, char *tag, char *file, int line, const char *func)
+{
+ if (p)
+ ao2_ref_debug(p,-1, tag, file, line, func);
+ return NULL;
+}
+#else
static struct sip_pvt *dialog_ref(struct sip_pvt *p, char *tag)
{
if (p)
@@ -1218,6 +1237,7 @@
ao2_ref(p,-1, tag);
return NULL;
}
+#endif
/*! \brief sip packet - raw format for outbound packets that are sent or scheduled for transmission
* Packets are linked in a list, whose head is in the struct sip_pvt they belong to.
@@ -1453,6 +1473,8 @@
{
struct sip_peer *peer = obj, *peer2 = arg;
+ ast_log(LOG_NOTICE,"peer %s == peer %s ? %d\n", peer->name, peer2->name, !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0);
+
return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
}
@@ -1475,6 +1497,11 @@
static int peer_ipcmp_cb(void *obj, void *arg, int flags)
{
struct sip_peer *peer = obj, *peer2 = arg;
+
+ ast_log(LOG_NOTICE,"peerip %d/%d (ins:%d) == peerip %d/%d (ins:%d) ? %d\n",
+ peer->addr.sin_addr.s_addr, peer->addr.sin_port, ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT),
+ peer2->addr.sin_addr.s_addr, peer2->addr.sin_port, ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT),
+ !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0);
if (peer->addr.sin_addr.s_addr != peer2->addr.sin_addr.s_addr)
return 0;
@@ -1505,6 +1532,7 @@
{
struct sip_user *user = obj, *user2 = arg;
+ ast_log(LOG_NOTICE,"user %s == user %s ? %d\n", user->name, user2->name, !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0);
return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
}
@@ -1524,7 +1552,7 @@
static int dialog_cmp_cb(void *obj, void *arg, int flags)
{
struct sip_pvt *pvt = obj, *pvt2 = arg;
- ast_log(LOG_NOTICE,"obj %s == obj %s ? %d\n", pvt->callid, pvt2->callid, !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0);
+ ast_log(LOG_NOTICE,"dialog %s == obj %s ? %d\n", pvt->callid, pvt2->callid, !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0);
return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0;
}
@@ -2044,6 +2072,14 @@
return NULL;
}
+static struct sip_peer *ref_peer(struct sip_peer *peer, char *tag)
+{
+ int rc = ao2_ref(peer,1,tag);
+ ast_log(LOG_NOTICE,"Ref peer %s prev refcount=%d\n", peer->name, rc);
+ return peer;
+}
+
+
static void *dialog_unlink_all(struct sip_pvt *dialog, int lockowner, int lockdialoglist)
{
int rc = ao2_ref(dialog,0, "");
@@ -2055,10 +2091,10 @@
ast_log(LOG_NOTICE,"Unlink dialog %s prev refcount=%d\n", dialog->callid, rc);
if (dialog->registry) {
if (dialog->registry->call == dialog)
- dialog->registry->call = NULL;
+ dialog->registry->call = dialog_unref(dialog->registry->call,"nulling out the registry's call dialog field in unlink_all");
dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
}
- /* Unlink us from the owner if we have one */
+ /* Unlink us from the owner (channel) if we have one */
if (dialog->owner) {
if (lockowner)
ast_channel_lock(dialog->owner);
@@ -2076,6 +2112,19 @@
else
dialog_unref(x,"remove result of ao2_find");
*/
+
+ if (dialog->initid > -1) {
+ ast_sched_del(sched, dialog->initid);
+ dialog_unref(dialog,"when you delete the initid sched, you should dec the refcount for the stored dialog ptr");
+ dialog->initid = -1;
+ }
+
+ if (dialog->autokillid > -1) {
+ ast_sched_del(sched, dialog->autokillid);
+ dialog_unref(dialog,"when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr");
+ dialog->autokillid = -1;
+ }
+
rc = ao2_ref(dialog,0,"");
ast_log(LOG_NOTICE,"Unlink dialog %s prev refcount=%d\n", dialog->callid, rc);
return NULL;
@@ -3753,7 +3802,7 @@
}
}
sip_pvt_unlock(p);
- dialog_unref(p,"unreffing arg passed into auto_conget -- is this right?");
+ dialog_unref(p,"unreffing arg passed into auto_congest callback");
return 0;
}
@@ -3841,7 +3890,7 @@
/* Initialize auto-congest time */
p->initid = ast_sched_replace(p->initid, sched, SIP_TRANS_TIMEOUT,
- auto_congest, dialog_ref(p, "sip_call: bumping refcount as calling ast_sched_replace"));
+ auto_congest, dialog_ref(p,"this is a pointer for the autocongest callback to use"));
}
return res;
@@ -3898,10 +3947,6 @@
if (p->stateid > -1)
ast_extension_state_del(p->stateid, NULL);
- if (p->initid > -1)
- ast_sched_del(sched, p->initid);
- if (p->autokillid > -1)
- ast_sched_del(sched, p->autokillid);
if (p->rtp)
ast_rtp_destroy(p->rtp);
@@ -3934,7 +3979,7 @@
p->packets = p->packets->next;
if (cp->retransid > -1)
ast_sched_del(sched, cp->retransid);
- dialog_unref(cp->owner,"free cp->owner dialog before freeing the pkt");
+ cp->owner = dialog_unref(cp->owner,"free cp->owner dialog before freeing the pkt");
ast_free(cp);
}
if (p->chanvars) {
@@ -5239,7 +5284,7 @@
return NULL;
if (ast_string_field_init(p, 512)) {
- ast_free(p);
+ ao2_ref(p,-1,"failed to string_field_init, drop p");
return NULL;
}
@@ -5291,7 +5336,7 @@
ast_variables_destroy(p->chanvars);
p->chanvars = NULL;
}
- ast_free(p);
+ ao2_ref(p,-1,"failed to create RTP audio session, drop p");
return NULL;
}
ast_rtp_setqos(p->rtp, global_tos_audio, global_cos_audio);
@@ -5507,7 +5552,7 @@
if (intended_method == SIP_RESPONSE)
ast_debug(2, "That's odd... Got a response on a call we dont know about. Callid %s\n", callid ? callid : "<unknown>");
- return p;
+ return p; /* most likely null if returning here */
}
/*! \brief Parse register=> line in sip.conf and add to registry */
@@ -7754,7 +7799,8 @@
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version)
{
struct sip_request req;
-
+ int res;
+
reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1);
add_header(&req, "Allow", ALLOWED_METHODS);
@@ -7771,7 +7817,8 @@
initialize_initreq(p, &req);
p->lastinvite = p->ocseq;
ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */
- return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
+ res = send_request(p, &req, XMIT_CRITICAL, p->ocseq);
+ return res;
}
/* \brief Remove URI parameters at end of URI, not in username part though */
@@ -8035,6 +8082,7 @@
static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init)
{
struct sip_request req;
+ int res;
req.method = sipmethod;
if (init) {/* Bump branch even on initial requests */
@@ -8123,7 +8171,8 @@
if (!p->initreq.headers)
initialize_initreq(p, &req);
p->lastinvite = p->ocseq;
- return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
+ res = send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
+ return res;
}
/*! \brief Used in the SUBSCRIBE notification subsystem */
@@ -8139,7 +8188,8 @@
enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
char *pidfstate = "--";
char *pidfnote= "Ready";
-
+ int res;
+
memset(from, 0, sizeof(from));
memset(to, 0, sizeof(to));
@@ -8304,7 +8354,8 @@
add_header_contentLength(&req, tmp->used);
add_line(&req, tmp->str);
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ res = send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ return res;
}
/*! \brief Notify user of messages waiting in voicemail
@@ -8317,7 +8368,8 @@
{
struct sip_request req;
struct ast_str *out = ast_str_alloca(500);
-
+ int res;
+
initreqprep(&req, p, SIP_NOTIFY);
add_header(&req, "Event", "message-summary");
add_header(&req, "Content-Type", default_notifymime);
@@ -8343,15 +8395,18 @@
if (!p->initreq.headers)
initialize_initreq(p, &req);
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ res = send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ return res;
}
/*! \brief Transmit SIP request unreliably (only used in sip_notify subsystem) */
static int transmit_sip_request(struct sip_pvt *p, struct sip_request *req)
{
+ int res;
if (!p->initreq.headers) /* Initialize first request before sending */
initialize_initreq(p, req);
- return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
+ res = send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
+ return res;
}
/*! \brief Notify a transferring party of the status of transfer */
@@ -8359,7 +8414,8 @@
{
struct sip_request req;
char tmp[BUFSIZ/2];
-
+ int res;
+
reqprep(&req, p, SIP_NOTIFY, 0, 1);
snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
add_header(&req, "Event", tmp);
@@ -8377,7 +8433,8 @@
p->lastnoninvite = p->ocseq;
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ res = send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ return res;
}
static const struct _map_x_s regstatestrings[] = {
@@ -8500,6 +8557,7 @@
char tmp[80];
char addr[80];
struct sip_pvt *p;
+ int res;
/* exit if we are already in process with this registrar ?*/
if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
@@ -8512,7 +8570,7 @@
ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
return 0;
} else {
- p = r->call;
+ p = dialog_ref(r->call,"getting a copy of the r->call dialog in transmit_register");
make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */
ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */
}
@@ -8559,7 +8617,7 @@
} else /* Set registry port to the port set from the peer definition/srv or default */
r->portno = ntohs(p->sa.sin_port);
ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
- r->call = dialog_ref(p,"transmit_register: setting dialog in registry r->call"); /* Save pointer to SIP dialog */
+ r->call = dialog_ref(p,"copying dialog into registry r->call"); /* Save pointer to SIP dialog */
p->registry = registry_addref(r,"transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */
if (!ast_strlen_zero(r->secret)) /* Secret (password) */
ast_string_field_set(p, peersecret, r->secret);
@@ -8687,17 +8745,21 @@
r->regattempts++; /* Another attempt */
if (option_debug > 3)
ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
- return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
+ res = send_request(p, &req, XMIT_CRITICAL, p->ocseq);
+ dialog_unref(p,"p is finished here at the end of transmit_register");
+ return res;
}
/*! \brief Transmit text with SIP MESSAGE method */
static int transmit_message_with_text(struct sip_pvt *p, const char *text)
{
struct sip_request req;
-
+ int res;
+
reqprep(&req, p, SIP_MESSAGE, 0, 1);
add_text(&req, text);
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ res = send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ return res;
}
/*! \brief Allocate SIP refer structure */
@@ -8723,6 +8785,7 @@
char referto[256];
char *ttag, *ftag;
char *theirtag = ast_strdupa(p->theirtag);
+ int res;
if (sipdebug)
ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest);
@@ -8770,7 +8833,9 @@
if (!ast_strlen_zero(p->our_contact))
add_header(&req, "Referred-By", p->our_contact);
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ res = send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ return res;
+
/* We should propably wait for a NOTIFY here until we ack the transfer */
/* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
@@ -8786,20 +8851,24 @@
static int transmit_info_with_digit(struct sip_pvt *p, const char digit, unsigned int duration)
{
struct sip_request req;
-
+ int res;
+
reqprep(&req, p, SIP_INFO, 0, 1);
add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO));
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ res = send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ return res;
}
/*! \brief Send SIP INFO with video update request */
static int transmit_info_with_vidupdate(struct sip_pvt *p)
{
struct sip_request req;
-
+ int res;
+
reqprep(&req, p, SIP_INFO, 0, 1);
add_vidupdate(&req);
- return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ res = send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+ return res;
}
/*! \brief Transmit generic SIP request
@@ -8808,7 +8877,8 @@
static int transmit_request(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
{
struct sip_request resp;
-
+ int res;
+
if (sipmethod == SIP_ACK)
p->invitestate = INV_CONFIRMED;
@@ -8817,7 +8887,8 @@
add_header(&resp, "Reason:", "SIP;cause=200;text=\"Call completed elsewhere\"");
add_header_contentLength(&resp, 0);
- return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
+ res = send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
+ return res;
}
/*! \brief return the request and response heade for a 401 or 407 code */
@@ -8839,7 +8910,8 @@
static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
{
struct sip_request resp;
-
+ int res;
+
reqprep(&resp, p, sipmethod, seqno, newbranch);
if (!ast_strlen_zero(p->realm)) {
char digest[1024];
@@ -8864,7 +8936,8 @@
}
add_header_contentLength(&resp, 0);
- return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
+ res = send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
+ return res;
}
/*! \brief Remove registration data from realtime database or AST/DB when registration expires */
@@ -10883,7 +10956,7 @@
i = ao2_iterator_init(users, 0);
- while ((user = ao2_iterator_next(&i))) {
+ while ((user = ao2_iterator_next(&i,"iterate thru user table"))) {
if (user->call_limit)
snprintf(ilimits, sizeof(ilimits), "%d", user->call_limit);
else
@@ -10891,13 +10964,14 @@
snprintf(iused, sizeof(iused), "%d", user->inUse);
if (showall || user->call_limit)
ast_cli(a->fd, FORMAT2, user->name, iused, ilimits);
+ unref_user(user,"toss iterator pointer");
}
ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit");
i = ao2_iterator_init(peers, 0);
- while ((peer = ao2_iterator_next(&i))) {
+ while ((peer = ao2_iterator_next(&i, "iterate thru peer table"))) {
if (peer->call_limit)
snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit);
else
@@ -10905,6 +10979,7 @@
snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold);
if (showall || peer->call_limit)
ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits);
+ unref_peer(peer,"toss iterator pointer");
}
return CLI_SUCCESS;
@@ -11012,7 +11087,7 @@
i = ao2_iterator_init(users, 0);
- while ((user = ao2_iterator_next(&i))) {
+ while ((user = ao2_iterator_next(&i, "iterate thru user table"))) {
if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) {
ao2_unlock(user);
@@ -11025,6 +11100,7 @@
user->context,
cli_yesno(user->ha != NULL),
nat2str(ast_test_flag(&user->flags[0], SIP_NAT)));
+ unref_user(user,"toss iterator pointer");
}
if (havepattern)
@@ -11185,13 +11261,14 @@
ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
i = ao2_iterator_init(peers, 0);
- while ((peer = ao2_iterator_next(&i))) {
+ while ((peer = ao2_iterator_next(&i, "iterate thru peers table"))) {
char status[20] = "";
char srch[2000];
char pstatus;
if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
ao2_unlock(peer);
+ unref_peer(peer,"toss iterator peer ptr before continue");
continue;
}
@@ -11259,6 +11336,7 @@
}
total_peers++;
+ unref_peer(peer,"toss iterator peer ptr");
}
if (!s)
@@ -11532,14 +11610,16 @@
ao2_lock(peers); /* was WRLOCK */
i = ao2_iterator_init(peers, 0);
- while ((pi = ao2_iterator_next(&i))) {
+ while ((pi = ao2_iterator_next(&i,"iterate thru peers table"))) {
if (name && regexec(®exbuf, pi->name, 0, NULL, 0)) {
+ unref_peer(pi,"toss iterator peer ptr before continue");
continue;
};
if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
pi->theMark = 1;
pruned++;
}
+ unref_peer(pi,"toss iterator peer ptr");
}
if (pruned) {
ast_log(LOG_NOTICE,"Callback to PRUNE PEERS\n");
@@ -11554,14 +11634,16 @@
ao2_lock(users); /* was WRLOCK */
i = ao2_iterator_init(users, 0);
- while ((ui = ao2_iterator_next(&i))) {
+ while ((ui = ao2_iterator_next(&i, "iterate thru users table"))) {
if (name && regexec(®exbuf, ui->name, 0, NULL, 0)) {
+ unref_user(ui,"toss iterator user ptr before continue");
continue;
};
if (ast_test_flag(&ui->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
ui->theMark = 1;
pruned++;
}
+ unref_user(ui,"toss iterator user ptr");
}
if (pruned) {
ast_log(LOG_NOTICE,"Callback to PRUNE USERS\n");
@@ -12421,7 +12503,7 @@
i = ao2_iterator_init(dialogs, 0);
- while ((cur = ao2_iterator_next(&i))) {
+ while ((cur = ao2_iterator_next(&i, "iterate thru dialogs"))) {
if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
c = ast_strdup(cur->callid);
ao2_ref(cur,-1,"drop ref in iterator loop break");
@@ -12442,14 +12524,17 @@
struct ao2_iterator i = ao2_iterator_init(peers,0);
struct sip_peer *peer;
- while ((peer = ao2_iterator_next(&i))) {
+ while ((peer = ao2_iterator_next(&i, "iterate thru peers table"))) {
/* locking of the object is not required because only the name and flags are being compared */
if (!strncasecmp(word, peer->name, wordlen) &&
(!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
++which > state)
result = ast_strdup(peer->name);
- if (result)
+ if (result) {
+ unref_peer(peer,"toss iterator peer ptr before break");
break;
+ }
+ unref_peer(peer,"toss iterator peer ptr");
}
return result;
}
@@ -12464,13 +12549,16 @@
struct sip_peer *peer;
i = ao2_iterator_init(peers, 0);
- while ((peer = ao2_iterator_next(&i))) {
+ while ((peer = ao2_iterator_next(&i, "iterate thru peers table"))) {
if (!strncasecmp(word, peer->name, wordlen) &&
(!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
++which > state && peer->expire > 0)
result = ast_strdup(peer->name);
- if (result)
+ if (result) {
+ unref_peer(peer,"toss iterator peer ptr before break");
break;
+ }
+ unref_peer(peer,"toss iterator peer ptr");
}
return result;
}
@@ -12513,17 +12601,22 @@
i = ao2_iterator_init(users, 0);
- while ((user = ao2_iterator_next(&i))) {
+ while ((user = ao2_iterator_next(&i, "iterate thru users table"))) {
/* locking of the object is not required because only the name and flags are being compared */
if (!strncasecmp(word, user->name, wordlen)) {
- if (flags2 && !ast_test_flag(&user->flags[1], flags2))
+ if (flags2 && !ast_test_flag(&user->flags[1], flags2)) {
+ unref_user(user,"toss iterator user ptr before continue");
continue;
+ }
if (++which > state) {
result = ast_strdup(user->name);
}
}
- if (result)
+ if (result) {
+ unref_user(user,"toss iterator user ptr before break");
break;
+ }
+ unref_user(user,"toss iterator user ptr");
}
return result;
}
@@ -12593,7 +12686,7 @@
i = ao2_iterator_init(dialogs, 0);
- while ((cur = ao2_iterator_next(&i))) {
+ while ((cur = ao2_iterator_next(&i, "iterate thru dialogs"))) {
if (!strncasecmp(cur->callid, a->argv[3], len)) {
char formatbuf[BUFSIZ/2];
ast_cli(a->fd,"\n");
@@ -12645,6 +12738,7 @@
ast_cli(a->fd, "\n\n");
found++;
}
+ ao2_ref(cur,-1,"toss dialog ptr set by iterator_next");
}
dialoglist_unlock();
if (!found)
@@ -12678,7 +12772,7 @@
len = strlen(a->argv[3]);
dialoglist_lock();
i = ao2_iterator_init(dialogs, 0);
- while ((cur = ao2_iterator_next(&i))) {
+ while ((cur = ao2_iterator_next(&i,"iterate thru dialogs"))) {
if (!strncasecmp(cur->callid, a->argv[3], len)) {
struct sip_history *hist;
int x = 0;
@@ -12695,6 +12789,7 @@
ast_cli(a->fd, "Call '%s' has no history\n", cur->callid);
found++;
}
+ ao2_ref(cur,-1,"toss dialog ptr from iterator_next");
}
dialoglist_unlock();
if (!found)
@@ -13077,9 +13172,10 @@
build_via(p);
build_callid_pvt(p);
ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]);
+ dialog_ref(p,"bump the count of p, which transmit_sip_request will decrement.");
transmit_sip_request(p, &req);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- dialog_unref(p,"unref pvt at end of for loop");
+ dialog_unref(p,"unref pvt at end of for loop in sip_notify");
}
return CLI_SUCCESS;
@@ -13691,6 +13787,7 @@
if (p->initid > -1) {
/* Don't auto congest anymore since we've gotten something useful back */
ast_sched_del(sched, p->initid);
+ dialog_unref(p,"when you delete the initid sched, you should dec the refcount for the stored dialog ptr");
p->initid = -1;
}
@@ -14041,8 +14138,8 @@
{
int expires, expires_ms;
struct sip_registry *r;
- r=p->registry;
-
+ r=p->registry; /* do I need to ref/unref this during this routine? Doesn't LOOK like it...*/
+
switch (resp) {
case 401: /* Unauthorized */
if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
@@ -14060,7 +14157,8 @@
case 404: /* Not found */
ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
p->needdestroy = 1;
- r->call = NULL;
+ if (r->call)
+ r->call = dialog_unref(r->call,"unsetting registry->call pointer-- case 404");
r->regstate = REG_STATE_REJECTED;
ast_sched_del(sched, r->timeout);
r->timeout = -1;
@@ -14075,7 +14173,8 @@
if (global_regattempts_max)
p->registry->regattempts = global_regattempts_max+1;
p->needdestroy = 1;
- r->call = NULL;
+ if (r->call)
+ r->call = dialog_unref(r->call,"unsetting registry->call pointer-- case 408");
ast_sched_del(sched, r->timeout);
r->timeout = -1;
break;
@@ -14085,7 +14184,7 @@
ast_sched_del(sched, r->timeout);
r->timeout = -1;
if (r->call) {
- r->call = NULL;
+ r->call = dialog_unref(r->call,"unsetting registry->call pointer-- case 423");
p->needdestroy = 1;
}
if (r->expiry > max_expiry) {
@@ -14101,7 +14200,8 @@
case 479: /* SER: Not able to process the URI - address is wrong in register*/
ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
p->needdestroy = 1;
- r->call = NULL;
+ if (r->call)
+ r->call = dialog_unref(r->call,"unsetting registry->call pointer-- case 479");
r->regstate = REG_STATE_REJECTED;
ast_sched_del(sched, r->timeout);
r->timeout = -1;
@@ -14112,7 +14212,7 @@
p->needdestroy = 1;
return 0;
}
-
+
r->regstate = REG_STATE_REGISTERED;
r->regtime = ast_tvnow(); /* Reset time of last succesful registration */
manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
@@ -14123,12 +14223,13 @@
ast_sched_del(sched, r->timeout);
}
r->timeout=-1;
- r->call = NULL;
- p->registry = registry_unref(p->registry,"unref registry entry p->registry"); /* are we erasing a ref? */
+ if (r->call)
+ r->call = dialog_unref(r->call,"unsetting registry->call pointer-- case 200");
+ p->registry = registry_unref(p->registry,"unref registry entry p->registry");
/* Let this one hang around until we have all the responses */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
/* p->needdestroy = 1; */
-
+
/* set us up for re-registering */
/* figure out how long we got registered for */
if (r->expire > -1)
@@ -14136,7 +14237,7 @@
/* according to section 6.13 of RFC, contact headers override
expires headers, so check those first */
expires = 0;
-
+
/* XXX todo: try to save the extra call */
if (!ast_strlen_zero(get_header(req, "Contact"))) {
const char *contact = NULL;
@@ -14158,13 +14259,13 @@
if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
expires = 0;
}
-
+
}
if (!expires)
expires=atoi(get_header(req, "expires"));
if (!expires)
expires=default_expiry;
-
+
expires_ms = expires * 1000;
if (expires <= EXPIRY_GUARD_LIMIT)
expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
@@ -14172,12 +14273,16 @@
expires_ms -= EXPIRY_GUARD_SECS * 1000;
if (sipdebug)
ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000);
-
+
r->refresh= (int) expires_ms / 1000;
-
+
/* Schedule re-registration before we expire */
r->expire = ast_sched_replace(r->expire, sched, expires_ms, sip_reregister, r);
- registry_unref(r,"unref registry ptr r");
+ registry_unref(r,"unref registry ptr r"); /* HUH? if this gets deleted, p->registry will be a bad pointer! */
+ /* shouldn't this be:
+ p->registry = registry_unref(r,"unref registry entry at p->registry");
+ ???????
+ */
}
return 1;
}
@@ -14185,7 +14290,7 @@
/*! \brief Handle qualification responses (OPTIONS) */
static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_request *req)
{
- struct sip_peer *peer = p->relatedpeer; /* hope this is already refcounted! */
+ struct sip_peer *peer = ref_peer(p->relatedpeer,"bump refcount on p, as it is being used in this function(handle_response_peerpoke)"); /* hope this is already refcounted! */
int statechanged, is_reachable, was_reachable;
int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
@@ -14227,6 +14332,7 @@
peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched,
is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
sip_poke_peer_s, peer);
+ unref_peer(peer,"unref relatedpeer ptr var at end of handle_response_peerpoke");
}
/*! \brief Immediately stop RTP, VRTP and UDPTL as applicable */
@@ -16627,8 +16733,12 @@
authpeer->mwipvt = dialog_unref(authpeer->mwipvt,"unref dialog authpeer->mwipvt");
/* sip_destroy(authpeer->mwipvt); */
}
- authpeer->mwipvt = p; /* Link from peer to pvt UH- should this be dialog_ref()? */
- p->relatedpeer = authpeer; /* already refcounted...Link from pvt to peer UH- should this be dialog_ref()? */
+ if (authpeer->mwipvt)
+ dialog_unref(authpeer->mwipvt,"Unref previously stored mwipvt dialog pointer");
+ authpeer->mwipvt = dialog_ref(p,"setting peers' mwipvt to p"); /* Link from peer to pvt UH- should this be dialog_ref()? */
+ if (p->relatedpeer)
+ unref_peer(p->relatedpeer,"Unref previously stored relatedpeer ptr");
+ p->relatedpeer = ref_peer(authpeer,"setting dialog's relatedpeer pointer"); /* already refcounted...Link from pvt to peer UH- should this be dialog_ref()? */
/* Do not release authpeer here */
} else { /* At this point, Asterisk does not understand the specified event */
transmit_response(p, "489 Bad Event", req);
@@ -16701,23 +16811,31 @@
i = ao2_iterator_init(dialogs, 0);
- while ((p_old = ao2_iterator_next(&i))) {
- if (p_old == p)
+ while ((p_old = ao2_iterator_next(&i,"iterate thru dialogs"))) {
+ if (p_old == p) {
+ ao2_ref(p_old,-1,"toss dialog ptr from iterator_next before continue");
continue;
- if (p_old->initreq.method != SIP_SUBSCRIBE)
+ }
+ if (p_old->initreq.method != SIP_SUBSCRIBE) {
+ ao2_ref(p_old,-1,"toss dialog ptr from iterator_next before continue");
continue;
- if (p_old->subscribed == NONE)
+ }
+ if (p_old->subscribed == NONE) {
+ ao2_ref(p_old,-1,"toss dialog ptr from iterator_next before continue");
continue;
+ }
sip_pvt_lock(p_old);
if (!strcmp(p_old->username, p->username)) {
if (!strcmp(p_old->exten, p->exten) &&
!strcmp(p_old->context, p->context)) {
p_old->needdestroy = 1;
sip_pvt_unlock(p_old);
+ ao2_ref(p_old,-1,"toss dialog ptr from iterator_next before break");
break;
}
}
sip_pvt_unlock(p_old);
+ ao2_ref(p_old,-1,"toss dialog ptr from iterator_next");
}
dialoglist_unlock();
}
@@ -17177,8 +17295,8 @@
/* Send MWI */
ast_set_flag(&p->flags[0], SIP_OUTGOING);
+ /* the following will decrement the refcount on p as it finishes */
transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
-
return 0;
}
@@ -17395,8 +17513,9 @@
peer->call = dialog_unref(peer->call, "unref dialog peer->call");
/* peer->call = sip_destroy(peer->call); */
}
- if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
+ if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
return -1;
+ peer->call = dialog_ref(p,"copy sip alloc from p to peer->call");
p->sa = peer->addr;
p->recv = peer->addr;
@@ -17419,14 +17538,13 @@
if (peer->pokeexpire > -1)
ast_sched_del(sched, peer->pokeexpire);
- p->relatedpeer = peer;
- ao2_ref(peer,1,"add one for ->relatedpeer copy"); /* we just added another ref to peer here */
+ p->relatedpeer = ref_peer(peer,"setting the relatedpeer field in the dialog");
ast_set_flag(&p->flags[0], SIP_OUTGOING);
#ifdef VOCAL_DATA_HACK
ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
- xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
+ xmitres = transmit_invite(p, SIP_INVITE, 0, 2); /* sinks the p refcount */
#else
- xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
+ xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); /* sinks the p refcount */
#endif
peer->ps = ast_tvnow();
if (xmitres == XMIT_ERROR)
@@ -17637,10 +17755,9 @@
if (!tmpc) {
ast_log(LOG_NOTICE,"Calling Sip_Destroy() from call request 3 for %s....\n", p->callid);
dialog_unlink_all(p, TRUE, TRUE);
- dialog_unref(p,"unref dialog before destroy");
/* sip_destroy(p); */
}
-
+ dialog_unref(p,"toss pvt ptr at end of sip_request_call");
ast_update_use_count();
restart_monitor();
return tmpc;
@@ -19589,10 +19706,11 @@
if (!speerobjs) /* No peers, just give up */
return;
- while ((peer = ao2_iterator_next(&i))) {
+ while ((peer = ao2_iterator_next(&i, "iterate thru peers table"))) {
ms += 100;
peer->pokeexpire = ast_sched_replace(peer->pokeexpire,
sched, ms, sip_poke_peer_s, peer);
+ unref_peer(peer,"toss iterator peer ptr");
}
}
@@ -19814,9 +19932,10 @@
dialoglist_lock();
/* Hangup all dialogs if they have an owner */
i = ao2_iterator_init(dialogs, 0);
- while ((p = ao2_iterator_next(&i))) {
+ while ((p = ao2_iterator_next(&i, "iterate thru dialogs"))) {
if (p->owner)
ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
+ ao2_ref(p,-1,"toss dialog ptr from iterator_next");
}
dialoglist_unlock();
@@ -19832,7 +19951,7 @@
dialoglist_lock();
/* Destroy all the dialogs and free their memory */
i = ao2_iterator_init(dialogs, 0);
- while ((p = ao2_iterator_next(&i))) {
+ while ((p = ao2_iterator_next(&i, "iterate thru dialogs"))) {
ao2_unlink(dialogs,p,"unlink from dialogs");
ao2_ref(p,-1,"throw away iterator result");
}
Modified: team/murf/bug11210/funcs/func_dialgroup.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/funcs/func_dialgroup.c?view=diff&rev=91889&r1=91888&r2=91889
==============================================================================
--- team/murf/bug11210/funcs/func_dialgroup.c (original)
+++ team/murf/bug11210/funcs/func_dialgroup.c Fri Dec 7 17:00:43 2007
@@ -55,6 +55,8 @@
char *file, int line, const char *funcname);
#define ao2_find(arg1,arg2,arg3) ao2_find_debug((arg1), (arg2), (arg3), "func_dialgroup", __FILE__, __LINE__, __PRETTY_FUNCTION__)
void *ao2_find_debug(struct ao2_container *c, void *arg, enum search_flags flags, char *tag, char *file, int line, const char *funcname);
+#define ao2_iterator_next(arg1) ao2_iterator_next_debug((arg1), "func_dialgroup", __FILE__, __LINE__, __PRETTY_FUNCTION__)
+void *ao2_iterator_next_debug(struct ao2_iterator *a, char *tag, char *file, int line, const char *funcname);
static struct ao2_container *group_container = NULL;
Modified: team/murf/bug11210/include/asterisk/astobj2.h
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/include/asterisk/astobj2.h?view=diff&rev=91889&r1=91888&r2=91889
==============================================================================
--- team/murf/bug11210/include/asterisk/astobj2.h (original)
+++ team/murf/bug11210/include/asterisk/astobj2.h Fri Dec 7 17:00:43 2007
@@ -659,8 +659,12 @@
};
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags);
-
+#ifdef REF_DEBUG
+#define ao2_iterator_next(arg1, arg2) ao2_iterator_next_debug((arg1), (arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+void *ao2_iterator_next_debug(struct ao2_iterator *a, char *tag, char *file, int line, const char *funcname);
+#else
void *ao2_iterator_next(struct ao2_iterator *a);
+#endif
/* extra functions */
void ao2_bt(void); /* backtrace */
Modified: team/murf/bug11210/main/astobj2.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/main/astobj2.c?view=diff&rev=91889&r1=91888&r2=91889
==============================================================================
--- team/murf/bug11210/main/astobj2.c (original)
+++ team/murf/bug11210/main/astobj2.c Fri Dec 7 17:00:43 2007
@@ -790,7 +790,8 @@
/*
* move to the next element in the container.
*/
-void * ao2_iterator_next(struct ao2_iterator *a)
+#ifdef REF_DEBUG
+void * ao2_iterator_next_debug(struct ao2_iterator *a, char *tag, char *file, int line, const char *funcname)
{
int lim;
struct bucket_list *p = NULL;
@@ -837,7 +838,7 @@
a->c_version = a->c->version;
ret = EXTERNAL_OBJ(p->astobj);
/* inc refcount of returned object */
- ao2_ref(ret, 1, "iterator_next bumps the refcount before returning ptr" );
+ ao2_ref_debug(ret, 1, tag, file, line, funcname);
}
if (!(a->flags & F_AO2I_DONTLOCK))
@@ -845,6 +846,63 @@
return ret;
}
+#else
+void * ao2_iterator_next(struct ao2_iterator *a)
+{
+ int lim;
+ struct bucket_list *p = NULL;
+ void *ret = NULL;
+
+ if (INTERNAL_OBJ(a->c) == NULL)
+ return NULL;
+
+ if (!(a->flags & F_AO2I_DONTLOCK))
+ ao2_lock(a->c);
+
+ /* optimization. If the container is unchanged and
+ * we have a pointer, try follow it
+ */
+ if (a->c->version == a->c_version && (p = a->obj) ) {
+ if ( (p = AST_LIST_NEXT(p, entry)) )
+ goto found;
+ /* nope, start from the next bucket */
+ a->bucket++;
+ a->version = 0;
+ a->obj = NULL;
+ }
+
+ lim = a->c->n_buckets;
+
+ /* Browse the buckets array, moving to the next
+ * buckets if we don't find the entry in the current one.
+ * Stop when we find an element with version number greater
+ * than the current one (we reset the version to 0 when we
+ * switch buckets).
+ */
+ for (; a->bucket < lim; a->bucket++, a->version = 0) {
+ /* scan the current bucket */
+ AST_LIST_TRAVERSE(&a->c->buckets[a->bucket], p, entry) {
+ if (p->version > a->version)
+ goto found;
+ }
+ }
+
+found:
+ if (p) {
+ a->version = p->version;
+ a->obj = p;
+ a->c_version = a->c->version;
+ ret = EXTERNAL_OBJ(p->astobj);
+ /* inc refcount of returned object */
[... 86 lines stripped ...]
More information about the asterisk-commits
mailing list