summaryrefslogtreecommitdiff
path: root/apps/app_queue.c
diff options
context:
space:
mode:
authorRussell Bryant <russell@russellbryant.com>2007-06-01 23:34:43 +0000
committerRussell Bryant <russell@russellbryant.com>2007-06-01 23:34:43 +0000
commit605368649ef8280e3b52a45a80fd30562a767af3 (patch)
treeca2f21d45b7f24e39079d1aec0006a66cad40dec /apps/app_queue.c
parentc9cf12b6758eba923746fc47e36b9684ac593944 (diff)
Merge major changes to the way device state is passed around Asterisk. The two
places that cared about device states were app_queue and the hint code in pbx.c. The changes include converting it to use the Asterisk event system, as well as other efficiency improvements. * app_queue: This module used to register a callback into devicestate.c to monitor device state changes. Now, it is just a subscriber to Asterisk events with the type, device state. * pbx.c hints: Previously, the device state processing thread in devicestate.c would call ast_hint_state_changed() each time the state of a device changed. Then, that code would go looking for all the hints that monitor that device, and call their callbacks. All of this blocked the device state processing thread. Now, the hint code is a subscriber of Asterisk events with the type, device state. Furthermore, when this code receives a device state change event, it queues it up to be processed by another thread so that it doesn't block one of the event processing threads. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@66958 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r--apps/app_queue.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index dad3ac33b..7d06d2df2 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -92,6 +92,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/astdb.h"
#include "asterisk/devicestate.h"
#include "asterisk/stringfields.h"
+#include "asterisk/event.h"
enum {
QUEUE_STRATEGY_RINGALL = 0,
@@ -257,6 +258,9 @@ static int autofill_default = 0;
/*! \brief queues.conf [general] option */
static int montype_default = 0;
+/*! \brief Subscription to device state change events */
+static struct ast_event_sub *device_state_sub;
+
enum queue_result {
QUEUE_UNKNOWN = 0,
QUEUE_TIMEOUT = 1,
@@ -656,10 +660,8 @@ static void *device_state_thread(void *data)
return NULL;
}
-static int statechange_queue(const char *dev, enum ast_device_state state, void *data)
+static int statechange_queue(const char *dev, enum ast_device_state state)
{
- /* Avoid potential for deadlocks by spawning a new thread to handle
- the event */
struct statechange *sc;
if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
@@ -676,6 +678,22 @@ static int statechange_queue(const char *dev, enum ast_device_state state, void
return 0;
}
+static void device_state_cb(const struct ast_event *event, void *unused)
+{
+ enum ast_device_state state;
+ const char *device;
+
+ state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
+ device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
+
+ if (ast_strlen_zero(device)) {
+ ast_log(LOG_ERROR, "Received invalid event that had no device IE\n");
+ return;
+ }
+
+ statechange_queue(device, state);
+}
+
static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused)
{
struct member *cur;
@@ -4747,7 +4765,9 @@ static int unload_module(void)
res |= ast_custom_function_unregister(&queuemembercount_function);
res |= ast_custom_function_unregister(&queuememberlist_function);
res |= ast_custom_function_unregister(&queuewaitingcount_function);
- ast_devstate_del(statechange_queue, NULL);
+
+ if (device_state_sub)
+ ast_event_unsubscribe(device_state_sub);
ast_module_user_hangup_all();
@@ -4788,7 +4808,9 @@ static int load_module(void)
res |= ast_custom_function_register(&queuemembercount_function);
res |= ast_custom_function_register(&queuememberlist_function);
res |= ast_custom_function_register(&queuewaitingcount_function);
- res |= ast_devstate_add(statechange_queue, NULL);
+
+ if (!(device_state_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE, device_state_cb, NULL, AST_EVENT_IE_END)))
+ res = -1;
return res;
}