]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
mod_rayo: rework component inheritance- component now inherits parent call/mixer...
authorChris Rienzo <chris.rienzo@grasshopper.com>
Fri, 13 Jun 2014 16:16:26 +0000 (12:16 -0400)
committerChris Rienzo <chris.rienzo@grasshopper.com>
Fri, 13 Jun 2014 16:16:26 +0000 (12:16 -0400)
src/mod/event_handlers/mod_rayo/mod_rayo.c
src/mod/event_handlers/mod_rayo/mod_rayo.h
src/mod/event_handlers/mod_rayo/rayo_cpa_component.c
src/mod/event_handlers/mod_rayo/rayo_fax_components.c
src/mod/event_handlers/mod_rayo/rayo_input_component.c
src/mod/event_handlers/mod_rayo/rayo_output_component.c
src/mod/event_handlers/mod_rayo/rayo_prompt_component.c
src/mod/event_handlers/mod_rayo/rayo_record_component.c

index 1d46fdb2a5c0bc2b1c25ff5bd8a427a0b05fc42e..15061138080ff3b0e3edc70ca12687023e9f96a7 100644 (file)
@@ -950,6 +950,10 @@ void rayo_actor_destroy(struct rayo_actor *actor, const char *file, int line)
                if (actor->cleanup_fn) {
                        actor->cleanup_fn(actor);
                }
+               if (actor->parent) {
+                       /* safe to destroy parent now */
+                       RAYO_RELEASE(actor->parent);
+               }
                switch_core_hash_delete(globals.destroy_actors, RAYO_JID(actor));
                switch_core_destroy_memory_pool(&pool);
        } else {
@@ -1224,10 +1228,12 @@ void rayo_actor_send_ignore(struct rayo_actor *to, struct rayo_message *msg)
        switch_log_printf(SWITCH_CHANNEL_ID_LOG, msg->file, "", msg->line, "", SWITCH_LOG_WARNING, "%s, dropping unexpected message to %s.\n", msg->from_jid, RAYO_JID(to));
 }
 
-#define RAYO_ACTOR_INIT(actor, pool, type, subtype, id, jid, cleanup, send) rayo_actor_init(actor, pool, type, subtype, id, jid, cleanup, send, __FILE__, __LINE__)
+#define RAYO_ACTOR_INIT(actor, pool, type, subtype, id, jid, cleanup, send) rayo_actor_init(actor, pool, type, subtype, id, jid, cleanup, send, NULL, __FILE__, __LINE__)
+#define RAYO_ACTOR_INIT_PARENT(actor, pool, type, subtype, id, jid, cleanup, send, parent) rayo_actor_init(actor, pool, type, subtype, id, jid, cleanup, send, parent, __FILE__, __LINE__)
 
 /**
  * Initialize a rayo actor
+ * @param actor to initialize
  * @param pool to use
  * @param type of actor (MIXER, CALL, SERVER, COMPONENT)
  * @param subtype of actor (input/output/prompt)
@@ -1235,11 +1241,12 @@ void rayo_actor_send_ignore(struct rayo_actor *to, struct rayo_message *msg)
  * @param jid external ID
  * @param cleanup function
  * @param send sent message handler
+ * @param parent of actor
  * @param file that called this function
  * @param line that called this function
  * @return the actor or NULL if JID conflict
  */
