Index: pjproject/trunk/pjlib-util/src/pjlib-util/resolver.c
===================================================================
--- pjproject/trunk/pjlib-util/src/pjlib-util/resolver.c	(revision 5612)
+++ pjproject/trunk/pjlib-util/src/pjlib-util/resolver.c	(revision 5826)
@@ -170,5 +170,5 @@
     /* Internals */
     pj_pool_t		*pool;		/**< Internal pool.		    */
-    pj_mutex_t		*mutex;		/**< Mutex protection.		    */
+    pj_grp_lock_t	*grp_lock;	/**< Group lock protection.	    */
     pj_bool_t		 own_timer;	/**< Do we own timer?		    */
     pj_timer_heap_t	*timer;		/**< Timer instance.		    */
@@ -237,4 +237,6 @@
 				      unsigned servers[]);
 
+/* Destructor */
+static void dns_resolver_on_destroy(void *member);
 
 /* Close UDP socket */
@@ -285,7 +287,7 @@
     pj_bzero(&socket_cb, sizeof(socket_cb));
     socket_cb.on_read_complete = &on_read_complete;
-    status = pj_ioqueue_register_sock(resv->pool, resv->ioqueue,
-				      resv->udp_sock, resv, &socket_cb,
-				      &resv->udp_key);
+    status = pj_ioqueue_register_sock2(resv->pool, resv->ioqueue,
+				       resv->udp_sock, resv->grp_lock,
+				       resv, &socket_cb, &resv->udp_key);
     if (status != PJ_SUCCESS)
 	return status;
@@ -332,7 +334,7 @@
     pj_bzero(&socket_cb, sizeof(socket_cb));
     socket_cb.on_read_complete = &on_read_complete;
-    status = pj_ioqueue_register_sock(resv->pool, resv->ioqueue,
-				      resv->udp6_sock, resv, &socket_cb,
-				      &resv->udp6_key);
+    status = pj_ioqueue_register_sock2(resv->pool, resv->ioqueue,
+				       resv->udp6_sock, resv->grp_lock,
+				       resv, &socket_cb, &resv->udp6_key);
     if (status != PJ_SUCCESS)
 	return status;
@@ -403,8 +405,12 @@
     pj_strdup2_with_null(pool, &resv->name, name);
     
-    /* Create the mutex */
-    status = pj_mutex_create_recursive(pool, name, &resv->mutex);
+    /* Create group lock */
+    status = pj_grp_lock_create_w_handler(pool, NULL, resv,
+					  &dns_resolver_on_destroy,
+					  &resv->grp_lock); 
     if (status != PJ_SUCCESS)
 	goto on_error;
+
+    pj_grp_lock_add_ref(resv->grp_lock);
 
     /* Timer, ioqueue, and settings */
@@ -418,4 +424,5 @@
     /* Create the timer heap if one is not specified */
     if (resv->timer == NULL) {
+	resv->own_timer = PJ_TRUE;
 	status = pj_timer_heap_create(pool, TIMER_SIZE, &resv->timer);
 	if (status != PJ_SUCCESS)
@@ -425,4 +432,5 @@
     /* Create the ioqueue if one is not specified */
     if (resv->ioqueue == NULL) {
+	resv->own_ioqueue = PJ_TRUE;
 	status = pj_ioqueue_create(pool, MAX_FD, &resv->ioqueue);
 	if (status != PJ_SUCCESS)
@@ -450,4 +458,11 @@
     pj_dns_resolver_destroy(resv, PJ_FALSE);
     return status;
+}
+
+
+void dns_resolver_on_destroy(void *member)
+{
+    pj_dns_resolver *resolver = (pj_dns_resolver*)member;
+    pj_pool_safe_release(&resolver->pool);
 }
 
@@ -509,10 +524,5 @@
     }
 
-    if (resolver->mutex) {
-	pj_mutex_destroy(resolver->mutex);
-	resolver->mutex = NULL;
-    }
-
-    pj_pool_safe_release(&resolver->pool);
+    pj_grp_lock_dec_ref(resolver->grp_lock);
 
     return PJ_SUCCESS;
@@ -536,5 +546,5 @@
     PJ_ASSERT_RETURN(count < PJ_DNS_RESOLVER_MAX_NS, PJ_EINVAL);
 
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
 
     if (count > PJ_DNS_RESOLVER_MAX_NS)
@@ -555,5 +565,5 @@
 				      (pj_uint16_t)(ports ? ports[i] : PORT));
 	if (status != PJ_SUCCESS) {
-	    pj_mutex_unlock(resolver->mutex);
+	    pj_grp_lock_release(resolver->grp_lock);
 	    return PJLIB_UTIL_EDNSINNSADDR;
 	}
@@ -566,5 +576,5 @@
     resolver->ns_count = count;
 
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
     return PJ_SUCCESS;
 }
@@ -580,7 +590,7 @@
     PJ_ASSERT_RETURN(resolver && st, PJ_EINVAL);
 
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
     pj_memcpy(&resolver->settings, st, sizeof(*st));
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
     return PJ_SUCCESS;
 }
@@ -595,7 +605,7 @@
     PJ_ASSERT_RETURN(resolver && st, PJ_EINVAL);
 
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
     pj_memcpy(st, &resolver->settings, sizeof(*st));
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
     return PJ_SUCCESS;
 }
