bus->listen() and the controller wrappers accept a timeout to wait for callbacks
authorMartin Willi <martin@revosec.ch>
Fri, 26 Aug 2011 08:42:42 +0000 (10:42 +0200)
committerMartin Willi <martin@revosec.ch>
Fri, 26 Aug 2011 08:44:25 +0000 (10:44 +0200)
14 files changed:
src/conftest/actions.c
src/libcharon/bus/bus.c
src/libcharon/bus/bus.h
src/libcharon/control/controller.c
src/libcharon/control/controller.h
src/libcharon/plugins/load_tester/load_tester_plugin.c
src/libcharon/plugins/maemo/maemo_service.c
src/libcharon/plugins/medcli/medcli_config.c
src/libcharon/plugins/nm/nm_service.c
src/libcharon/plugins/smp/smp.c
src/libcharon/plugins/stroke/stroke_control.c
src/libcharon/plugins/uci/uci_control.c
src/libcharon/processing/jobs/initiate_mediation_job.c
src/libcharon/processing/jobs/start_action_job.c

index 1844d0c..7532e95 100644 (file)
@@ -65,7 +65,7 @@ static job_requeue_t initiate(char *config)
        {
                DBG1(DBG_CFG, "initiating IKE_SA for CHILD_SA config '%s'", config);
                charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
-                                                                        NULL, NULL);
+                                                                        NULL, NULL, 0);
        }
        else
        {
@@ -207,7 +207,7 @@ static job_requeue_t close_ike(char *config)
        if (id)
        {
                DBG1(DBG_CFG, "closing IKE_SA '%s'", config);
-               charon->controller->terminate_ike(charon->controller, id, NULL, NULL);
+               charon->controller->terminate_ike(charon->controller, id, NULL, NULL, 0);
        }
        else
        {
@@ -246,7 +246,8 @@ static job_requeue_t close_child(char *config)
        if (id)
        {
                DBG1(DBG_CFG, "closing CHILD_SA '%s'", config);
-               charon->controller->terminate_child(charon->controller, id, NULL, NULL);
+               charon->controller->terminate_child(charon->controller, id,
+                                                                                       NULL, NULL, 0);
        }
        else
        {
index f2f59d7..74bd0ec 100644 (file)
@@ -151,11 +151,20 @@ static void listener_cleanup(cleanup_data_t *data)
        entry_destroy(data->entry);
 }
 
-METHOD(bus_t, listen_, void,
-       private_bus_t *this, listener_t *listener, job_t *job)
+METHOD(bus_t, listen_, bool,
+       private_bus_t *this, listener_t *listener, job_t *job, u_int timeout)
 {
-       bool old;
+       bool old, timed_out = FALSE;
        cleanup_data_t data;
+       timeval_t tv, add;
+
+       if (timeout)
+       {
+               add.tv_sec = timeout / 1000;
+               add.tv_usec = (timeout - (add.tv_sec * 1000)) * 1000;
+               time_monotonic(&tv);
+               timeradd(&tv, &add, &tv);
+       }
 
        data.this = this;
        data.entry = entry_create(listener, TRUE);
@@ -168,13 +177,26 @@ METHOD(bus_t, listen_, void,
        old = thread_cancelability(TRUE);
        while (data.entry->blocker)
        {
-               data.entry->condvar->wait(data.entry->condvar, this->mutex);
+               if (timeout)
+               {
+                       if (data.entry->condvar->timed_wait_abs(data.entry->condvar,
+                                                                                                   this->mutex, tv))
+                       {
+                               timed_out = TRUE;
+                               break;
+                       }
+               }
+               else
+               {
+                       data.entry->condvar->wait(data.entry->condvar, this->mutex);
+               }
        }
        thread_cancelability(old);
        thread_cleanup_pop(FALSE);
        /* unlock mutex */
        thread_cleanup_pop(TRUE);
        entry_destroy(data.entry);
+       return timed_out;
 }
 
 METHOD(bus_t, set_sa, void,
index 2ade796..69060d3 100644 (file)
@@ -152,8 +152,10 @@ struct bus_t {
         *
         * @param listener      listener to register
         * @param job           job to execute asynchronously when registered, or NULL
+        * @param timeout       max timeout in ms to listen for events, 0 to disable
+        * @return                      TRUE if timed out
         */
-       void (*listen)(bus_t *this, listener_t *listener, job_t *job);
+       bool (*listen)(bus_t *this, listener_t *listener, job_t *job, u_int timeout);
 
        /**
         * Set the IKE_SA the calling thread is using.
index 5317971..0f24796 100644 (file)
@@ -240,7 +240,7 @@ METHOD(job_t, initiate_execute, void,
 
 METHOD(controller_t, initiate, status_t,
        private_controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
-       controller_cb_t callback, void *param)
+       controller_cb_t callback, void *param, u_int timeout)
 {
        interface_job_t job = {
                .listener = {
@@ -267,7 +267,11 @@ METHOD(controller_t, initiate, status_t,
        }
        else
        {
-               charon->bus->listen(charon->bus, &job.listener.public, &job.public);
+               if (charon->bus->listen(charon->bus, &job.listener.public, &job.public,
+                                                               timeout))
+               {
+                       job.listener.status = OUT_OF_RES;
+               }
        }
        return job.listener.status;
 }
@@ -296,7 +300,7 @@ METHOD(job_t, terminate_ike_execute, void,
 
 METHOD(controller_t, terminate_ike, status_t,
        controller_t *this, u_int32_t unique_id,
-       controller_cb_t callback, void *param)
+       controller_cb_t callback, void *param, u_int timeout)
 {
        ike_sa_t *ike_sa;
        interface_job_t job = {
@@ -333,7 +337,11 @@ METHOD(controller_t, terminate_ike, status_t,
        }
        else
        {
-               charon->bus->listen(charon->bus, &job.listener.public, &job.public);
+               if (charon->bus->listen(charon->bus, &job.listener.public, &job.public,
+                                                               timeout))
+               {
+                       job.listener.status = OUT_OF_RES;
+               }
                /* checkin of the ike_sa happened in the thread that executed the job */
                charon->bus->set_sa(charon->bus, NULL);
        }
@@ -363,7 +371,8 @@ METHOD(job_t, terminate_child_execute, void,
 }
 
 METHOD(controller_t, terminate_child, status_t,
-       controller_t *this, u_int32_t reqid, controller_cb_t callback, void *param)
+       controller_t *this, u_int32_t reqid,
+       controller_cb_t callback, void *param, u_int timeout)
 {
        ike_sa_t *ike_sa;
        child_sa_t *child_sa;
@@ -424,7 +433,11 @@ METHOD(controller_t, terminate_child, status_t,
        }
        else
        {
-               charon->bus->listen(charon->bus, &job.listener.public, &job.public);
+               if (charon->bus->listen(charon->bus, &job.listener.public, &job.public,
+                                                               timeout))
+               {
+                       job.listener.status = OUT_OF_RES;
+               }
                /* checkin of the ike_sa happened in the thread that executed the job */
                charon->bus->set_sa(charon->bus, NULL);
        }
index 81c83d9..6adaef1 100644 (file)
@@ -83,14 +83,16 @@ struct controller_t {
         * @param child_cfg             child_cfg to set up CHILD_SA from
         * @param cb                    logging callback
         * @param param                 parameter to include in each call of cb
+        * @param timeout               timeout in ms to wait for callbacks, 0 to disable
         * @return
         *                                              - SUCCESS, if CHILD_SA established
         *                                              - FAILED, if setup failed
         *                                              - NEED_MORE, if callback returned FALSE
+        *                                              - OUT_OF_RES if timed out
         */
        status_t (*initiate)(controller_t *this,
                                                 peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
-                                                controller_cb_t callback, void *param);
+                                                controller_cb_t callback, void *param, u_int timeout);
 
        /**
         * Terminate an IKE_SA and all of its CHILD_SAs.
@@ -102,13 +104,16 @@ struct controller_t {
         * @param unique_id             unique id of the IKE_SA to terminate.
         * @param cb                    logging callback
         * @param param                 parameter to include in each call of cb
+        * @param timeout               timeout in ms to wait for callbacks, 0 to disable
         * @return
         *                                              - SUCCESS, if CHILD_SA terminated
         *                                              - NOT_FOUND, if no such CHILD_SA found
         *                                              - NEED_MORE, if callback returned FALSE
+        *                                              - OUT_OF_RES if timed out
         */
        status_t (*terminate_ike)(controller_t *this, u_int32_t unique_id,
-                                                         controller_cb_t callback, void *param);
+                                                         controller_cb_t callback, void *param,
+                                                         u_int timeout);
 
        /**
         * Terminate a CHILD_SA.
@@ -116,13 +121,16 @@ struct controller_t {
         * @param reqid                 reqid of the CHILD_SA to terminate
         * @param cb                    logging callback
         * @param param                 parameter to include in each call of cb
+        * @param timeout               timeout in ms to wait for callbacks, 0 to disable
         * @return
         *                                              - SUCCESS, if CHILD_SA terminated
         *                                              - NOT_FOUND, if no such CHILD_SA found
         *                                              - NEED_MORE, if callback returned FALSE
+        *                                              - OUT_OF_RES if timed out
         */
        status_t (*terminate_child)(controller_t *this, u_int32_t reqid,
-                                                               controller_cb_t callback, void *param);
+                                                               controller_cb_t callback, void *param,
+                                                               u_int timeout);
 
        /**
         * Destroy a controller_t instance.
index f274022..b260a97 100644 (file)
@@ -148,7 +148,7 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this)
 
                charon->controller->initiate(charon->controller,
                                        peer_cfg, child_cfg->get_ref(child_cfg),
-                                       NULL, NULL);
+                                       NULL, NULL, 0);
                if (s)
                {
                        sleep(s);
index d6ba8fa..6675e1d 100644 (file)
@@ -217,7 +217,7 @@ static void disconnect(private_maemo_service_t *this)
                id = ike_sa->get_unique_id(ike_sa);
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
                charon->controller->terminate_ike(charon->controller, id,
-                                                                                 NULL, NULL);
+                                                                                 NULL, NULL, 0);
        }
        this->current = (g_free(this->current), NULL);
        this->status = VPN_STATUS_DISCONNECTED;
index 52bbd6d..cc6662b 100644 (file)
@@ -335,7 +335,7 @@ static job_requeue_t initiate_config(peer_cfg_t *peer_cfg)
                peer_cfg->get_ref(peer_cfg);
                enumerator->destroy(enumerator);
                charon->controller->initiate(charon->controller,
-                                                                        peer_cfg, child_cfg, NULL, NULL);
+                                                                        peer_cfg, child_cfg, NULL, NULL, 0);
        }
        else
        {
index 65218d0..a6783fc 100644 (file)
@@ -640,7 +640,7 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err)
                        id = ike_sa->get_unique_id(ike_sa);
                        enumerator->destroy(enumerator);
                        charon->controller->terminate_ike(charon->controller, id,
-                                                                                         controller_cb_empty, NULL);
+                                                                                         controller_cb_empty, NULL, 0);
                        return TRUE;
                }
        }
index ea54dbf..68935aa 100644 (file)
@@ -421,14 +421,14 @@ static void request_control_terminate(xmlTextReaderPtr reader,
                if (ike)
                {
                        status = charon->controller->terminate_ike(
-                                       charon->controller,     id,
-                                       (controller_cb_t)xml_callback, writer);
+                                       charon->controller, id,
+                                       (controller_cb_t)xml_callback, writer, 0);
                }
                else
                {
                        status = charon->controller->terminate_child(
-                                       charon->controller,     id,
-                                       (controller_cb_t)xml_callback, writer);
+                                       charon->controller, id,
+                                       (controller_cb_t)xml_callback, writer, 0);
                }
                /* </log> */
                xmlTextWriterEndElement(writer);
@@ -490,7 +490,7 @@ static void request_control_initiate(xmlTextReaderPtr reader,
                        {
                                status = charon->controller->initiate(charon->controller,
                                                        peer, child, (controller_cb_t)xml_callback,
-                                                       writer);
+                                                       writer, 0);
                        }
                        else
                        {
index 972606d..f0d8f3b 100644 (file)
@@ -103,14 +103,14 @@ static void charon_initiate(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
        if (msg->output_verbosity < 0)
        {
                charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
-                                                                        NULL, NULL);
+                                                                        NULL, NULL, 0);
        }
        else
        {
                stroke_log_info_t info = { msg->output_verbosity, out };
 
                charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
-                                                                        (controller_cb_t)stroke_log, &info);
+                                                                        (controller_cb_t)stroke_log, &info, 0);
        }
 }
 
