[asterisk-commits] russell: branch russell/events r84142 - in /team/russell/events/res: ./ ais/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Sep 29 22:00:40 CDT 2007


Author: russell
Date: Sat Sep 29 22:00:40 2007
New Revision: 84142

URL: http://svn.digium.com/view/asterisk?view=rev&rev=84142
Log:
Various bits of code cleanup and more code toward exposing the distributed
locks service with dialplan functions (still not complete)

Modified:
    team/russell/events/res/ais/clm.c
    team/russell/events/res/ais/evt.c
    team/russell/events/res/ais/lck.c
    team/russell/events/res/res_ais.c

Modified: team/russell/events/res/ais/clm.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/res/ais/clm.c?view=diff&rev=84142&r1=84141&r2=84142
==============================================================================
--- team/russell/events/res/ais/clm.c (original)
+++ team/russell/events/res/ais/clm.c Sat Sep 29 22:00:40 2007
@@ -71,9 +71,10 @@
 
 static char *ais_clm_show_members(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	int i, res;
+	int i;
 	SaClmClusterNotificationBufferT buf;
 	SaClmClusterNotificationT notif[64];
+	SaAisErrorT ais_res;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -93,8 +94,8 @@
 	buf.notification = notif;
 	buf.numberOfItems = ARRAY_LEN(notif);
 
-	res = saClmClusterTrack(clm_handle, SA_TRACK_CURRENT, &buf);
-	if (res != SA_AIS_OK) {
+	ais_res = saClmClusterTrack(clm_handle, SA_TRACK_CURRENT, &buf);
+	if (ais_res != SA_AIS_OK) {
 		ast_cli(a->fd, "Error retrieving current cluster members.\n");
 		return CLI_FAILURE;
 	}
@@ -133,30 +134,30 @@
 
 int ast_ais_clm_load_module(void)
 {
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 
-	res = saClmInitialize(&clm_handle, &clm_callbacks, &ais_version);
-	if (res != SA_AIS_OK) {
+	ais_res = saClmInitialize(&clm_handle, &clm_callbacks, &ais_version);
+	if (ais_res != SA_AIS_OK) {
 		ast_log(LOG_ERROR, "Could not initialize cluster membership service: %s\n",
-			ais_err2str(res));
-		return AST_MODULE_LOAD_DECLINE;
+			ais_err2str(ais_res));
+		return -1;
 	}
 
 	ast_cli_register_multiple(ais_cli, ARRAY_LEN(ais_cli));
 
-	return AST_MODULE_LOAD_SUCCESS;
+	return 0;
 }
 
 int ast_ais_clm_unload_module(void)
 {
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 
 	ast_cli_unregister_multiple(ais_cli, ARRAY_LEN(ais_cli));
 
-	res = saClmFinalize(clm_handle);
-	if (res != SA_AIS_OK) {
+	ais_res = saClmFinalize(clm_handle);
+	if (ais_res != SA_AIS_OK) {
 		ast_log(LOG_ERROR, "Problem stopping cluster membership service: %s\n", 
-			ais_err2str(res));
+			ais_err2str(ais_res));
 		return -1;
 	}
 

Modified: team/russell/events/res/ais/evt.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/res/ais/evt.c?view=diff&rev=84142&r1=84141&r2=84142
==============================================================================
--- team/russell/events/res/ais/evt.c (original)
+++ team/russell/events/res/ais/evt.c Sat Sep 29 22:00:40 2007
@@ -139,7 +139,7 @@
 	 * should get changed to a thread-local buffer, instead. */
 	static unsigned char buf[4096];
 	struct ast_event *event_dup, *event = (void *) buf;
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 	SaSizeT len = sizeof(buf);
 
 	if (event_datalen > len) {
@@ -149,10 +149,10 @@
 		return;
 	}
 
-	res = saEvtEventDataGet(event_handle, event, &len);
-	if (res != SA_AIS_OK) {
+	ais_res = saEvtEventDataGet(event_handle, event, &len);
+	if (ais_res != SA_AIS_OK) {
 		ast_log(LOG_ERROR, "Error retrieving event payload: %s\n", 
-			ais_err2str(res));
+			ais_err2str(ais_res));
 		return;
 	}
 
@@ -187,7 +187,7 @@
 static void ast_event_cb(const struct ast_event *ast_event, void *data)
 {
 	SaEvtEventHandleT event_handle;
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 	struct event_channel *event_channel = data;
 	SaClmClusterNodeT local_node;
 	SaEvtEventPatternArrayT pattern_array;
@@ -204,17 +204,17 @@
 		return;
 	}
 
-	res = saEvtEventAllocate(event_channel->handle, &event_handle);
-	if (res != SA_AIS_OK) {
-		ast_log(LOG_ERROR, "Error allocating event: %s\n", ais_err2str(res));
+	ais_res = saEvtEventAllocate(event_channel->handle, &event_handle);
+	if (ais_res != SA_AIS_OK) {
+		ast_log(LOG_ERROR, "Error allocating event: %s\n", ais_err2str(ais_res));
 		ast_log(LOG_DEBUG, "Returning here\n");
 		return;
 	}
 	
-	res = saClmClusterNodeGet(clm_handle, SA_CLM_LOCAL_NODE_ID, 
+	ais_res = saClmClusterNodeGet(clm_handle, SA_CLM_LOCAL_NODE_ID, 
 		SA_TIME_ONE_SECOND, &local_node);
-	if (res != SA_AIS_OK) {
-		ast_log(LOG_ERROR, "Error getting local node name: %s\n", ais_err2str(res));
+	if (ais_res != SA_AIS_OK) {
+		ast_log(LOG_ERROR, "Error getting local node name: %s\n", ais_err2str(ais_res));
 		goto return_event_free;
 	}
 
@@ -232,24 +232,24 @@
 	 * /todo Make retention time configurable 
 	 * /todo Make event priorities configurable
 	 */
-	res = saEvtEventAttributesSet(event_handle, &pattern_array,
+	ais_res = saEvtEventAttributesSet(event_handle, &pattern_array,
 		SA_EVT_LOWEST_PRIORITY, SA_TIME_ONE_MINUTE, &local_node.nodeName);
-	if (res != SA_AIS_OK) {
-		ast_log(LOG_ERROR, "Error setting event attributes: %s\n", ais_err2str(res));
+	if (ais_res != SA_AIS_OK) {
+		ast_log(LOG_ERROR, "Error setting event attributes: %s\n", ais_err2str(ais_res));
 		goto return_event_free;
 	}
 
-	res = saEvtEventPublish(event_handle, 
+	ais_res = saEvtEventPublish(event_handle, 
 		ast_event, ast_event_get_size(ast_event), &event_id);
-	if (res != SA_AIS_OK) {
-		ast_log(LOG_ERROR, "Error publishing event: %s\n", ais_err2str(res));
+	if (ais_res != SA_AIS_OK) {
+		ast_log(LOG_ERROR, "Error publishing event: %s\n", ais_err2str(ais_res));
 		goto return_event_free;
 	}
 
 return_event_free:
-	res = saEvtEventFree(event_handle);
-	if (res != SA_AIS_OK) {
-		ast_log(LOG_ERROR, "Error freeing allocated event: %s\n", ais_err2str(res));
+	ais_res = saEvtEventFree(event_handle);
+	if (ais_res != SA_AIS_OK) {
+		ast_log(LOG_ERROR, "Error freeing allocated event: %s\n", ais_err2str(ais_res));
 	}
 	ast_log(LOG_DEBUG, "Returning here (event_free)\n");
 }
@@ -345,7 +345,7 @@
 static SaAisErrorT set_egress_subscription(struct event_channel *event_channel,
 	struct subscribe_event *subscribe_event)
 {
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 	SaEvtEventFilterArrayT filter_array;
 	SaEvtEventFilterT filter;
 	const char *filter_str = NULL;
@@ -363,10 +363,10 @@
 	filter_array.filtersNumber = 1;
 	filter_array.filters = &filter;
 
-	res = saEvtEventSubscribe(event_channel->handle, &filter_array, 
+	ais_res = saEvtEventSubscribe(event_channel->handle, &filter_array, 
 		subscribe_event->id);
 
-	return res;
+	return ais_res;
 }
 
 static void add_subscribe_event(struct event_channel *event_channel, const char *event_type)
@@ -374,7 +374,7 @@
 	int i;
 	enum ast_event_type type = -1;
 	struct subscribe_event *subscribe_event;
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 
 	for (i = 0; i < ARRAY_LEN(supported_event_types); i++) {
 		if (!strcasecmp(event_type, supported_event_types[i].str)) {
@@ -394,10 +394,10 @@
 	subscribe_event->type = type;
 	subscribe_event->id = ast_atomic_fetchadd_int(&unique_id, +1);
 
-	res = set_egress_subscription(event_channel, subscribe_event);
-	if (res != SA_AIS_OK) {
+	ais_res = set_egress_subscription(event_channel, subscribe_event);
+	if (ais_res != SA_AIS_OK) {
 		ast_log(LOG_ERROR, "Error setting up egress subscription: %s\n",
-			ais_err2str(res));
+			ais_err2str(ais_res));
 		free(subscribe_event);
 		return;
 	}
@@ -409,7 +409,7 @@
 {
 	struct ast_variable *var;
 	struct event_channel *event_channel;
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 	SaNameT sa_name = { 0, };
 
 	AST_RWLIST_WRLOCK(&event_channels);
@@ -430,11 +430,11 @@
 	strcpy(event_channel->name, cat);
 	ast_copy_string((char *) sa_name.value, cat, sizeof(sa_name.value));
 	sa_name.length = strlen((char *) sa_name.value);
-	res = saEvtChannelOpen(evt_handle, &sa_name, 
+	ais_res = saEvtChannelOpen(evt_handle, &sa_name, 
 		SA_EVT_CHANNEL_PUBLISHER | SA_EVT_CHANNEL_SUBSCRIBER | SA_EVT_CHANNEL_CREATE,
 		SA_TIME_MAX, &event_channel->handle);
-	if (res != SA_AIS_OK) {
-		ast_log(LOG_ERROR, "Error opening event channel: %s\n", ais_err2str(res));
+	if (ais_res != SA_AIS_OK) {
+		ast_log(LOG_ERROR, "Error opening event channel: %s\n", ais_err2str(ais_res));
 		free(event_channel);
 		return;
 	}
@@ -500,13 +500,13 @@
 static void subscribe_event_destroy(const struct event_channel *event_channel,
 	struct subscribe_event *subscribe_event)
 {
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 
 	/* saEvtChannelClose() will actually do this automatically, but it just
 	 * feels cleaner to go ahead and do it manually ... */
-	res = saEvtEventUnsubscribe(event_channel->handle, subscribe_event->id);
-	if (res != SA_AIS_OK) {
-		ast_log(LOG_ERROR, "Error unsubscribing: %s\n", ais_err2str(res));
+	ais_res = saEvtEventUnsubscribe(event_channel->handle, subscribe_event->id);
+	if (ais_res != SA_AIS_OK) {
+		ast_log(LOG_ERROR, "Error unsubscribing: %s\n", ais_err2str(ais_res));
 	}
 
 	free(subscribe_event);
@@ -516,17 +516,17 @@
 {
 	struct publish_event *publish_event;
 	struct subscribe_event *subscribe_event;
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 
 	while ((publish_event = AST_LIST_REMOVE_HEAD(&event_channel->publish_events, entry)))
 		publish_event_destroy(publish_event);
 	while ((subscribe_event = AST_LIST_REMOVE_HEAD(&event_channel->subscribe_events, entry)))
 		subscribe_event_destroy(event_channel, subscribe_event);
 
-	res = saEvtChannelClose(event_channel->handle);
-	if (res != SA_AIS_OK) {
+	ais_res = saEvtChannelClose(event_channel->handle);
+	if (ais_res != SA_AIS_OK) {
 		ast_log(LOG_ERROR, "Error closing event channel '%s': %s\n",
-			event_channel->name, ais_err2str(res));
+			event_channel->name, ais_err2str(ais_res));
 	}
 
 	free(event_channel);
@@ -544,35 +544,35 @@
 
 int ast_ais_evt_load_module(void)
 {
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 
 	ast_set_eid(&g_eid);
 	ast_eid_to_str(g_eid_str, sizeof(g_eid_str), &g_eid);
 
-	res = saEvtInitialize(&evt_handle, &evt_callbacks, &ais_version);
-	if (res != SA_AIS_OK) {
+	ais_res = saEvtInitialize(&evt_handle, &evt_callbacks, &ais_version);
+	if (ais_res != SA_AIS_OK) {
 		ast_log(LOG_ERROR, "Could not initialize eventing service: %s\n",
-			ais_err2str(res));
-		return AST_MODULE_LOAD_DECLINE;
+			ais_err2str(ais_res));
+		return -1;
 	}
 	
 	load_config();
 
 	ast_cli_register_multiple(ais_cli, ARRAY_LEN(ais_cli));
 
-	return AST_MODULE_LOAD_SUCCESS;
+	return 0;
 }
 
 int ast_ais_evt_unload_module(void)
 {
-	SaAisErrorT res;
+	SaAisErrorT ais_res;
 
 	destroy_event_channels();
 
-	res = saEvtFinalize(evt_handle);
-	if (res != SA_AIS_OK) {
+	ais_res = saEvtFinalize(evt_handle);
+	if (ais_res != SA_AIS_OK) {
 		ast_log(LOG_ERROR, "Problem stopping eventing service: %s\n", 
-			ais_err2str(res));
+			ais_err2str(ais_res));
 		return -1;
 	}
 

Modified: team/russell/events/res/ais/lck.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/res/ais/lck.c?view=diff&rev=84142&r1=84141&r2=84142
==============================================================================
--- team/russell/events/res/ais/lck.c (original)
+++ team/russell/events/res/ais/lck.c Sat Sep 29 22:00:40 2007
@@ -44,9 +44,18 @@
 #include "asterisk/utils.h"
 #include "asterisk/cli.h"
 #include "asterisk/logger.h"
+#include "asterisk/pbx.h"
+#include "asterisk/app.h"
 
 SaLckHandleT lck_handle;
 
+/*!
+ * \brief Callbacks available in the Lock Service
+ *
+ * None of these are actually required if only synchronous locking is used.
+ * However, some of them must be implemented should the asynchronous locks
+ * be used.
+ */
 static SaLckCallbacksT lck_callbacks = {
 	/*! Get notified when a cluster-wide lock gets created */
 	.saLckResourceOpenCallback =   NULL,
@@ -58,6 +67,13 @@
 	.saLckResourceUnlockCallback = NULL,
 };
 
+enum lock_type {
+	RDLOCK,
+	WRLOCK,
+	TRY_RDLOCK,
+	TRY_WRLOCK,
+};
+
 static struct ao2_container * attribute_unused lock_resources;
 
 struct lock_resource {
@@ -66,28 +82,193 @@
 	char name[1];
 };
 
+static int handle_lock(struct ast_channel *chan, enum lock_type lock_type,
+	char *data, char *buf, size_t len)
+{
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(name);
+		AST_APP_ARG(timeout);
+	);
+	int res = 0;
+	double timeout = 3;
+
+	ast_autoservice_start(chan);
+
+	AST_STANDARD_APP_ARGS(args, data);
+	if (ast_strlen_zero(args.name)) {
+		ast_log(LOG_ERROR, "The DLOCK functions require a lock name\n");
+		res = -1;
+		goto return_cleanup;
+	}
+	switch (lock_type) {
+	case RDLOCK:
+	case WRLOCK:
+		if (!ast_strlen_zero(args.timeout) && ((timeout = atof(args.timeout)) < 0)) {
+			ast_log(LOG_ERROR, "Timeout value '%s' not valid\n", args.timeout);
+			res = -1;
+			goto return_cleanup;
+		}
+		break;
+	case TRY_RDLOCK:
+	case TRY_WRLOCK:
+		if (!ast_strlen_zero(args.timeout)) {
+			ast_log(LOG_ERROR, "The trylock functions only take one argument\n");
+			res = -1;
+			goto return_cleanup;
+		}
+	}
+
+
+
+return_cleanup:
+	ast_autoservice_stop(chan);
+
+	return 0;
+}
+
+static int handle_rdlock(struct ast_channel *chan, const char *cmd, char *data,
+	char *buf, size_t len)
+{
+	return handle_lock(chan, RDLOCK, data, buf, len);
+}
+
+static int handle_wrlock(struct ast_channel *chan, const char *cmd, char *data,
+	char *buf, size_t len)
+{
+	return handle_lock(chan, WRLOCK, data, buf, len);
+}
+
+static int handle_tryrdlock(struct ast_channel *chan, const char *cmd, char *data,
+	char *buf, size_t len)
+{
+	return handle_lock(chan, TRY_RDLOCK, data, buf, len);
+}
+
+static int handle_trywrlock(struct ast_channel *chan, const char *cmd, char *data,
+	char *buf, size_t len)
+{
+	return handle_lock(chan, TRY_WRLOCK, data, buf, len);
+}
+
+static int handle_unlock(struct ast_channel *chan, const char *cmd, char *data,
+	char *buf, size_t len)
+{
+
+	return -1;
+}
+
+static struct ast_custom_function dlock_rdlock = {
+	.name = "DLOCK_RDLOCK",
+	.synopsis = "Read-lock a distributed lock",
+	.desc = 
+"  This function will read-lock a distributed lock provided by the locking\n"
+"service of AIS.  This is a blocking operation.  However, a timeout can be\n"
+"specified to avoid deadlocks.  The default timeout used if one is not\n"
+"provided as an argument is 3 seconds.\n"
+"  The name of the lock can be anything.  The first time a named lock gets\n"
+"used, it will be automatically created and maintained amongst the cluster.\n"
+"  The result of this function will be one of the following:\n"
+"     SUCCESS | TIMEOUT | FAILURE\n"
+"",
+	.syntax = "DLOCK_RDLOCK(<lock_name>,[timeout])",
+	.read = handle_rdlock,
+};
+
+static struct ast_custom_function dlock_wrlock = {
+	.name = "DLOCK_WRLOCK",
+	.synopsis = "Write-lock a distributed lock",
+	.desc = 
+"  This function will write-lock a distributed lock provided by the locking\n"
+"service of AIS.  This is a blocking operation.  However, a timeout can be\n"
+"specified to avoid deadlocks.  The default timeout used if one is not\n"
+"provided as an argument is 3 seconds.\n"
+"  The name of the lock can be anything.  The first time a named lock gets\n"
+"used, it will be automatically created and maintained amongst the cluster.\n"
+"  The result of this function will be one of the following:\n"
+"     SUCCESS | TIMEOUT | FAILURE\n"
+"",
+	.syntax = "DLOCK_WRLOCK(<lock_name>,[timeout])",
+	.read = handle_wrlock,
+};
+
+static struct ast_custom_function dlock_tryrdlock = {
+	.name = "DLOCK_TRYRDLOCK",
+	.synopsis = "Try to read-lock a distributed lock",
+	.desc =
+"  This function will attempt to read-lock a distributed lock provided by the\n"
+"locking service of AIS.  This is a non-blocking operation.\n"
+"  The name of the lock can be anything.  The first time a named lock gets\n"
+"used, it will be automatically created and maintained amongst the cluster.\n"
+"  The result of this function will be one of the following:\n"
+"     SUCCESS | FAILURE\n"
+"",
+	.syntax = "DLOCK_TRYRDLOCK(<lock_name>)",
+	.read = handle_tryrdlock,
+};
+
+static struct ast_custom_function dlock_trywrlock = {
+	.name = "DLOCK_TRYWRLOCK",
+	.synopsis = "Try to write-lock a distributed lock",
+	.desc =
+"  This function will attempt to write-lock a distributed lock provided by\n"
+"the locking service of AIS.  This is a non-blocking operation.\n"
+"  The name of the lock can be anything.  The first time a named lock gets\n"
+"used, it will be automatically created and maintained amongst the cluster.\n"
+"  The result of this function will be one of the following:\n"
+"     SUCCESS | FAILURE\n"
+"",
+	.syntax = "DLOCK_TRYWRLOCK(<lock_name>)",
+	.read = handle_trywrlock,
+};
+
+static struct ast_custom_function dlock_unlock = {
+	.name = "DLOCK_UNLOCK",
+	.synopsis = "Unlock a distributed lock",
+	.desc =
+"  This function will unlock a currently held distributed lock.  This should\n"
+"be used regardless of the lock was read or write locked.  The result of\n"
+"this funtion will be one of the following:\n"
+"      SUCCESS | FAILURE\n"
+"",
+	.syntax = "DLOCK_UNLOCK(<lock_name>)",
+	.read = handle_unlock,
+};
+
 int ast_ais_lck_load_module(void)
 {
-	SaAisErrorT res;
-
-	res = saLckInitialize(&lck_handle, &lck_callbacks, &ais_version);
-	if (res != SA_AIS_OK) {
+	SaAisErrorT ais_res;
+	int res;
+
+	ais_res = saLckInitialize(&lck_handle, &lck_callbacks, &ais_version);
+	if (ais_res != SA_AIS_OK) {
 		ast_log(LOG_ERROR, "Could not initialize distributed locking service: %s\n",
-			ais_err2str(res));
-		return AST_MODULE_LOAD_DECLINE;
-	}
-
-	return AST_MODULE_LOAD_SUCCESS;
+			ais_err2str(ais_res));
+		return -1;
+	}
+
+	res = ast_custom_function_register(&dlock_rdlock);
+	res |= ast_custom_function_register(&dlock_wrlock);
+	res |= ast_custom_function_register(&dlock_tryrdlock);
+	res |= ast_custom_function_register(&dlock_trywrlock);
+	res |= ast_custom_function_register(&dlock_unlock);
+
+	return res;
 }
 
 int ast_ais_lck_unload_module(void)
 {
-	SaAisErrorT res;
-
-	res = saLckFinalize(lck_handle);
-	if (res != SA_AIS_OK) {
+	SaAisErrorT ais_res;
+
+	ast_custom_function_unregister(&dlock_rdlock);
+	ast_custom_function_unregister(&dlock_wrlock);
+	ast_custom_function_unregister(&dlock_tryrdlock);
+	ast_custom_function_unregister(&dlock_trywrlock);
+	ast_custom_function_unregister(&dlock_unlock);
+
+	ais_res = saLckFinalize(lck_handle);
+	if (ais_res != SA_AIS_OK) {
 		ast_log(LOG_ERROR, "Problem stopping distributed locking service: %s\n", 
-			ais_err2str(res));
+			ais_err2str(ais_res));
 		return -1;
 	}
 

Modified: team/russell/events/res/res_ais.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/res/res_ais.c?view=diff&rev=84142&r1=84141&r2=84142
==============================================================================
--- team/russell/events/res/res_ais.c (original)
+++ team/russell/events/res/res_ais.c Sat Sep 29 22:00:40 2007
@@ -31,7 +31,6 @@
 /*** MODULEINFO
 	<depend>SaClm</depend>
 	<depend>SaEvt</depend>
-	<depend>SaLck</depend>
  ***/
 
 #include "asterisk.h"
@@ -161,18 +160,13 @@
 
 static int load_module(void)
 {
-	int res;
-
-	res = ast_ais_clm_load_module();
-	if (res != AST_MODULE_LOAD_SUCCESS)
+	if (ast_ais_clm_load_module())
 		goto clm_failed;
 
-	res = ast_ais_evt_load_module();
-	if (res != AST_MODULE_LOAD_SUCCESS)
+	if (ast_ais_evt_load_module())
 		goto evt_failed;
 
-	res = ast_ais_lck_load_module();
-	if (res != AST_MODULE_LOAD_SUCCESS)
+	if (ast_ais_lck_load_module())
 		goto lck_failed;
 
 	ast_pthread_create_background(&dispatch_thread.id, NULL, 
@@ -185,7 +179,7 @@
 evt_failed:
 	ast_ais_clm_unload_module();
 clm_failed:
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 static int unload_module(void)




More information about the asterisk-commits mailing list