diff --git a/modules/presence/hash.c b/modules/presence/hash.c index e520029a14d..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)) @@ -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..470524b6cc4 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 - %.*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 + 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)== NULL) { LM_ERR("inserting record in presentity hash table"); pkg_free(uri.s);