[OpenSIPS-News] [NEW] OpenSIPS script locks

Liviu Chircu liviu at opensips.org
Wed Nov 28 16:02:23 CET 2012


The cfgutils module now provides the possibility of defining atomic
test-and-set operations in the OpenSIPS script.
Such need is a result of complex mixing in script of various
functionality / functions from different modules. Like testing
is done based on ratelimit module and the setting is done in
dialog module.

Modules do provide internal locking and synchronization for their
own functionalities, but cannot cover a more complex and various
scenarios of test-and-set scripting scenarios.

Example of scenarios which require atomic test-and-set functionalities:

###########
# Example 1: Counting active outgoing calls with dialog
# The F-URIs of the SIP messages are the same
#
# Suppose there are 0 active calls

get_profile_size("caller", "$fu", "$avp(size)");

if ($avp(size) < 1) {
     xlog("Call allowed!\n");
     set_dlg_profile("caller", "$fu");
     ...
} else {
     xlog("Too many calls!\n");
     ...
}

Possible correct result (profile will have size 1):
Call allowed!
Too many calls!

Possible bad result (profile will have size 2):
Call allowed!
Call allowed!


If two or more processes read the same value from get_profile_size(),
results may be incorrect. By using dynamic script locks, the problem is solved:

get_dynamic_lock("$fu");

get_profile_size("caller", "$fu", "$avp(size)");

if ($avp(size) < 10) {
     xlog("Call allowed!\n");
     set_dlg_profile("caller", "$fu");
     ...
} else {
     xlog("Too many calls!\n");
     ...
}

release_dynamic_lock("$fu");

###########
# Example 2: Counting registered users using cachedb_local
# In this educational example, two users register at the same time
#
# Suppose there are 10 registered users

cache_counter_fetch("local", "registered_users", "$avp(reg_users)");
$avp(reg_users) = $avp(reg_users) + 1;
cache_store("local", "registered_users", "$avp(reg_users)", 1200);

xlog("System has $avp(reg_users) registered users!\n");


Possible correct result:
System has 11 registered users!
System has 12 registered users!

Possible bad result:
System has 11 registered users!
System has 11 registered users!


The same thing as above. A sequence of two operations which should not
be atomic from an internal point of view, but from a logical perspective
it should. In order for the code to work properly, we can use static locks:

get_static_lock("reg_users");

cache_counter_fetch("local", "registered_users", "$avp(reg_users)");
$avp(reg_users) = $avp(reg_users) + 1;
cache_store("local", "registered_users", "$avp(reg_users)", 1200);

release_static_lock("reg_users");

xlog("System has $avp(reg_users) registered users!\n");

-- 
Liviu Chircu
OpenSIPS Dev
http://www.opensips-solutions.com







More information about the News mailing list