@@ -277,12 +277,12 @@ METHOD(stroke_control_t, terminate, void,
                if (child)
                {
                        charon->controller->terminate_child(charon->controller, id,
-                                                                       (controller_cb_t)stroke_log, &info);
+                                                                       (controller_cb_t)stroke_log, &info, 0);
                }
                else
                {
                        charon->controller->terminate_ike(charon->controller, id,
-                                                                       (controller_cb_t)stroke_log, &info);
+                                                                       (controller_cb_t)stroke_log, &info, 0);
                }
                return;
        }
@@ -333,7 +333,7 @@ METHOD(stroke_control_t, terminate, void,
        while (enumerator->enumerate(enumerator, &del))
        {
                charon->controller->terminate_child(charon->controller, del,
-                                                                       (controller_cb_t)stroke_log, &info);
+                                                                       (controller_cb_t)stroke_log, &info, 0);
        }
        enumerator->destroy(enumerator);
 
@@ -341,7 +341,7 @@ METHOD(stroke_control_t, terminate, void,
        while (enumerator->enumerate(enumerator, &del))
        {
                charon->controller->terminate_ike(charon->controller, del,
-                                                                       (controller_cb_t)stroke_log, &info);
+                                                                       (controller_cb_t)stroke_log, &info, 0);
        }
        enumerator->destroy(enumerator);
 
