From 91e4dbd46f1d042fa94cf11e582e71b251625b24 Mon Sep 17 00:00:00 2001 From: Damien Sandras Date: Mon, 5 Aug 2013 15:56:41 +0200 Subject: [PATCH 1/4] PUBLISH requests are now handled in the same order than received. That is specifically useful for pua dialoginfo which was generating dialog info notifications that were handled in the wrong order with that patch. PUBLISH with older documents were sometimes treated after PUBLISH requests with newer documents, leading to incoherent states. --- modules/presence/hash.c | 27 ++++++++++++++++++--- modules/presence/hash.h | 7 +++++- modules/presence/presentity.c | 44 +++++++++++++++++++++++++++-------- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/modules/presence/hash.c b/modules/presence/hash.c index e520029a14d..93b285b3b2c 100644 --- a/modules/presence/hash.c +++ b/modules/presence/hash.c @@ -506,7 +506,7 @@ void update_pres_etag(pres_entry_t* p, str* etag) p->etag_count++; } -int insert_phtable(str* pres_uri, int event, str* etag, char* sphere) +pres_entry_t* insert_phtable(str* pres_uri, int event, str* etag, char* sphere, int init_turn) { unsigned int hash_code; pres_entry_t* p= NULL; @@ -543,14 +543,16 @@ int insert_phtable(str* pres_uri, int event, str* etag, char* sphere) p->next= pres_htable[hash_code].entries->next; pres_htable[hash_code].entries->next= p; + p->last_turn = init_turn; + lock_release(&pres_htable[hash_code].lock); - return 0; + return p; error: if(p) shm_free(p); - return -1; + return NULL; } int delete_phtable_query(str *pres_uri, int event, str* etag) @@ -572,6 +574,25 @@ int delete_phtable_query(str *pres_uri, int event, str* etag) return 0; } + +void next_turn_phtable(pres_entry_t* p_p, unsigned int hash_code) +{ + pres_entry_t* p; + + lock_get(&pres_htable[hash_code].lock); + for ( p=pres_htable[hash_code].entries->next ; p ; p=p->next ) { + if(p==p_p) { + p->current_turn++; + LM_DBG("xXx - new current turn is %d\n",p->current_turn); + break; + } + } + + lock_release(&pres_htable[hash_code].lock); + return; +} + + int delete_phtable(pres_entry_t* p, unsigned int hash_code) { pres_entry_t* prev_p= NULL; diff --git a/modules/presence/hash.h b/modules/presence/hash.h index d09df1a244e..0f120c4e2c1 100644 --- a/modules/presence/hash.h +++ b/modules/presence/hash.h @@ -127,6 +127,9 @@ typedef struct pres_entry char* sphere; char etag[ETAG_LEN]; int etag_len; + /* ordering */ + unsigned int current_turn; + unsigned int last_turn; struct pres_entry* next; }pres_entry_t; @@ -144,10 +147,12 @@ pres_entry_t* search_phtable_etag(str* pres_uri, int event, void update_pres_etag(pres_entry_t* p, str* etag); -int insert_phtable(str* pres_uri, int event, str* etag, char* sphere); +pres_entry_t* insert_phtable(str* pres_uri, int event, str* etag, char* sphere, int init_turn); int update_phtable(struct presentity* presentity, str pres_uri, str body); +void next_turn_phtable(pres_entry_t* p_p, unsigned int hash_code); + int delete_phtable(pres_entry_t* p, unsigned int hash_code); int delete_phtable_query(str *pres_uri, int event, str* etag); diff --git a/modules/presence/presentity.c b/modules/presence/presentity.c index 227daa6b681..52c22f56904 100644 --- a/modules/presence/presentity.c +++ b/modules/presence/presentity.c @@ -411,6 +411,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, int* sent_r str pres_uri= {NULL, 0}; pres_entry_t* p= NULL; unsigned int hash_code; + unsigned int turn; str body = presentity->body; str *extra_hdrs = presentity->extra_hdrs; db_res_t *result= NULL; @@ -462,6 +463,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, int* sent_r n_query_cols++; result_cols[0] = &str_etag_col; + hash_code= core_hash(&pres_uri, NULL, phtable_size); if(presentity->etag_new) { @@ -473,8 +475,9 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, int* sent_r *sent_reply= 1; /* insert new record in hash_table */ - if(insert_phtable(&pres_uri, presentity->event->evp->parsed, - &presentity->etag, presentity->sphere)< 0) + p = insert_phtable(&pres_uri, presentity->event->evp->parsed, + &presentity->etag, presentity->sphere, 1); + if (p==NULL) { LM_ERR("inserting record in hash table\n"); goto error; @@ -542,14 +545,27 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, int* sent_r } else { - hash_code= core_hash(&pres_uri, NULL, phtable_size); lock_get(&pres_htable[hash_code].lock); - p = search_phtable_etag(&pres_uri, presentity->event->evp->parsed, &presentity->etag, hash_code); + if (p) { + + turn = p->last_turn++; + LM_DBG("xXx - my turn is %d, current turn is %d\n",turn, p->current_turn); + + /* wait to get our turn as order of handling pubishs + (need to wait the ongoing published to terminate + before starting */ + while (p && turn!=p->current_turn) { + lock_release(&pres_htable[hash_code].lock); + sleep_us(100); + lock_get(&pres_htable[hash_code].lock); + p = search_phtable_etag(&pres_uri, presentity->event->evp->parsed, + &presentity->etag, hash_code); + } + + } else { - if(!p) - { lock_release(&pres_htable[hash_code].lock); /* search also in db */ if (pa_dbf.use_table(pa_db, &presentity_table) < 0) @@ -580,7 +596,6 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, int* sent_r goto done; } - pa_dbf.free_result(pa_db, result); LM_INFO("*** found in db but not in htable [%.*s]\n", presentity->etag.len, presentity->etag.s); @@ -644,8 +659,9 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, int* sent_r else { lock_release(&pres_htable[hash_code].lock); - if(insert_phtable(&pres_uri, presentity->event->evp->parsed, - &presentity->etag, presentity->sphere)< 0) + p = insert_phtable(&pres_uri, presentity->event->evp->parsed, + &presentity->etag, presentity->sphere, 1); + if ( p==NULL ) { LM_ERR("inserting record in hash table\n"); goto error; @@ -806,6 +822,10 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, int* sent_r } done: + /* allow next publish to be handled */ + if (p) + next_turn_phtable( p, hash_code); + if (notify_body.s) xmlFree(notify_body.s); @@ -820,6 +840,10 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, int* sent_r return 0; error: + /* allow next publish to be handled */ + if (p) + next_turn_phtable( p, hash_code); + if(result) pa_dbf.free_result(pa_db, result); if(etag.s) @@ -962,7 +986,7 @@ int pres_htable_restore(void) sphere= extract_sphere(body); } - if(insert_phtable(&uri, event, &etag, sphere)< 0) + if(insert_phtable(&uri, event, &etag, sphere, 0)< 0) { LM_ERR("inserting record in presentity hash table"); pkg_free(uri.s); From 1ae4041cd685ccf2b7c57081026c969c3d799069 Mon Sep 17 00:00:00 2001 From: Damien Sandras Date: Mon, 5 Aug 2013 15:58:41 +0200 Subject: [PATCH 2/4] The correct document version number is now set in the NOTIFY requests. There was a locking bug leading to NOTIFY being issued with the same version number. --- modules/presence/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/presence/hash.c b/modules/presence/hash.c index 93b285b3b2c..cc2e9745d63 100644 --- a/modules/presence/hash.c +++ b/modules/presence/hash.c @@ -355,7 +355,7 @@ int update_shtable(shtable_t htable,unsigned int hash_code, else { subs->local_cseq= s->local_cseq++; - s->version= subs->version+ 1; + subs->version= s->version++; } if(strncmp(s->contact.s, subs->contact.s, subs->contact.len)) From c2d545b0932a6c1fd367239dacef466cb74e134e Mon Sep 17 00:00:00 2001 From: Damien Sandras Date: Wed, 7 Aug 2013 10:22:59 +0200 Subject: [PATCH 3/4] Fixed comparison wrt last changes. --- modules/presence/presentity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/presence/presentity.c b/modules/presence/presentity.c index 52c22f56904..c849d92e1a5 100644 --- a/modules/presence/presentity.c +++ b/modules/presence/presentity.c @@ -986,7 +986,7 @@ int pres_htable_restore(void) sphere= extract_sphere(body); } - if(insert_phtable(&uri, event, &etag, sphere, 0)< 0) + if(insert_phtable(&uri, event, &etag, sphere, 0)== NULL) { LM_ERR("inserting record in presentity hash table"); pkg_free(uri.s); From 6293f51787d9aa0c2e56fb2ab0345e781187b293 Mon Sep 17 00:00:00 2001 From: Damien Sandras Date: Wed, 7 Aug 2013 10:43:25 +0200 Subject: [PATCH 4/4] Improved debugging message to make it more useful. --- modules/presence/presentity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/presence/presentity.c b/modules/presence/presentity.c index c849d92e1a5..470524b6cc4 100644 --- a/modules/presence/presentity.c +++ b/modules/presence/presentity.c @@ -551,7 +551,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, int* sent_r if (p) { turn = p->last_turn++; - LM_DBG("xXx - my turn is %d, current turn is %d\n",turn, p->current_turn); + LM_DBG("xXx - %.*s my turn is %d, current turn is %d\n",pres_uri.len, pres_uri.s, turn, p->current_turn); /* wait to get our turn as order of handling pubishs (need to wait the ongoing published to terminate