Author: file
Date: Mon Mar 16 10:55:38 2015
New Revision: 432997

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=432997
Log:
Hide an asynchronous query behind an opaque structure so results can not be 
retrieved until the callback is invoked.

Modified:
    team/group/dns/include/asterisk/dns_core.h
    team/group/dns/include/asterisk/dns_internal.h
    team/group/dns/main/dns_core.c
    team/group/dns/main/dns_recurring.c
    team/group/dns/res/res_resolver_unbound.c
    team/group/dns/tests/test_dns.c

Modified: team/group/dns/include/asterisk/dns_core.h
URL: 
http://svnview.digium.com/svn/asterisk/team/group/dns/include/asterisk/dns_core.h?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/include/asterisk/dns_core.h (original)
+++ team/group/dns/include/asterisk/dns_core.h Mon Mar 16 10:55:38 2015
@@ -28,6 +28,9 @@
 extern "C" {
 #endif
 
+/*! \brief Opaque structure for an active DNS query */
+struct ast_dns_query_active;
+
 /*! \brief Opaque structure for a DNS query */
 struct ast_dns_query;
 
@@ -220,21 +223,21 @@
  *
  * \note This function increments the reference count of the user data, it 
does NOT steal
  *
- * \note The query must be released upon completion or cancellation using 
ao2_ref
- */
-struct ast_dns_query *ast_dns_resolve_async(const char *name, int rr_type, int 
rr_class, ast_dns_resolve_callback callback, void *data);
+ * \note The active query must be released upon completion or cancellation 
using ao2_ref
+ */
+struct ast_dns_query_active *ast_dns_resolve_async(const char *name, int 
rr_type, int rr_class, ast_dns_resolve_callback callback, void *data);
 
 /*!
  * \brief Cancel an asynchronous DNS resolution
  *
- * \param query The DNS query returned from ast_dns_resolve_async
+ * \param active The active DNS query returned from ast_dns_resolve_async
  *
  * \retval 0 success
  * \retval -1 failure
  *
  * \note If successfully cancelled the callback will not be invoked
  */
-int ast_dns_resolve_cancel(struct ast_dns_query *query);
+int ast_dns_resolve_cancel(struct ast_dns_query_active *active);
 
 /*!
  * \brief Synchronously resolve a DNS query

Modified: team/group/dns/include/asterisk/dns_internal.h
URL: 
http://svnview.digium.com/svn/asterisk/team/group/dns/include/asterisk/dns_internal.h?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/include/asterisk/dns_internal.h (original)
+++ team/group/dns/include/asterisk/dns_internal.h Mon Mar 16 10:55:38 2015
@@ -106,14 +106,13 @@
 };
 
 /*! \brief A recurring DNS query */
-struct ast_dns_query_recurring
-{
+struct ast_dns_query_recurring {
        /*! \brief Callback to invoke upon completion */
        ast_dns_resolve_callback callback;
        /*! \brief User-specific data */
        void *user_data;
        /*! \brief Current active query */
-       struct ast_dns_query *query;
+       struct ast_dns_query_active *active;
        /*! \brief The recurring query has been cancelled */
        unsigned int cancelled;
        /*! \brief Scheduled timer for next resolution */
@@ -126,6 +125,12 @@
        char name[0];
 };
 
+/*! \brief An active DNS query */
+struct ast_dns_query_active {
+       /*! \brief The underlying DNS query */
+       struct ast_dns_query *query;
+};
+
 struct ast_sched_context;
 
 /*!

Modified: team/group/dns/main/dns_core.c
URL: 
http://svnview.digium.com/svn/asterisk/team/group/dns/main/dns_core.c?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/main/dns_core.c (original)
+++ team/group/dns/main/dns_core.c Mon Mar 16 10:55:38 2015
@@ -162,6 +162,14 @@
        return AST_LIST_NEXT(record, list);
 }
 
+/*! \brief Destructor for an active DNS query */
+static void dns_query_active_destroy(void *data)
+{
+       struct ast_dns_query_active *active = data;
+
+       ao2_cleanup(active->query);
+}
+
 /*! \brief \brief Destructor for a DNS query */
 static void dns_query_destroy(void *data)
 {
@@ -172,9 +180,9 @@
        ast_dns_result_free(query->result);
 }
 
-struct ast_dns_query *ast_dns_resolve_async(const char *name, int rr_type, int 
rr_class, ast_dns_resolve_callback callback, void *data)
-{
-       struct ast_dns_query *query;
+struct ast_dns_query_active *ast_dns_resolve_async(const char *name, int 
rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
+{
+       struct ast_dns_query_active *active;
 
        if (ast_strlen_zero(name)) {
                ast_log(LOG_WARNING, "Could not perform asynchronous 
resolution, no name provided\n");
@@ -201,41 +209,46 @@
                return NULL;
        }
 
-       query = ao2_alloc_options(sizeof(*query) + strlen(name) + 1, 
dns_query_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
-       if (!query) {
-               return NULL;
-       }
-
-       query->callback = callback;
-       query->user_data = ao2_bump(data);
-       query->rr_type = rr_type;
-       query->rr_class = rr_class;
-       strcpy(query->name, name); /* SAFE */
+       active = ao2_alloc_options(sizeof(*active), dns_query_active_destroy, 
AO2_ALLOC_OPT_LOCK_NOLOCK);
+       if (!active) {
+               return NULL;
+       }
+
+       active->query = ao2_alloc_options(sizeof(*active->query) + strlen(name) 
+ 1, dns_query_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
+       if (!active->query) {
+               return NULL;
+       }
+
+       active->query->callback = callback;
+       active->query->user_data = ao2_bump(data);
+       active->query->rr_type = rr_type;
+       active->query->rr_class = rr_class;
+       strcpy(active->query->name, name); /* SAFE */
 
        AST_RWLIST_RDLOCK(&resolvers);
-       query->resolver = AST_RWLIST_FIRST(&resolvers);
+       active->query->resolver = AST_RWLIST_FIRST(&resolvers);
        AST_RWLIST_UNLOCK(&resolvers);
 
-       if (!query->resolver) {
+       if (!active->query->resolver) {
                ast_log(LOG_ERROR, "Attempted to do a DNS query for '%s' of 
class '%d' and type '%d' but no resolver is available\n",
                        name, rr_class, rr_type);
-               ao2_ref(query, -1);
-               return NULL;
-       }
-
-       if (query->resolver->resolve(query)) {
+               ao2_ref(active, -1);
+               return NULL;
+       }
+
+       if (active->query->resolver->resolve(active->query)) {
                ast_log(LOG_ERROR, "Resolver '%s' returned an error when 
resolving '%s' of class '%d' and type '%d'\n",
-                       query->resolver->name, name, rr_class, rr_type);
-               ao2_ref(query, -1);
-               return NULL;
-       }
-
-       return query;
-}
-
-int ast_dns_resolve_cancel(struct ast_dns_query *query)
-{
-       return query->resolver->cancel(query);
+                       active->query->resolver->name, name, rr_class, rr_type);
+               ao2_ref(active, -1);
+               return NULL;
+       }
+
+       return active;
+}
+
+int ast_dns_resolve_cancel(struct ast_dns_query_active *active)
+{
+       return active->query->resolver->cancel(active->query);
 }
 
 /*! \brief Structure used for signaling back for synchronous resolution 
completion */
@@ -278,7 +291,7 @@
 int ast_dns_resolve(const char *name, int rr_type, int rr_class, struct 
ast_dns_result **result)
 {
        struct dns_synchronous_resolve *synchronous;
-       struct ast_dns_query *query;
+       struct ast_dns_query_active *active;
 
        if (ast_strlen_zero(name)) {
                ast_log(LOG_WARNING, "Could not perform synchronous resolution, 
no name provided\n");
@@ -313,15 +326,15 @@
        ast_mutex_init(&synchronous->lock);
        ast_cond_init(&synchronous->cond, NULL);
 
-       query = ast_dns_resolve_async(name, rr_type, rr_class, 
dns_synchronous_resolve_callback, synchronous);
-       if (query) {
+       active = ast_dns_resolve_async(name, rr_type, rr_class, 
dns_synchronous_resolve_callback, synchronous);
+       if (active) {
                /* Wait for resolution to complete */
                ast_mutex_lock(&synchronous->lock);
                while (!synchronous->completed) {
                        ast_cond_wait(&synchronous->cond, &synchronous->lock);
                }
                ast_mutex_unlock(&synchronous->lock);
-               ao2_ref(query, -1);
+               ao2_ref(active, -1);
        }
 
        *result = synchronous->result;

Modified: team/group/dns/main/dns_recurring.c
URL: 
http://svnview.digium.com/svn/asterisk/team/group/dns/main/dns_recurring.c?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/main/dns_recurring.c (original)
+++ team/group/dns/main/dns_recurring.c Mon Mar 16 10:55:38 2015
@@ -59,7 +59,7 @@
        ao2_lock(recurring);
        recurring->timer = -1;
        if (!recurring->cancelled) {
-               recurring->query = ast_dns_resolve_async(recurring->name, 
recurring->rr_type, recurring->rr_class, 
dns_query_recurring_resolution_callback,
+               recurring->active = ast_dns_resolve_async(recurring->name, 
recurring->rr_type, recurring->rr_class, 
dns_query_recurring_resolution_callback,
                        recurring);
        }
        ao2_unlock(recurring);
@@ -93,7 +93,7 @@
                }
        }
 
-       ao2_replace(recurring->query, NULL);
+       ao2_replace(recurring->active, NULL);
        ao2_unlock(recurring);
 
        /* Since we stole the reference from the query we need to drop it 
ourselves */
@@ -120,8 +120,8 @@
        recurring->rr_class = rr_class;
        strcpy(recurring->name, name); /* SAFE */
 
-       recurring->query = ast_dns_resolve_async(name, rr_type, rr_class, 
dns_query_recurring_resolution_callback, recurring);
-       if (!recurring->query) {
+       recurring->active = ast_dns_resolve_async(name, rr_type, rr_class, 
dns_query_recurring_resolution_callback, recurring);
+       if (!recurring->active) {
                ao2_ref(recurring, -1);
                return NULL;
        }
@@ -138,9 +138,9 @@
        recurring->cancelled = 1;
        AST_SCHED_DEL_UNREF(ast_dns_get_sched(), recurring->timer, 
ao2_ref(recurring, -1));
 
-       if (recurring->query) {
-               res = ast_dns_resolve_cancel(recurring->query);
-               ao2_replace(recurring->query, NULL);
+       if (recurring->active) {
+               res = ast_dns_resolve_cancel(recurring->active);
+               ao2_replace(recurring->active, NULL);
        }
 
        ao2_unlock(recurring);

Modified: team/group/dns/res/res_resolver_unbound.c
URL: 
http://svnview.digium.com/svn/asterisk/team/group/dns/res/res_resolver_unbound.c?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/res/res_resolver_unbound.c (original)
+++ team/group/dns/res/res_resolver_unbound.c Mon Mar 16 10:55:38 2015
@@ -681,7 +681,7 @@
 static int async_run(struct ast_test *test, const char *domain, int rr_type,
                int rr_class, struct dns_record *records, size_t num_records)
 {
-       RAII_VAR(struct ast_dns_query *, query, NULL, ao2_cleanup);
+       RAII_VAR(struct ast_dns_query_active *, active, NULL, ao2_cleanup);
        RAII_VAR(struct async_data *, adata, NULL, ao2_cleanup);
        int i;
 
@@ -698,8 +698,8 @@
 
        ast_test_status_update(test, "Performing DNS query '%s', type %d\n", 
domain, rr_type);
 
-       query = ast_dns_resolve_async(domain, rr_type, rr_class, 
async_callback, adata);
-       if (!query) {
+       active = ast_dns_resolve_async(domain, rr_type, rr_class, 
async_callback, adata);
+       if (!active) {
                ast_test_status_update(test, "Failed to perform asynchronous 
resolution of domain %s\n", domain);
                return -1;
        }

Modified: team/group/dns/tests/test_dns.c
URL: 
http://svnview.digium.com/svn/asterisk/team/group/dns/tests/test_dns.c?view=diff&rev=432997&r1=432996&r2=432997
==============================================================================
--- team/group/dns/tests/test_dns.c (original)
+++ team/group/dns/tests/test_dns.c Mon Mar 16 10:55:38 2015
@@ -1005,7 +1005,7 @@
 AST_TEST_DEFINE(resolver_resolve_async)
 {
        RAII_VAR(struct async_resolution_data *, async_data, NULL, ao2_cleanup);
-       RAII_VAR(struct ast_dns_query *, query, NULL, ao2_cleanup);
+       RAII_VAR(struct ast_dns_query_active *, active, NULL, ao2_cleanup);
        struct ast_dns_result *result;
        enum ast_test_result_state res = AST_TEST_PASS;
        struct timespec timeout;
@@ -1039,8 +1039,8 @@
                goto cleanup;
        }
 
-       query = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, 
async_callback, async_data);
-       if (!query) {
+       active = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, 
async_callback, async_data);
+       if (!active) {
                ast_test_status_update(test, "Asynchronous resolution of 
address failed\n");
                res = AST_TEST_FAIL;
                goto cleanup;
@@ -1080,7 +1080,7 @@
                goto cleanup;
        }
 
-       result = ast_dns_query_get_result(query);
+       result = ast_dns_query_get_result(active->query);
        if (!result) {
                ast_test_status_update(test, "Asynchronous resolution yielded 
no result\n");
                res = AST_TEST_FAIL;
@@ -1128,7 +1128,7 @@
                { "asterisk.org", ns_t_a,       ns_c_in,      NULL },
        };
 
-       struct ast_dns_query *query;
+       struct ast_dns_query_active *active;
        enum ast_test_result_state res = AST_TEST_PASS;
        int i;
 
@@ -1155,11 +1155,11 @@
        }
 
        for (i = 0; i < ARRAY_LEN(resolves); ++i) {
-               query = ast_dns_resolve_async(resolves[i].name, 
resolves[i].rr_type, resolves[i].rr_class,
+               active = ast_dns_resolve_async(resolves[i].name, 
resolves[i].rr_type, resolves[i].rr_class,
                                resolves[i].callback, NULL);
-               if (query) {
+               if (active) {
                        ast_test_status_update(test, "Successfully performed 
asynchronous resolution with invalid data\n");
-                       ao2_ref(query, -1);
+                       ao2_ref(active, -1);
                        res = AST_TEST_FAIL;
                }
        }
@@ -1171,13 +1171,13 @@
                return AST_TEST_FAIL;
        }
 
-       query = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, 
stub_callback, NULL);
+       active = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, 
stub_callback, NULL);
 
        ast_dns_resolver_unregister(&terrible_resolver);
 
-       if (query) {
+       if (active) {
                ast_test_status_update(test, "Successfully performed 
asynchronous resolution with invalid data\n");
-               ao2_ref(query, -1);
+               ao2_ref(active, -1);
                return AST_TEST_FAIL;
        }
 
@@ -1187,7 +1187,7 @@
 AST_TEST_DEFINE(resolver_resolve_async_cancel)
 {
        RAII_VAR(struct async_resolution_data *, async_data, NULL, ao2_cleanup);
-       RAII_VAR(struct ast_dns_query *, query, NULL, ao2_cleanup);
+       RAII_VAR(struct ast_dns_query_active *, active, NULL, ao2_cleanup);
        struct ast_dns_result *result;
        enum ast_test_result_state res = AST_TEST_PASS;
        struct timespec timeout;
@@ -1221,8 +1221,8 @@
                goto cleanup;
        }
 
-       query = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, 
async_callback, async_data);
-       if (!query) {
+       active = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, 
async_callback, async_data);
+       if (!active) {
                ast_test_status_update(test, "Asynchronous resolution of 
address failed\n");
                res = AST_TEST_FAIL;
                goto cleanup;
@@ -1240,7 +1240,7 @@
                goto cleanup;
        }
 
-       ast_dns_resolve_cancel(query);
+       ast_dns_resolve_cancel(active);
 
        if (!test_resolver_data.canceled) {
                ast_test_status_update(test, "Resolver's cancel() method was 
not called\n");
@@ -1270,7 +1270,7 @@
                goto cleanup;
        }
 
-       result = ast_dns_query_get_result(query);
+       result = ast_dns_query_get_result(active->query);
        if (result) {
                ast_test_status_update(test, "Canceled resolution had a 
result\n");
                res = AST_TEST_FAIL;


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to