Skip to content

Commit

Permalink
Merge pull request #34 from dsandras/bi-presence-fixes
Browse files Browse the repository at this point in the history
Bi presence fixes

This is a critical fix ensuring the serial processing of the PUBLISHs for the same presentity. Failing to do so may lead to inconsistent state of the presentity, especially with BLF.
This fix is work on progress for 3 week, tested by Damien.
  • Loading branch information
bogdan-iancu committed Aug 13, 2013
2 parents 3b0b4da + 6293f51 commit 71eea81
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 15 deletions.
29 changes: 25 additions & 4 deletions modules/presence/hash.c
Expand Up @@ -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))
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion modules/presence/hash.h
Expand Up @@ -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;

Expand All @@ -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);

Expand Down
44 changes: 34 additions & 10 deletions modules/presence/presentity.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 71eea81

Please sign in to comment.