From 38b7f7b4a474cfb9cd79acd09515a84d0e6d746b Mon Sep 17 00:00:00 2001
From: Mark Spencer <markster@digium.com>
Date: Wed, 18 May 2005 01:49:13 +0000
Subject: [PATCH] Add optional call limit

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5712 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 asterisk.8.gz              | Bin 2458 -> 2547 bytes
 asterisk.c                 |  12 +++++++++++-
 asterisk.sgml              |  11 +++++++++++
 cli.c                      |   7 ++++++-
 include/asterisk/options.h |   1 +
 include/asterisk/pbx.h     |   3 +++
 pbx.c                      |  33 ++++++++++++++++++++++++++++++++-
 7 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/asterisk.8.gz b/asterisk.8.gz
index abbd0c45312bcbb54d0220a7c64661cf50b7f7b3..d05b828286821f76e2b02f98eac700d760fae784 100755
GIT binary patch
delta 2534
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

delta 2431
zcmV-_34r$V6Pgo$ABzYGJxDP^00UujbY*gBb89X*0Nq&MZyUK0e&4@>@I%ij^dpIJ
zKoJDN$+i#+jcq|vd?}hfP`lJF&%5M?<Vsc_`nUI+;qFS7eZ9vPeMr0_Im6-1H{T37
z`hF%>h4!M7rk1%9h4f;rlo7HCwvs`ovMl!^S4KG*R3_Gcdy(06ZSCWG$cSVF3L9rD
zA;q;#FELK@O{Gj2iKshRTZ$Bm*Gg<`V=^Jb2NwKTgiwDNkA0!aa-?fpYNJM}t;YXS
zWu;sg<GUVr8-5#qiW|;LCA|_}kuI|r>n0aY)z$?+5W1?J-72yGzo4M~s%1zEg%4Jt
zLOOzFVj0wbR*9=ZnOuDI^y8O2*F&iIO{HOEUH)m5j8-?|Y_eQU7qjJG&&1hZ@bBF_
zaVuR~i1%;b{*2!e!cO}~@ow}MKhKh6w7d~_liO+1PkkSXNm&l-#?=<~2UV)NusDEM
zZmZmgMV5cNyPq#-%Ov@}x$H#0Zx-V30t3UaDmK}F_Tfjp$Wv`-{2%Si75<-XbgA&;
zc>F7kH`wB2{4<T`&NlVQ#1l=B<D|*DspOeCV(1PQZU0!7&UJP@U0y9_^VRJB?kpM2
z=cnfbRHWE6aL`7{&^Vy&)I(xd=(I>Ez&cZ2%$?o>mg3S$gHWh%X(0+=d_KSY_GTbv
z2HItR8Z<)uV0Eg*LiySn`2KwMuy`{_CK2Y?>Iy&?*V+fC*G<sYi1W$SHIzg_OS{kJ
z;{3tR=5Is}nVsBglLJpz)@+nhCgq=!Kq=}{g~B>1>_*s7K=^PLS=S{Ji#DO`!0NTL
zGD{rW4uQkcOl`5d7uuv{lR-aVoIa``wrtgZ`EoYLF(=;!;`Z|uK9`T$nEfER8C|@;
zc+-oYuVI5gy3|%98Q4ZR@kuL>6C&q#NI?1<oXj*CCQGrpzD)}0vYmA5$bi+mftcdo
zY<Ybr=8M@td|nJM-d+sE;&M3<U#zWtkS<`{QMSh)2`|5-<+OQ4X<J#RMvR0>hbyOl
zWCk{}K9C<YOikfjoi~o%B?#U=63#0VNoi9KrZ!@X3?Fy!0u?=I7aArr$w#e`-kzOZ
zz~{AU_1I0Hu0OrL`7<WNMkMcLg@8X_p73%eL0atqGx~$|l>1Q^ARnof>{_e6g-X_!
z!lG!L_6ZR!v2*m*uiz@-8e=FJJB_$XQr@M=paFkzW?~=uUf?^iH6v{xdN2Ei5U42M
zYP(YoNhjKz6-2><qj0z52{AD+3QdEUg@_^9EWj)op}4X}2kSgX3PBGFkuH<V0~!MO
z*OTW1B7aHG?wM?sV4D@Q%_&7DUlECZWI+i~ar9pae4+|wWY$3@QybZoK>0JE9S}zv
z`h6)n$vm<ae1W;(s3_u47PzqyMO16a<<I~J$#Rq|fl|HM^B|Sd7)mN}96nOLVZ-6N
zoi3@&A{>W;1E&}ZAAwgKf$x!kk*OdNK29RuHh)@kvUO*AMy5}VT*FTFgqT4d^){!~
z6y;cG59`UE<eK&hukQGtcgsn7p(@ZVxWL=Sf#phF=|E0O2^C)d695WD<4Hep?g7|1
zZ`M?G!VBBnY)q*i6`(@cVp@@?COMhiMwjA9X38}>2<Xq*B$#t|znXsF(qx3U6-CG^
zAAdv9q92KZ#DF6BC*f?QJ-O^2<>6=g-jp&wa@1-0O%{zI1oF_)9PNILyrhE(&x2o%
z3T4xr`q5~34|%>uh)mF6^BrQ5z(26rH=JC^rOAQnl-X)$3b}>5z?x#?Jvj(cJEwz6
z=xC9++AT6>G)nlML65nkv^h0o%;Hs*cz;W!YY_9g3t1+ET*IvcZpnJ@6vr8}26b#;
zHkiom$qL701wzQV-;4~>Vk)SEF5T*?>OgGe=s=pi0w{3<iQ4V<HC2wf?I<4A-UCan
zg*j?ReNbo^<JxmlOzxI57*rDVF@2H8T3}PPsCgBP&a|&f*(Nh{RI84HoXj>%%YQ&%
z?6Qx_5}ClXCeE27pH$lLD8l5d3g}~Gz%-7Blc6-kvVdAz1`5>TOcwFm$6(>8)IDb%
zH=}bRC!qa^y%8wcDDPQEn?iklp=UrlftUh2Gy$eo)J=6w4s~X^la=oal<f<oLdv8C
zHTeC(f5dFhnzZNB11C12ZURcpQGd15L;>cv#&E@83zKerWdW4)j%?o?HgW9TLke}u
zq%dmt>d|^vLbpMikZ_OI$(>4c&D4S0*&a>3=SHR~A+H~^o(>1&xIo`FAV(spzJ7oI
z6Y~0h%w{pky4JAVBda&vRxL$514`0u1Uf3w%{?>GsaBE!DLoe``g`#f%zuoz?1&}<
zc_{Wgm~zZ3%t3=lN}Nj=acCL23y^{~LhA~uC~V0B8MrD%a{{}G#Ejqq!;*dHu%Uz%
z+(9z9Xjx{D;kqJI-~~Zh1yZPL?%q*$jWxrLlbkBK2W<hITTXb}m0EIivU}0P;d-&A
zz7QJ5a0-|+e<^n`<>XG+)qf6Vw|?e#D+f*gzZQ;dO!r7~EK!1$OL9T$V`jIm<!T)p
zyYz~?P6}?XiU91n3)3o#7VxSrUQE+5(%S!58@AQae$<?x`q;ide}y@FvPsC8o{Ty_
zKD0HCN*0}#1FB8D$k2BzMQF@)RjEt^^X2{!hL`UEbWP@@|6^u~6@M-=Q%ovcr{u{M
zrIr90@doO58-Y-uCCUrhf#93r@=8-&-8k*L=77_V2iToaZCh8l&*Zxf-`-|1bbTp_
za-F*f9@Od5l|`o-H<F~iTxIPYWcqD#JO46WzWU@b6qgEle(-{%J6R^t0GreGVz}LI
z^E8T4zO$h(k?>N^J%5QaU)Y_X*Ab&ie-@Q=(d~vwV;7hB-V%>+`So*a{^jAJjRVy_
z)NodV5&N!~a-E*}MEk&p3xgkJI@e7_&wEkrayk{0FU$L=`p;KiW}nEfg(~Z4-wM9S
zrrtYP@_a3y>iCKn1(!73-VBdtS-3T6x7&^S%bImL#8$@@?0<&({W)&kzbBO0)W0Tp
z-9CTDESblL#8V|(tLq_U6KNRl^rIg33QqL>ipf*)gDb~aez@0D|3)Phq3K_4T0FW_
z9q6SWQS4r7kqW(B{X~yKYw%MWt;yHb&HW<A>K38`REN&diI1d+WPdqW^@*2V*#>uX
xW?Oy%W3<xi8YI|c0E8)VwU}PdR?Emo+418Wm4_<c;(E$S{tAru8mO-p005oWxN`si

diff --git a/asterisk.c b/asterisk.c
index f42193fe30..308519ba27 100755
--- a/asterisk.c
+++ b/asterisk.c
@@ -87,6 +87,7 @@ int option_timestamp = 0;
 int option_overrideconfig = 0;
 int option_reconnect = 0;
 int option_transcode_slin = 1;
+int option_maxcalls = 0;
 int fully_booted = 0;
 char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR;
 char debug_filename[AST_FILENAME_MAX] = "";
@@ -1658,6 +1659,11 @@ static void ast_readconfig(void) {
 		/* Build transcode paths via SLINEAR, instead of directly */
 		} else if (!strcasecmp(v->name, "transcode_via_sln")) {
 			option_transcode_slin = ast_true(v->value);
+		} else if (!strcasecmp(v->name, "maxcalls")) {
+			if ((sscanf(v->value, "%d", &option_maxcalls) != 1) ||
+			    (option_maxcalls < 0)) {
+				option_maxcalls = 0;
+			}
 		}
 		v = v->next;
 	}
@@ -1711,7 +1717,7 @@ int main(int argc, char *argv[])
 	}
 	*/
 	/* Check for options */
-	while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:")) != -1) {
+	while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:M:")) != -1) {
 		switch(c) {
 		case 'd':
 			option_debug++;
@@ -1743,6 +1749,10 @@ int main(int argc, char *argv[])
 			option_verbose++;
 			option_nofork++;
 			break;
+		case 'M':
+			if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0))
+				option_maxcalls = 0;
+			break;
 		case 'q':
 			option_quiet++;
 			break;
diff --git a/asterisk.sgml b/asterisk.sgml
index b84ad0020a..abee2e6787 100755
--- a/asterisk.sgml
+++ b/asterisk.sgml
@@ -26,6 +26,7 @@
 <arg><option>-U </option><replaceable class="parameter">user</replaceable></arg>
 <arg><option>-G </option><replaceable class="parameter">group</replaceable></arg>
 <arg><option>-x </option><replaceable class="parameter">command</replaceable></arg>
+<arg><option>-M </option><replaceable class="parameter">value</replaceable></arg>
 	</cmdsynopsis>
 	<cmdsynopsis>
 
@@ -141,6 +142,16 @@
 			</para>
 		</listitem>
 	</varlistentry>
+	<varlistentry>
+		<term>-M <replaceable class="parameter">value</replaceable></term>
+		<listitem>
+			<para>
+			Limits the maximum number of calls to the specified value.  This can
+			be useful to prevent a system from being brought down by terminating
+			too many simultaneous calls.
+			</para>
+		</listitem>
+	</varlistentry>
 	<varlistentry>
 		<term>-n</term>
 		<listitem>
diff --git a/cli.c b/cli.c
index 141ac09ae7..80150eefed 100755
--- a/cli.c
+++ b/cli.c
@@ -429,8 +429,13 @@ static int handle_chanlist(int fd, int argc, char *argv[])
 		ast_mutex_unlock(&c->lock);
 		c = ast_channel_walk_locked(c);
 	}
-	if(!concise)
+	if(!concise) {
 		ast_cli(fd, "%d active channel(s)\n", numchans);
+		if (option_maxcalls)
+			ast_cli(fd, "%d of %d max active call(s) (%5.2f%% of capacity)\n", ast_active_calls(), option_maxcalls, ((float)ast_active_calls() / (float)option_maxcalls) * 100.0);
+		else
+			ast_cli(fd, "%d active call(s)\n", ast_active_calls());
+	}
 	return RESULT_SUCCESS;
 }
 
diff --git a/include/asterisk/options.h b/include/asterisk/options.h
index 598ea31db0..9d962bbe5a 100755
--- a/include/asterisk/options.h
+++ b/include/asterisk/options.h
@@ -33,6 +33,7 @@ extern int option_exec_includes;
 extern int option_cache_record_files;
 extern int option_timestamp;
 extern int option_transcode_slin;
+extern int option_maxcalls;
 extern char defaultlanguage[];
 extern time_t ast_startuptime;
 extern time_t ast_lastreloadtime;
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
index 19331acff3..b0f92b60a5 100755
--- a/include/asterisk/pbx.h
+++ b/include/asterisk/pbx.h
@@ -602,6 +602,9 @@ int ast_async_goto_if_exists(struct ast_channel *chan, char* context, char *exte
 struct ast_custom_function* ast_custom_function_find(char *name);
 int ast_custom_function_unregister(struct ast_custom_function *acf);
 int ast_custom_function_register(struct ast_custom_function *acf);
+
+/* Number of active calls */
+int ast_active_calls(void);
 	
 /*! executes a read operation on a function */
 /*!
diff --git a/pbx.c b/pbx.c
index ebadafd361..803c3fca47 100755
--- a/pbx.c
+++ b/pbx.c
@@ -213,6 +213,9 @@ static struct varshead globals;
 
 static int autofallthrough = 0;
 
+AST_MUTEX_DEFINE_STATIC(maxcalllock);
+static int countcalls = 0;
+
 AST_MUTEX_DEFINE_STATIC(acflock); 		/* Lock for the custom function list */
 static struct ast_custom_function *acf_root = NULL;
 
@@ -2232,7 +2235,7 @@ int ast_exec_extension(struct ast_channel *c, const char *context, const char *e
 	return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXEC);
 }
 
-int ast_pbx_run(struct ast_channel *c)
+static int __ast_pbx_run(struct ast_channel *c)
 {
 	int firstpass = 1;
 	char digit;
@@ -2497,6 +2500,34 @@ int ast_pbx_start(struct ast_channel *c)
 	return 0;
 }
 
+int ast_pbx_run(struct ast_channel *c)
+{
+	int res = 0;
+	ast_mutex_lock(&maxcalllock);
+	if (option_maxcalls) {
+		if (countcalls >= option_maxcalls) {
+			ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name);
+			res = -1;
+		}
+	}
+	if (!res)
+		countcalls++;	
+	ast_mutex_unlock(&maxcalllock);
+	if (!res) {
+		res = __ast_pbx_run(c);
+		ast_mutex_lock(&maxcalllock);
+		if (countcalls > 0)
+			countcalls--;
+		ast_mutex_unlock(&maxcalllock);
+	}
+	return res;
+}
+
+int ast_active_calls(void)
+{
+	return countcalls;
+}
+
 int pbx_set_autofallthrough(int newval)
 {
 	int oldval;
-- 
GitLab