[asterisk-commits] russell: branch russell/events r65572 - in
/team/russell/events: include/aste...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Tue May 22 19:13:06 MST 2007
Author: russell
Date: Tue May 22 21:13:06 2007
New Revision: 65572
URL: http://svn.digium.com/view/asterisk?view=rev&rev=65572
Log:
Finish the basic conversion of device state handling to the common event system.
I am still not terribly excited with how the device state events are generated
in the first place, but it is still a relic of the original code. Device state
providers queue an event to say that the state of a device has changed. Then,
another thread calls the device state providers callback to determine what the
new state actually is. I really don't see why the initial event to say that
the state of a device has changed doesn't just include the new state in the
first place. But, it's going to take a lot of work to change it ...
Modified:
team/russell/events/include/asterisk/pbx.h
team/russell/events/main/devicestate.c
team/russell/events/main/pbx.c
Modified: team/russell/events/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/team/russell/events/include/asterisk/pbx.h?view=diff&rev=65572&r1=65571&r2=65572
==============================================================================
--- team/russell/events/include/asterisk/pbx.h (original)
+++ team/russell/events/include/asterisk/pbx.h Tue May 22 21:13:06 2007
@@ -877,8 +877,6 @@
*/
int ast_func_write(struct ast_channel *chan, const char *function, const char *value);
-void ast_hint_state_changed(const char *device);
-
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
Modified: team/russell/events/main/devicestate.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/devicestate.c?view=diff&rev=65572&r1=65571&r2=65572
==============================================================================
--- team/russell/events/main/devicestate.c (original)
+++ team/russell/events/main/devicestate.c Tue May 22 21:13:06 2007
@@ -393,9 +393,6 @@
ast_event_queue_and_cache(event,
AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
AST_EVENT_IE_END);
-
- /*! \todo Convert hints to be device state subscribers. */
- ast_hint_state_changed(device);
}
static int __ast_device_state_changed_literal(char *buf)
Modified: team/russell/events/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/pbx.c?view=diff&rev=65572&r1=65571&r2=65572
==============================================================================
--- team/russell/events/main/pbx.c (original)
+++ team/russell/events/main/pbx.c Tue May 22 21:13:06 2007
@@ -219,6 +219,29 @@
{ AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
{ AST_EXTENSION_ONHOLD, "Hold" },
{ AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
+};
+
+struct statechange {
+ AST_LIST_ENTRY(statechange) entry;
+ char dev[0];
+};
+
+/*!
+ * \brief Data used by the device state thread
+ */
+static struct {
+ /*! Set to 1 to stop the thread */
+ unsigned int stop:1;
+ /*! The device state monitoring thread */
+ pthread_t thread;
+ /*! Lock for the state change queue */
+ ast_mutex_t lock;
+ /*! Condition for the state change queue */
+ ast_cond_t cond;
+ /*! Queue of state changes */
+ AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
+} device_state = {
+ .thread = AST_PTHREADT_NULL,
};
static int pbx_builtin_answer(struct ast_channel *, void *);
@@ -1921,7 +1944,7 @@
return ast_extension_state2(e); /* Check all devices in the hint */
}
-void ast_hint_state_changed(const char *device)
+static void handle_statechange(const char *device)
{
struct ast_hint *hint;
@@ -1962,6 +1985,47 @@
}
AST_RWLIST_UNLOCK(&hints);
+}
+
+static int statechange_queue(const char *dev)
+{
+ /* 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)))
+ return 0;
+
+ strcpy(sc->dev, dev);
+
+ ast_mutex_lock(&device_state.lock);
+ AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
+ ast_cond_signal(&device_state.cond);
+ ast_mutex_unlock(&device_state.lock);
+
+ return 0;
+}
+
+static void *device_state_thread(void *data)
+{
+ struct statechange *sc;
+
+ while (!device_state.stop) {
+ ast_mutex_lock(&device_state.lock);
+ while (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry)))
+ ast_cond_wait(&device_state.cond, &device_state.lock);
+ ast_mutex_unlock(&device_state.lock);
+
+ /* Check to see if we were woken up to see the request to stop */
+ if (device_state.stop)
+ return NULL;
+
+ handle_statechange(sc->dev);
+
+ free(sc);
+ }
+
+ return NULL;
}
/*! \brief ast_extension_state_add: Add watcher for extension states */
@@ -6056,18 +6120,15 @@
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;
}
- // XXX statechange_queue(device, state);
+ statechange_queue(device);
}
int load_pbx(void)
@@ -6093,6 +6154,10 @@
/* Register manager application */
ast_manager_register2("ShowDialPlan", EVENT_FLAG_CONFIG, manager_show_dialplan, "List dialplan", mandescr_show_dialplan);
+
+ ast_mutex_init(&device_state.lock);
+ ast_cond_init(&device_state.cond, NULL);
+ ast_pthread_create(&device_state.thread, NULL, device_state_thread, NULL);
if (!(device_state_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE, device_state_cb, NULL,
AST_EVENT_IE_END))) {
More information about the asterisk-commits
mailing list