[asterisk-commits] dvossel: branch dvossel/awesomehooks r286934 - in /team/dvossel/awesomehooks:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Sep 15 14:22:54 CDT 2010
Author: dvossel
Date: Wed Sep 15 14:22:50 2010
New Revision: 286934
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=286934
Log:
adds functionality for pushing events to awesomehook lists.
Modified:
team/dvossel/awesomehooks/include/asterisk/awesomehook.h
team/dvossel/awesomehooks/main/awesomehook.c
Modified: team/dvossel/awesomehooks/include/asterisk/awesomehook.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/awesomehooks/include/asterisk/awesomehook.h?view=diff&rev=286934&r1=286933&r2=286934
==============================================================================
--- team/dvossel/awesomehooks/include/asterisk/awesomehook.h (original)
+++ team/dvossel/awesomehooks/include/asterisk/awesomehook.h Wed Sep 15 14:22:50 2010
@@ -37,7 +37,7 @@
};
enum ast_awesomehook_event {
- AST_AWESOMEHOOK_NO_EVENTS,
+ AST_AWESOMEHOOK_EVENT_NOOP, /*!< This is a NO-OP event. It only exists to initilized the awesomehook->last_event variable*/
AST_AWESOMEHOOK_EVENT_READ, /*!< frame is intercepted in the read direction on the channel. */
AST_AWESOMEHOOK_EVENT_WRITE, /*!< frame is intercepted on the write direction on the channel. */
AST_AWESOMEHOOK_EVENT_ATTACHED, /*!< the awesomehook is attached and running on the channel. */
@@ -54,8 +54,25 @@
* immediately after the awesomehook is attached to a channel, and
* AST_AWESOMEHOOK_EVENT_DETACHED, which occurs right after the awesomehook is
* detached.
+ *
+ * It is _NOT_ safe to assume the channel or the frame are ever not NULL. Always perform
+ * a NULL check before performing any action on either of these objects.
+ *
+ * When the channel variable is present, it is safe to assume it will always be locked.
+ * Never attempt to unlock the channel variable during this callback.
+ *
+ * When the frame variable is present, it is safe to view and manipulate that frame
+ * in any way possible. It is even safe to return a completely different frame, but
+ * when that occurs this function is in charge of freeing the previous frame.
+ *
+ * \param awesomehook, The awesomehook associated with this callback.
+ * \param channel, The ast_channel this awesomehook is attached to.
+ * \param frame, The ast_frame being intercepted for viewing and manipulation
+ * \param event, The type of event which is occurring
+ *
+ * \retval the resulting frame.
*/
-typedef int (*ast_awesomehook_event_callback)(struct ast_awesomehook *awesomehook,
+typedef struct ast_frame *(*ast_awesomehook_event_callback)(struct ast_awesomehook *awesomehook,
struct ast_channel *chan,
struct ast_frame *frame,
enum ast_awesomehook_event event);
@@ -125,9 +142,32 @@
int ast_awesomehook_list_destroy(struct ast_awesomehook_list *awesomehooks);
/*!
- * \brief Return the status of an awesomehook.
+ * \brief This is used by the channel API push a frame read event to a channel's awesomehook list.
+ *
+ * \details After this function completes, the resulting frame that is returned could be anything,
+ * even NULL. There is nothing to keep up with after this function. If the frame is modified, the
+ * awesomehook callback is in charge of any memory management associated with that modification.
+ *
+ * \param awesomehook list to push event to.
+ * \param frame being pushed to the awesomehook list.
+ *
+ * \return The resulting frame after being viewed and modified by the awesomehook callbacks.
*/
-enum ast_awesomehook_status ast_awesomehook_get_status(struct ast_awesomehook *awesomehook);
+struct ast_frame *ast_awesomehook_list_read_event(struct ast_awesomehook_list *awesomehooks, struct ast_frame *frame);
+
+/*!
+ * \brief This is used by the channel API push a frame write event to a channel's awesomehook list.
+ *
+ * \details After this function completes, the resulting frame that is returned could be anything,
+ * even NULL. There is nothing to keep up with after this function. If the frame is modified, the
+ * awesomehook callback is in charge of any memory management associated with that modification.
+ *
+ * \param awesomehook list to push event to.
+ * \param frame being pushed to the awesomehook list.
+ *
+ * \return The resulting frame after being viewed and modified by the awesomehook callbacks.
+ */
+struct ast_frame *ast_awesomehook_list_write_event(struct ast_awesomehook_list *awesomehooks, struct ast_frame *frame);
/*!
* \brief Set the awesomehook's custom data storage pointer.
Modified: team/dvossel/awesomehooks/main/awesomehook.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/awesomehooks/main/awesomehook.c?view=diff&rev=286934&r1=286933&r2=286934
==============================================================================
--- team/dvossel/awesomehooks/main/awesomehook.c (original)
+++ team/dvossel/awesomehooks/main/awesomehook.c Wed Sep 15 14:22:50 2010
@@ -84,13 +84,14 @@
awesomehook->event_cb = event_cb;
awesomehook->destroy_cb = destroy_cb;
awesomehook->status = AST_AWESOMEHOOK_STATUS_INIT;
- awesomehook->last_event = AST_AWESOMEHOOK_NO_EVENTS;
+ awesomehook->last_event = AST_AWESOMEHOOK_EVENT_NOOP;
ast_mutex_init(&awesomehook->lock);
return awesomehook;
}
int ast_awesomehook_attach(struct ast_awesomehook *awesomehook, struct ast_channel *chan)
{
+ struct ast_frame *frame;
ast_channel_lock(chan);
AST_LIST_INSERT_TAIL(&chan->awesomehooks.list, awesomehook, list);
awesomehook->chan = chan;
@@ -99,9 +100,29 @@
awesomehook_update_status(awesomehook, AST_AWESOMEHOOK_STATUS_ATTACHED);
/* tell the event callback we're live and rocking */
- awesomehook->event_cb(awesomehook, awesomehook->chan, NULL, AST_AWESOMEHOOK_EVENT_ATTACHED);
+ frame = awesomehook->event_cb(awesomehook, awesomehook->chan, NULL, AST_AWESOMEHOOK_EVENT_ATTACHED);
+
+ /* never assume anything about this function. If you can return a frame during
+ * the attached event, then assume someone will. */
+ if (frame) {
+ ast_frfree(frame);
+ }
return 0;
+}
+
+static void awesomehook_detach_and_destroy(struct ast_awesomehook *awesomehook)
+{
+ struct ast_frame *frame;
+ awesomehook_update_status(awesomehook, AST_AWESOMEHOOK_STATUS_DETACHED);
+ frame = awesomehook->event_cb(awesomehook, awesomehook->chan, NULL, AST_AWESOMEHOOK_EVENT_DETACHED);
+ /* never assume anything about this function. If you can return a frame during
+ * the detached event, then assume someone will. */
+ if (frame) {
+ ast_frfree(frame);
+ }
+ awesomehook->chan = NULL;
+ awesomehook_destroy(awesomehook);
}
int ast_awesomehook_signal_destroy(struct ast_awesomehook *awesomehook)
@@ -117,19 +138,39 @@
AST_LIST_TRAVERSE_SAFE_BEGIN(&awesomehooks->list, awesomehook, list) {
AST_LIST_REMOVE_CURRENT(list);
- awesomehook_update_status(awesomehook, AST_AWESOMEHOOK_STATUS_DETACHED);
- awesomehook->event_cb(awesomehook, awesomehook->chan, NULL, AST_AWESOMEHOOK_EVENT_DETACHED);
- awesomehook->chan = NULL;
- awesomehook_destroy(awesomehook);
+ awesomehook_detach_and_destroy(awesomehook);
}
AST_LIST_TRAVERSE_SAFE_END;
return 0;
}
-enum ast_awesomehook_status ast_awesomehook_get_status(struct ast_awesomehook *awesomehook)
+static struct ast_frame *awesomehook_list_push_event(struct ast_awesomehook_list *awesomehooks, struct ast_frame *frame, enum ast_awesomehook_event event)
{
- return awesomehook->status;
+ struct ast_awesomehook *awesomehook;
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&awesomehooks->list, awesomehook, list) {
+ /* check to see if this hook was signaled for detachment, if so do not push the
+ * read/write event. Instead detach from list and destroy */
+ if (awesomehook->status == AST_AWESOMEHOOK_STATUS_DETACHED) {
+ AST_LIST_REMOVE_CURRENT(list);
+ awesomehook_detach_and_destroy(awesomehook);
+ continue;
+ }
+ frame = awesomehook->event_cb(awesomehook, awesomehook->chan, frame, event);
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+
+ return frame;
+}
+
+struct ast_frame *ast_awesomehook_list_write_event(struct ast_awesomehook_list *awesomehooks, struct ast_frame *frame)
+{
+ return awesomehook_list_push_event(awesomehooks, frame, AST_AWESOMEHOOK_EVENT_WRITE);
+}
+
+struct ast_frame *ast_awesomehook_list_read_event(struct ast_awesomehook_list *awesomehooks, struct ast_frame *frame)
+{
+ return awesomehook_list_push_event(awesomehooks, frame, AST_AWESOMEHOOK_EVENT_READ);
}
int ast_awesomehook_set_datastore(struct ast_awesomehook *awesomehook, void *data)
More information about the asterisk-commits
mailing list