diff options
author | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-08-14 03:26:02 +0000 |
---|---|---|
committer | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-08-14 03:26:02 +0000 |
commit | 488a3ac4dcef5cfc8ed1aec91601891f82c3a145 (patch) | |
tree | 64fee52151802eae15224d830efc8f521dcb9e3c /doc/macroexclusive.txt | |
parent | 19758a4ffd5da144f993d1c9da1fb3fba7977275 (diff) |
add the doc file about the MacroExclusive app (issue #7366, Steve Davies)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@39683 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'doc/macroexclusive.txt')
-rw-r--r-- | doc/macroexclusive.txt | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/doc/macroexclusive.txt b/doc/macroexclusive.txt new file mode 100644 index 000000000..3a3111493 --- /dev/null +++ b/doc/macroexclusive.txt @@ -0,0 +1,78 @@ +About the MacroExclusive application +------------------------------------ + +Steve Davies <steve@connection-telecom.com + + +The MacroExclusive application was added to solve the problem of +synchronisation between calls running at the same time. + +This is usually an issue when you have calls manipulating global +variables or the Asterisk database, but may be useful elsewhere. + +Consider this example macro, intended to return a "next" number - +each caller is intended to get a different number: + +[macro-next] +exten => s,1,Set(RESULT=${COUNT}) +exten => s,n,SetGlobalVar(COUNT=$[${COUNT} + 1]) + +The problem is that in a box with high activity, you can be sure +that two calls will come along together - both will get the same +"RESULT", or the "COUNT" value will get mangled. + +Calling this Macro via MacroExclusive will use a mutex to make sure +that only one call executes in the Macro at a time. This ensures +that the two lines execute as a unit. + +Note that even the s,2 line above has its own race problem. Two +calls running that line at once will step on each other and +the count will end up as +1 rather than +2. + +I've also been able to use MacroExclusive where I have two Macros +that need to be mutually exclusive. + +Here's the example: + +[macro-push] +; push value ${ARG2} onto stack ${ARG1} +exten => s,1,Set(DB(STACK/${ARG1})=${ARG2}^${DB(STACK/${ARG1})}) + +[macro-pop] +; pop top value from stack ${ARG1} +exten => s,1,Set(RESULT=${DB(STACK/${ARG1})}) +exten => s,n,Set(DB(STACK/${ARG1})=${CUT(RESULT,^,2)}) +exten => s,n,Set(RESULT=${CUT(RESULT,^,1)}) + +All that futzing with the STACK/${ARG1} in the astdb needs protecting +if this is to work. But neither push nor pop can run together. + +So add this "pattern": + +[macro-stack] +exten => Macro(${ARG1},${ARG2},${ARG3}) + +... and use it like so: + +exten => s,1,MacroExclusive(stack,push,MYSTACK,bananas) +exten => s,n,MacroExclusive(stack,push,MYSTACK,apples) +exten => s,n,MacroExclusive(stack,push,MYSTACK,guavas) +exten => s,n,MacroExclusive(stack,push,MYSTACK,pawpaws) +exten => s,n,MacroExclusive(stack,pop,MYSTACK) ; RESULT gets pawpaws (yum) +exten => s,n,MacroExclusive(stack,pop,MYSTACK) ; RESULT gets guavas +exten => s,n,MacroExclusive(stack,pop,MYSTACK) ; RESULT gets apples +exten => s,n,MacroExclusive(stack,pop,MYSTACK) ; RESULT gets bananas + +We get to the push and pop macros "via" the stack macro. But only one call +can execute the stack macro at a time; ergo, only one of push OR pop can +run at a time. + +Hope people find this useful. + +Lastly, its worth pointing out that only Macros that access shared data +will require this MacroExclusive protection. And Macro's that you call +with macroExclusive should run quickly or you will clog up your Asterisk +system. + +Regards, +Steve |