<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/4.2.3">
</HEAD>
<BODY>
Hi Anca,<BR>
<BR>
This is the watchers table, not the active_watchers table.&nbsp; It's the cache table for presence authorisation (based on a parse of pres-rules), so it has nothing to do with dialogs.<BR>
<BR>
Regards,<BR>
<BR>
Peter<BR>
<BR>
On Thu, 2012-03-29 at 18:30 +0300, Anca Vamanu wrote:
<BLOCKQUOTE TYPE=CITE>
<PRE>
Hi Peter,

You do not create transactions for Subscribe requests before calling 
handle_subscribe() function to catch retransmissions?
I wonder how can you get to the situation of another process inserting a 
record (with exactly the same callid, to tag &amp; from tag) between the 
query and the insert.

Regards,
Anca

On 03/29/2012 06:13 PM, Peter Dunkley wrote:
&gt; Module: sip-router
&gt; Branch: master
&gt; Commit: 5a89af6ea8b83ecc781d3f169023fde8388a2da6
&gt; URL:    <A HREF="http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=5a89af6ea8b83ecc781d3f169023fde8388a2da6">http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=5a89af6ea8b83ecc781d3f169023fde8388a2da6</A>
&gt;
&gt; Author: Peter Dunkley&lt;<A HREF="mailto:peter.dunkley@crocodile-rcs.com">peter.dunkley@crocodile-rcs.com</A>&gt;
&gt; Committer: Peter Dunkley&lt;<A HREF="mailto:peter.dunkley@crocodile-rcs.com">peter.dunkley@crocodile-rcs.com</A>&gt;
&gt; Date:   Thu Mar 29 16:02:13 2012 +0100
&gt;
&gt; modules_k/presence: Fixed DB insert race hazard on the watchers table
&gt;
&gt; - The time between the query on the watchers table (which determines
&gt;    there is no matching entry) and the insert is substantial.  During
&gt;    a soak I observed inserts failing because rows had been inserted in
&gt;    this time window.
&gt; - The fix is to use replace (where available) instead of insert.
&gt; - Also fixed a small whitespace issue I noticed, and added an extra
&gt;    use_table call (as I think there was one missing).
&gt;
&gt; ---
&gt;
&gt;   modules_k/presence/presence.c  |    2 +-
&gt;   modules_k/presence/subscribe.c |   32 ++++++++++++++++++++++++++++----
&gt;   2 files changed, 29 insertions(+), 5 deletions(-)
&gt;
&gt; diff --git a/modules_k/presence/presence.c b/modules_k/presence/presence.c
&gt; index dd415f7..f6f9152 100644
&gt; --- a/modules_k/presence/presence.c
&gt; +++ b/modules_k/presence/presence.c
&gt; @@ -833,7 +833,7 @@ int update_watchers_status(str pres_uri, pres_ev_t* ev, str* rules_doc)
&gt;           }ws_t;
&gt;           ws_t* ws_list= NULL;
&gt;
&gt; -    LM_DBG(&quot;start\n&quot;);
&gt; +        LM_DBG(&quot;start\n&quot;);
&gt;
&gt;           if(ev-&gt;content_type.s== NULL)
&gt;           {
&gt; diff --git a/modules_k/presence/subscribe.c b/modules_k/presence/subscribe.c
&gt; index 0c914c7..0a9db83 100644
&gt; --- a/modules_k/presence/subscribe.c
&gt; +++ b/modules_k/presence/subscribe.c
&gt; @@ -315,6 +315,12 @@ int insert_subs_db(subs_t* s, int type)
&gt;           query_vals[reason_col].val.str_val= s-&gt;reason;
&gt;           query_vals[socket_info_col].val.str_val= s-&gt;sockinfo_str;
&gt;
&gt; +        if (pa_dbf.use_table(pa_db,&amp;active_watchers_table)&lt;  0)
&gt; +        {
&gt; +                LM_ERR(&quot;in use table sql operation\n&quot;);        
&gt; +                return -1;
&gt; +        }
&gt; +
&gt;           LM_DBG(&quot;inserting subscription in active_watchers table\n&quot;);
&gt;           if(pa_dbf.insert(pa_db, query_cols, query_vals, n_query_cols)&lt;  0)
&gt;           {
&gt; @@ -2310,10 +2316,28 @@ int insert_db_subs_auth(subs_t* subs)
&gt;                   return -1;
&gt;           }
&gt;
&gt; -        if(pa_dbf.insert(pa_db, db_keys, db_vals, n_query_cols )&lt;  0)
&gt; -        {        
&gt; -                LM_ERR(&quot;in sql insert\n&quot;);
&gt; -                return -1;
&gt; +        if (pa_dbf.replace != NULL)
&gt; +        {
&gt; +                if(pa_dbf.replace(pa_db, db_keys, db_vals, n_query_cols,
&gt; +                                        2, 0)&lt;  0)
&gt; +                {
&gt; +                        LM_ERR(&quot;in sql replace\n&quot;);
&gt; +                        return -1;
&gt; +                }
&gt; +        }
&gt; +        else
&gt; +        {
&gt; +                /* If you use insert() instead of replace() be prepared for some
&gt; +                    DB error messages.  There is a lot of time between the
&gt; +                   query() that indicated there was no matching entry in the DB
&gt; +                   and this insert(), so on a multi-user system it is entirely
&gt; +                   possible (even likely) that a record will be added after the
&gt; +                   query() but before this insert(). */
&gt; +                if(pa_dbf.insert(pa_db, db_keys, db_vals, n_query_cols )&lt;  0)
&gt; +                {        
&gt; +                        LM_ERR(&quot;in sql insert\n&quot;);
&gt; +                        return -1;
&gt; +                }
&gt;           }
&gt;
&gt;           return 0;
&gt;
&gt;
&gt; _______________________________________________
&gt; sr-dev mailing list
&gt; <A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A>
&gt; <A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A>
&gt;


_______________________________________________
sr-dev mailing list
<A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A>
<A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A>
</PRE>
</BLOCKQUOTE>
<BR>
<TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE>
-- 
Peter Dunkley
Technical Director
Crocodile RCS Ltd
</PRE>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>