@@ -610,7 +620,7 @@
     PJ_ASSERT_ON_FAIL(resolver, return);
 
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
     pj_timer_heap_poll(resolver->timer, NULL);
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
 
     pj_ioqueue_poll(resolver->ioqueue, timeout);
@@ -684,5 +694,8 @@
     delay.msec = resolver->settings.qretr_delay;
     pj_time_val_normalize(&delay);
-    status = pj_timer_heap_schedule(resolver->timer, &q->timer_entry, &delay);
+    status = pj_timer_heap_schedule_w_grp_lock(resolver->timer,
+					       &q->timer_entry,
+					       &delay, 1,
+					       resolver->grp_lock);
     if (status != PJ_SUCCESS) {
 	return status;
@@ -874,5 +887,5 @@
 
     /* Start working with the resolver */
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
 
     /* Get current time. */
@@ -907,5 +920,5 @@
 	     */
 	    cache->ref_cnt++;
-	    pj_mutex_unlock(resolver->mutex);
+	    pj_grp_lock_release(resolver->grp_lock);
 
 	    /* This cached response is still valid. Just return this
@@ -917,5 +930,5 @@
 
 	    /* Done. No host resolution is necessary */
-	    pj_mutex_lock(resolver->mutex);
+	    pj_grp_lock_acquire(resolver->grp_lock);
 
 	    /* Decrement the ref counter. Also check if it is time to free
@@ -934,5 +947,5 @@
              * Refer to ticket #1974.
 	     */
-	    pj_mutex_unlock(resolver->mutex);
+	    pj_grp_lock_release(resolver->grp_lock);
 	    return status;
 	}
@@ -1001,5 +1014,5 @@
 	*p_query = p_q;
 
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
     return status;
 }
@@ -1016,5 +1029,10 @@
     PJ_ASSERT_RETURN(query, PJ_EINVAL);
 
-    pj_mutex_lock(query->resolver->mutex);
+    pj_grp_lock_acquire(query->resolver->grp_lock);
+
+    if (query->timer_entry.id == 1) {
+	pj_timer_heap_cancel_if_active(query->resolver->timer,
+				       &query->timer_entry, 0);
+    }
 
     cb = query->cb;
@@ -1024,5 +1042,5 @@
 	(*cb)(query->user_data, PJ_ECANCELLED, NULL);
 
-    pj_mutex_unlock(query->resolver->mutex);
+    pj_grp_lock_release(query->resolver->grp_lock);
     return PJ_SUCCESS;
 }
@@ -1553,5 +1571,5 @@
     resolver = q->resolver;
 
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
 
     /* Recheck that this query is still pending, since there is a slight
@@ -1561,5 +1579,5 @@
     if (pj_hash_get(resolver->hquerybyid, &q->id, sizeof(q->id), NULL)==NULL) {
 	/* Yeah, this query is done. */
-	pj_mutex_unlock(resolver->mutex);
+	pj_grp_lock_release(resolver->grp_lock);
 	return;
     }
@@ -1572,5 +1590,5 @@
 	status = transmit_query(resolver, q);
 	if (status == PJ_SUCCESS) {
-	    pj_mutex_unlock(resolver->mutex);
+	    pj_grp_lock_release(resolver->grp_lock);
 	    return;
 	} else {
@@ -1591,5 +1609,5 @@
 
     /* Workaround for deadlock problem in #1565 (similar to #1108) */
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
 
     /* Call application callback, if any. */
@@ -1606,5 +1624,5 @@
 
     /* Workaround for deadlock problem in #1565 (similar to #1108) */
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
 
     /* Clear data */
@@ -1623,5 +1641,5 @@
     pj_list_push_back(&resolver->query_free_nodes, q);
 
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
 }
 
@@ -1663,5 +1681,5 @@
     }
 
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
 
 
@@ -1746,5 +1764,5 @@
 
     /* Workaround for deadlock problem in #1108 */
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
 
     /* Notify applications first, to allow application to modify the 
@@ -1767,5 +1785,5 @@
 
     /* Workaround for deadlock problem in #1108 */
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
 
     /* Save/update response cache. */
@@ -1796,5 +1814,5 @@
 				 src_addr, src_addr_len);
 
-    if (status != PJ_EPENDING) {
+    if (status != PJ_EPENDING && status != PJ_ECANCELLED) {
 	char errmsg[PJ_ERR_MSG_SIZE];
 
@@ -1806,5 +1824,5 @@
     }
 
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
 }
 
@@ -1832,5 +1850,5 @@
 		     PJLIB_UTIL_EDNSNOANSWERREC);
 
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
 
     /* Build resource key for looking up hash tables */
@@ -1854,5 +1872,5 @@
     update_res_cache(resolver, &key, PJ_SUCCESS, set_ttl, pkt);
 
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
 
     return PJ_SUCCESS;
@@ -1869,7 +1887,7 @@
     PJ_ASSERT_RETURN(resolver, 0);
 
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
     count = pj_hash_count(resolver->hrescache);
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
 
     return count;
@@ -1887,5 +1905,5 @@
     pj_time_val now;
 
-    pj_mutex_lock(resolver->mutex);
+    pj_grp_lock_acquire(resolver->grp_lock);
 
     pj_gettimeofday(&now);
@@ -1947,5 +1965,5 @@
 	      pj_pool_get_used_size(resolver->pool)));
 
-    pj_mutex_unlock(resolver->mutex);
+    pj_grp_lock_release(resolver->grp_lock);
 #endif
 }
