[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