@@ -515,7 +515,7 @@ METHOD(stroke_control_t, purge_ike, void,
        while (enumerator->enumerate(enumerator, &del))
        {
                charon->controller->terminate_ike(charon->controller, del,
-                                                                       (controller_cb_t)stroke_log, &info);
+                                                                       (controller_cb_t)stroke_log, &info, 0);
        }
        enumerator->destroy(enumerator);
        list->destroy(list);
@@ -544,7 +544,7 @@ static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
                }
        }
        else
-       {       
+       {
                if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
                {
                        fprintf(out, "'%s' routed\n", name);
index caf8acf..bb08de2 100644 (file)
@@ -148,8 +148,8 @@ static void initiate(private_uci_control_t *this, char *name)
                enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
                if (enumerator->enumerate(enumerator, &child_cfg) &&
                        charon->controller->initiate(charon->controller, peer_cfg,
-                                                                                child_cfg->get_ref(child_cfg),
-                                                                                controller_cb_empty, NULL) == SUCCESS)
+                                                               child_cfg->get_ref(child_cfg),
+                                                               controller_cb_empty, NULL, 0) == SUCCESS)
                {
                        write_fifo(this, "connection '%s' established\n", name);
                }
@@ -183,7 +183,7 @@ static void terminate(private_uci_control_t *this, char *name)
                        id = ike_sa->get_unique_id(ike_sa);
                        enumerator->destroy(enumerator);
                        charon->controller->terminate_ike(charon->controller, id,
-                                                                                         controller_cb_empty, NULL);
+                                                                                         controller_cb_empty, NULL, 0);
                        write_fifo(this, "connection '%s' terminated\n", name);
                        return;
                }
index b310c81..183484a 100644 (file)
@@ -126,7 +126,7 @@ static void initiate(private_initiate_mediation_job_t *this)
                mediation_cfg->get_ref(mediation_cfg);
 
                if (charon->controller->initiate(charon->controller, mediation_cfg,
-                                       NULL, (controller_cb_t)initiate_callback, this) != SUCCESS)
+                               NULL, (controller_cb_t)initiate_callback, this, 0) != SUCCESS)
                {
                        mediation_cfg->destroy(mediation_cfg);
                        mediated_cfg->destroy(mediated_cfg);
index 8f924bc..35f70e1 100644 (file)
@@ -66,7 +66,7 @@ METHOD(job_t, execute, void,
                                        charon->controller->initiate(charon->controller,
                                                                                                 peer_cfg->get_ref(peer_cfg),
                                                                                                 child_cfg->get_ref(child_cfg),
-                                                                                                NULL, NULL);
+                                                                                                NULL, NULL, 0);
                                        break;
                                case ACTION_ROUTE:
                                        DBG1(DBG_JOB, "start action: route '%s'", name);