-static struct rayo_actor *rayo_actor_init(struct rayo_actor *actor, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, const char *jid, rayo_actor_cleanup_fn cleanup, rayo_actor_send_fn send, const char *file, int line)
+static struct rayo_actor *rayo_actor_init(struct rayo_actor *actor, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, const char *jid, rayo_actor_cleanup_fn cleanup, rayo_actor_send_fn send, struct rayo_actor *parent, const char *file, int line)
 {
        char *domain;
        actor->type = switch_core_strdup(pool, type);
@@ -1265,7 +1272,6 @@ static struct rayo_actor *rayo_actor_init(struct rayo_actor *actor, switch_memor
        actor->seq = 1;
        actor->ref_count = 1;
        actor->destroy = 0;
-       switch_mutex_init(&actor->mutex, SWITCH_MUTEX_NESTED, pool);
        actor->cleanup_fn = cleanup;
        if (send == NULL) {
                actor->send_fn = rayo_actor_send_ignore;
@@ -1273,6 +1279,17 @@ static struct rayo_actor *rayo_actor_init(struct rayo_actor *actor, switch_memor
                actor->send_fn = send;
        }
 
+       actor->parent = parent;
+       if (!actor->parent) {
+               switch_mutex_init(&actor->mutex, SWITCH_MUTEX_NESTED, pool);
+       } else {
+               /* inherit mutex from parent */
+               actor->mutex = actor->parent->mutex;
+
+               /* prevent parent destruction */
+               RAYO_RETAIN(actor->parent);
+       }
+
        /* add to hash of actors, so commands can route to call */
        switch_mutex_lock(globals.actors_mutex);
        if (!zstr(jid)) {
@@ -1280,6 +1297,11 @@ static struct rayo_actor *rayo_actor_init(struct rayo_actor *actor, switch_memor
                        /* duplicate JID, give up! */
                        switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_NOTICE, "JID conflict! %s\n", RAYO_JID(actor));
                        switch_mutex_unlock(globals.actors_mutex);
+                       if (actor->parent) {
+                               /* unlink from parent */
+                               RAYO_RELEASE(actor->parent);
+                               actor->parent = NULL;
+                       }
                        return NULL;
                }
                switch_core_hash_insert(globals.actors, RAYO_JID(actor), actor);
@@ -1313,7 +1335,7 @@ static struct rayo_call *rayo_call_init(struct rayo_call *call, switch_memory_po
        }
        call_jid = switch_mprintf("%s@%s", uuid, RAYO_JID(globals.server));
 
-       call = RAYO_CALL(rayo_actor_init(RAYO_ACTOR(call), pool, RAT_CALL, "", uuid, call_jid, rayo_call_cleanup, rayo_call_send, file, line));
+       call = RAYO_CALL(rayo_actor_init(RAYO_ACTOR(call), pool, RAT_CALL, "", uuid, call_jid, rayo_call_cleanup, rayo_call_send, NULL, file, line));
        if (call) {
                call->dcp_jid = "";
                call->idle_start_time = switch_micro_time_now();
@@ -1370,7 +1392,7 @@ static void rayo_mixer_cleanup(struct rayo_actor *actor)
 static struct rayo_mixer *rayo_mixer_init(struct rayo_mixer *mixer, switch_memory_pool_t *pool, const char *name, const char *file, int line)
 {
        char *mixer_jid = switch_mprintf("%s@%s", name, RAYO_JID(globals.server));
-       mixer = RAYO_MIXER(rayo_actor_init(RAYO_ACTOR(mixer), pool, RAT_MIXER, "", name, mixer_jid, rayo_mixer_cleanup, rayo_mixer_send, file, line));
+       mixer = RAYO_MIXER(rayo_actor_init(RAYO_ACTOR(mixer), pool, RAT_MIXER, "", name, mixer_jid, rayo_mixer_cleanup, rayo_mixer_send, NULL, file, line));
        if (mixer) {
                switch_core_hash_init(&mixer->members);
                switch_core_hash_init(&mixer->subscribers);
@@ -1397,19 +1419,6 @@ static struct rayo_mixer *_rayo_mixer_create(const char *name, const char *file,
        return mixer;
 }
 
-/**
- * Clean up component before destruction
- */
-static void rayo_component_cleanup(struct rayo_actor *actor)
-{
-       if (RAYO_COMPONENT(actor)->cleanup_fn) {
-               RAYO_COMPONENT(actor)->cleanup_fn(actor);
-       }
-
-       /* parent can now be destroyed */
-       RAYO_RELEASE(RAYO_COMPONENT(actor)->parent);
-}
-
 /**
  * Initialize Rayo component
  * @param type of this component
@@ -1430,13 +1439,10 @@ struct rayo_component *_rayo_component_init(struct rayo_component *component, sw
                id = jid;
        }
 
-       component = RAYO_COMPONENT(rayo_actor_init(RAYO_ACTOR(component), pool, type, subtype, id, jid, rayo_component_cleanup, rayo_component_send, file, line));
+       component = RAYO_COMPONENT(rayo_actor_init(RAYO_ACTOR(component), pool, type, subtype, id, jid, cleanup, rayo_component_send, parent, file, line));
        if (component) {
-               RAYO_RETAIN(parent);
                component->client_jid = switch_core_strdup(pool, client_jid);
                component->ref = switch_core_strdup(pool, ref);
-               component->parent = parent;
-               component->cleanup_fn = cleanup;
        }
 
        switch_safe_free(ref);
index 074e32fd5ed848d0306abef15eebc6c5a5f65ff2..cefd4e17827272d429342983b4fed775ca814cba 100644 (file)
@@ -106,6 +106,8 @@ struct rayo_actor {
        rayo_actor_send_fn send_fn;
        /** optional cleanup */
        rayo_actor_cleanup_fn cleanup_fn;
+       /** optional parent */
+       struct rayo_actor *parent;
 };
 
 /**
@@ -114,16 +116,12 @@ struct rayo_actor {
 struct rayo_component {
        /** base actor class */
        struct rayo_actor base;
-       /** parent to this component */
-       struct rayo_actor *parent;
        /** owning client JID */
        const char *client_jid;
        /** external ref */
        const char *ref;
        /** true if component has completed */
        int complete;
-       /** optional cleanup */
-       rayo_actor_cleanup_fn cleanup_fn;
 };
 
 #define RAYO_ACTOR(x) ((struct rayo_actor *)x)
index 634968d4a8a20de697cad7b944c5d3e6e7c432b3..fb271bd03e8ecefc0cf252f255001afd406e6cea 100644 (file)
@@ -166,14 +166,14 @@ static void stop_cpa_detectors(struct cpa_component *cpa)
                        void *cpa_signal = NULL;
                        switch_core_hash_this(hi, &signal_type, NULL, &cpa_signal);
                        if (cpa_signal) {
-                               rayo_cpa_detector_stop(RAYO_COMPONENT(cpa)->parent->id, ((struct cpa_signal *)cpa_signal)->name);
-                               unsubscribe(RAYO_COMPONENT(cpa)->parent->id, ((struct cpa_signal *)cpa_signal)->name, RAYO_JID(cpa));
+                               rayo_cpa_detector_stop(RAYO_ACTOR(cpa)->parent->id, ((struct cpa_signal *)cpa_signal)->name);
+                               unsubscribe(RAYO_ACTOR(cpa)->parent->id, ((struct cpa_signal *)cpa_signal)->name, RAYO_JID(cpa));
                        }
                }
                switch_core_hash_destroy(&cpa->signals);
                cpa->signals = NULL;
        }
-       unsubscribe(RAYO_COMPONENT(cpa)->parent->id, "hangup", RAYO_JID(cpa));
+       unsubscribe(RAYO_ACTOR(cpa)->parent->id, "hangup", RAYO_JID(cpa));
 }
 
 /**
@@ -197,7 +197,7 @@ static void rayo_cpa_detector_event(const char *jid, void *user_data)
                        switch_event_t *event = (switch_event_t *)user_data;
                        const char *signal_type = switch_event_get_header(event, "signal-type");
                        struct cpa_signal *cpa_signal = switch_core_hash_find(CPA_COMPONENT(component)->signals, signal_type);
-                       switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_COMPONENT(component)->parent->id), SWITCH_LOG_DEBUG, "Handling CPA event\n");
+                       switch_log_printf(SWITCH_CHANNEL_UUID_LOG(component->parent->id), SWITCH_LOG_DEBUG, "Handling CPA event\n");
                        if (cpa_signal) {
                                const char *value = switch_event_get_header(event, "value");
                                const char *duration = switch_event_get_header(event, "duration");
@@ -234,7 +234,7 @@ static void rayo_cpa_detector_event(const char *jid, void *user_data)
                                }
                        }
                } else {
-                       switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_COMPONENT(component)->parent->id), SWITCH_LOG_DEBUG, "Skipping CPA event\n");
+                       switch_log_printf(SWITCH_CHANNEL_UUID_LOG(component->parent->id), SWITCH_LOG_DEBUG, "Skipping CPA event\n");
                }
                RAYO_RELEASE(component);
        }
index 0ceb0532b77e26cbea1d5a07d049846168ca51d3..b605702005702088465666f7c467f01f61943167 100644 (file)
@@ -340,7 +340,7 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess
 static iks *stop_fax_component(struct rayo_actor *component, struct rayo_message *msg, void *data)
 {
        iks *iq = msg->payload;
-       switch_core_session_t *session = switch_core_session_locate(RAYO_COMPONENT(component)->parent->id);
+       switch_core_session_t *session = switch_core_session_locate(component->parent->id);
        FAX_COMPONENT(component)->stop = 1;
        if (session) {
                switch_core_session_execute_application_async(session, "stopfax", "");
@@ -459,7 +459,7 @@ static void on_execute_complete_event(switch_event_t *event)
                        insert_fax_metadata(event, "fax_remote_station_id", complete);
 
                        /* flag faxing as done */
-                       rayo_call_set_faxing(RAYO_CALL(RAYO_COMPONENT(component)->parent), 0);
+                       rayo_call_set_faxing(RAYO_CALL(component->parent), 0);
 
                        rayo_component_send_complete_event(RAYO_COMPONENT(component), result);
 
index 4bcab10b0d28a6be11201d94da61a45ef8da1ce2..cfada79370ec6c54d3a29f92a73fb898d68d6527 100644 (file)
@@ -762,7 +762,7 @@ static iks *stop_call_input_component(struct rayo_actor *component, struct rayo_
        struct input_component *input_component = INPUT_COMPONENT(component);
 
        if (input_component && !input_component->stop) {
-               switch_core_session_t *session = switch_core_session_locate(RAYO_COMPONENT(component)->parent->id);
+               switch_core_session_t *session = switch_core_session_locate(component->parent->id);
                if (session) {
                        switch_mutex_lock(input_component->handler->mutex);
                        input_component->stop = 1;
@@ -787,7 +787,7 @@ static iks *start_timers_call_input_component(struct rayo_actor *component, stru
        iks *iq = msg->payload;
        struct input_component *input_component = INPUT_COMPONENT(component);
        if (input_component) {
-               switch_core_session_t *session = switch_core_session_locate(RAYO_COMPONENT(component)->parent->id);
+               switch_core_session_t *session = switch_core_session_locate(component->parent->id);
                if (session) {
                        switch_mutex_lock(input_component->handler->mutex);
                        if (input_component->speech_mode) {
index 82cf3a0272cc535a846090d32c592905a2b5f26d..9d075dc6aeee8af6c5302ac8114a79bd703d1def 100644 (file)
@@ -536,7 +536,7 @@ static switch_status_t rayo_file_close(switch_file_handle_t *handle)
                } else {
                        if (!strcmp(RAYO_ACTOR(context->component)->type, RAT_CALL_COMPONENT)) {
                                /* call output... check for hangup */
-                               switch_core_session_t *session = switch_core_session_locate(context->component->parent->id);
+                               switch_core_session_t *session = switch_core_session_locate(RAYO_ACTOR(context->component)->parent->id);
                                if (session) {
                                        if (switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) {
                                                rayo_component_send_complete(context->component, COMPONENT_COMPLETE_HANGUP);
index 7003762839ea90982bdb250f9abf1e52407d6cd3..33042ed19ddf893b4b6d408ba2ae565d26c0dd1f 100644 (file)
@@ -126,14 +126,14 @@ static void start_input(struct prompt_component *prompt, int start_timers, int b
        iks *input = iks_find(PROMPT_COMPONENT(prompt)->iq, "prompt");
        input = iks_find(input, "input");
        iks_insert_attrib(iq, "from", RAYO_JID(prompt));
-       iks_insert_attrib(iq, "to", RAYO_JID(RAYO_COMPONENT(prompt)->parent));
+       iks_insert_attrib(iq, "to", RAYO_JID(RAYO_ACTOR(prompt)->parent));
        iks_insert_attrib_printf(iq, "id", "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(prompt));
        iks_insert_attrib(iq, "type", "set");
        input = iks_copy_within(input, iks_stack(iq));
        iks_insert_attrib(input, "start-timers", start_timers ? "true" : "false");
        iks_insert_attrib(input, "barge-event", barge_event ? "true" : "false");
        iks_insert_node(iq, input);
-       RAYO_SEND_MESSAGE(prompt, RAYO_JID(RAYO_COMPONENT(prompt)->parent), iq);
+       RAYO_SEND_MESSAGE(prompt, RAYO_JID(RAYO_ACTOR(prompt)->parent), iq);
 }
 
 /**
@@ -281,7 +281,7 @@ static iks *prompt_component_handle_input_error(struct rayo_actor *prompt, struc
 
                        /* forward IQ error to client */
                        iq = PROMPT_COMPONENT(prompt)->iq;
-                       iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent));
+                       iks_insert_attrib(iq, "from", RAYO_JID(prompt->parent));
                        iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid);
                        iks_insert_node(iq, iks_copy_within(error, iks_stack(iq)));
                        RAYO_SEND_REPLY(prompt, RAYO_COMPONENT(prompt)->client_jid, iq);
@@ -309,7 +309,7 @@ static iks *prompt_component_handle_input_error(struct rayo_actor *prompt, struc
 
                        /* forward IQ error to client */
                        iq = PROMPT_COMPONENT(prompt)->iq;
-                       iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent));
+                       iks_insert_attrib(iq, "from", RAYO_JID(prompt->parent));
                        iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid);
                        iks_insert_node(iq, iks_copy_within(error, iks_stack(iq)));
                        PROMPT_COMPONENT(prompt)->complete = iks_copy(iq);
@@ -350,7 +350,7 @@ static iks *prompt_component_handle_output_error(struct rayo_actor *prompt, stru
 
                        /* forward IQ error to client */
                        iq = PROMPT_COMPONENT(prompt)->iq;
-                       iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent));
+                       iks_insert_attrib(iq, "from", RAYO_JID(prompt->parent));
                        iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid);
                        iks_insert_node(iq, iks_copy_within(error, iks_stack(iq)));
                        RAYO_SEND_REPLY(prompt, RAYO_COMPONENT(prompt)->client_jid, iq);
index d9474022f25a1e3680ec39f0c8014867380746e8..20d857377c0379af78eef853d3ea695e0e925ab0 100644 (file)
@@ -84,7 +84,7 @@ struct record_component {
 static void complete_record(struct rayo_component *component, const char *reason, const char *reason_namespace)
 {
        switch_core_session_t *session = NULL;
-       const char *uuid = component->parent->id;
+       const char *uuid = RAYO_ACTOR(component)->parent->id;
        const char *uri = RECORD_COMPONENT(component)->local_file_path;
        iks *recording;
        switch_size_t file_size = 0;
@@ -296,7 +296,7 @@ static iks *start_call_record_component(struct rayo_actor *call, struct rayo_mes
 static iks *stop_call_record_component(struct rayo_actor *component, struct rayo_message *msg, void *data)
 {
        iks *iq = msg->payload;
-       switch_core_session_t *session = switch_core_session_locate(RAYO_COMPONENT(component)->parent->id);
+       switch_core_session_t *session = switch_core_session_locate(component->parent->id);
        if (session) {
                RECORD_COMPONENT(component)->stop = 1;
                switch_ivr_stop_record_session(session, RAYO_ID(component));
@@ -383,7 +383,7 @@ static int start_mixer_record(struct rayo_component *component)
        char *args;
        SWITCH_STANDARD_STREAM(stream);
 
-       args = switch_mprintf("%s recording start %s", component->parent->id, RAYO_ID(component));
+       args = switch_mprintf("%s recording start %s", RAYO_ACTOR(component)->parent->id, RAYO_ID(component));
        switch_api_execute("conference", args, NULL, &stream);
        switch_safe_free(args);
        switch_safe_free(stream.data);
@@ -439,7 +439,7 @@ static iks *stop_mixer_record_component(struct rayo_actor *component, struct ray
        SWITCH_STANDARD_STREAM(stream);
 
        RECORD_COMPONENT(component)->stop = 1;
-       args = switch_mprintf("%s recording stop %s", RAYO_COMPONENT(component)->parent->id, RAYO_ID(component));
+       args = switch_mprintf("%s recording stop %s", component->parent->id, RAYO_ID(component));
        switch_api_execute("conference", args, NULL, &stream);
        switch_safe_free(args);
        switch_safe_free(stream.data);