Index: pjproject/trunk/pjlib/include/pj/lock.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/lock.h	(revision 4991)
+++ pjproject/trunk/pjlib/include/pj/lock.h	(revision 4992)
@@ -219,4 +219,25 @@
 
 /**
+ * Create a group lock object, with the specified destructor handler, to be
+ * called by the group lock when it is about to be destroyed. Initially the
+ * group lock will have reference counter of one.
+ *
+ * @param pool		The group lock only uses the pool parameter to get
+ * 			the pool factory, from which it will create its own
+ * 			pool.
+ * @param cfg		Optional configuration.
+ * @param member	A pointer to be passed to the handler.
+ * @param handler	The destroy handler.
+ * @param p_grp_lock	Pointer to receive the newly created group lock.
+ *
+ * @return		PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_grp_lock_create_w_handler(pj_pool_t *pool,
+                                        	  const pj_grp_lock_config *cfg,
+                                        	  void *member,
+                                                  void (*handler)(void *member),
+                                        	  pj_grp_lock_t **p_grp_lock);
+
+/**
  * Forcibly destroy the group lock, ignoring the reference counter value.
  *
Index: pjproject/trunk/pjlib/src/pj/lock.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/lock.c	(revision 4991)
+++ pjproject/trunk/pjlib/src/pj/lock.c	(revision 4992)
@@ -336,4 +336,29 @@
 }
 
+static pj_status_t grp_lock_add_handler( pj_grp_lock_t *glock,
+                             		 pj_pool_t *pool,
+                             		 void *comp,
+                             		 void (*destroy)(void *comp),
+                             		 pj_bool_t acquire_lock)
+{
+    grp_destroy_callback *cb;
+
+    if (acquire_lock)
+        grp_lock_acquire(glock);
+
+    if (pool == NULL)
+	pool = glock->pool;
+
+    cb = PJ_POOL_ZALLOC_T(pool, grp_destroy_callback);
+    cb->comp = comp;
+    cb->handler = destroy;
+    pj_list_push_back(&glock->destroy_list, cb);
+
+    if (acquire_lock)
+        grp_lock_release(glock);
+
+    return PJ_SUCCESS;
+}
+
 static pj_status_t grp_lock_destroy(LOCK_OBJ *p)
 {
@@ -428,4 +453,20 @@
 }
 
+PJ_DEF(pj_status_t) pj_grp_lock_create_w_handler( pj_pool_t *pool,
+                                        	  const pj_grp_lock_config *cfg,
+                                        	  void *member,
+                                                  void (*handler)(void *member),
+                                        	  pj_grp_lock_t **p_grp_lock)
+{
+    pj_status_t status;
+
+    status = pj_grp_lock_create(pool, cfg, p_grp_lock);
+    if (status == PJ_SUCCESS) {
+        grp_lock_add_handler(*p_grp_lock, pool, member, handler, PJ_FALSE);
+    }
+    
+    return status;
+}
+
 PJ_DEF(pj_status_t) pj_grp_lock_destroy( pj_grp_lock_t *grp_lock)
 {
@@ -477,18 +518,5 @@
                                              void (*destroy)(void *comp))
 {
-    grp_destroy_callback *cb;
-
-    grp_lock_acquire(glock);
-
-    if (pool == NULL)
-	pool = glock->pool;
-
-    cb = PJ_POOL_ZALLOC_T(pool, grp_destroy_callback);
-    cb->comp = comp;
-    cb->handler = destroy;
-    pj_list_push_back(&glock->destroy_list, cb);
-
-    grp_lock_release(glock);
-    return PJ_SUCCESS;
+    return grp_lock_add_handler(glock, pool, comp, destroy, PJ_TRUE);
 }
 
Index: pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 4991)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 4992)
@@ -1008,14 +1008,17 @@
     if (grp_lock) {
 	tsx->grp_lock = grp_lock;
+        
+        pj_grp_lock_add_ref(tsx->grp_lock);
+        pj_grp_lock_add_handler(tsx->grp_lock, tsx->pool, tsx, &tsx_on_destroy);
     } else {
-	status = pj_grp_lock_create(pool, NULL, &tsx->grp_lock);
+	status = pj_grp_lock_create_w_handler(pool, NULL, tsx, &tsx_on_destroy,
+					      &tsx->grp_lock);
 	if (status != PJ_SUCCESS) {
 	    pjsip_endpt_release_pool(mod_tsx_layer.endpt, pool);
 	    return status;
 	}
-    }
-
-    pj_grp_lock_add_ref(tsx->grp_lock);
-    pj_grp_lock_add_handler(tsx->grp_lock, tsx->pool, tsx, &tsx_on_destroy);
+	
+	pj_grp_lock_add_ref(tsx->grp_lock);
+    }
 
     status = pj_mutex_create_simple(pool, tsx->obj_name, &tsx->mutex_b);
@@ -1309,6 +1312,10 @@
 
 
-    /* Lock transaction. */
-    pj_grp_lock_acquire(tsx->grp_lock);
+    /* Lock transaction.
+     * We don't need to lock the group lock if none was supplied, while the
+     * newly created group lock has not been exposed.
+     */
+    if (grp_lock)
+        pj_grp_lock_acquire(tsx->grp_lock);
 
     /* Role is UAC. */
@@ -1376,5 +1383,6 @@
     status = pjsip_get_request_dest(tdata, &dst_info);
     if (status != PJ_SUCCESS) {
-	pj_grp_lock_release(tsx->grp_lock);
+	if (grp_lock)
+	    pj_grp_lock_release(tsx->grp_lock);
 	tsx_shutdown(tsx);
 	return status;
@@ -1388,5 +1396,6 @@
 	pj_assert(!"Bug in branch_param generator (i.e. not unique)");
 	*/
-	pj_grp_lock_release(tsx->grp_lock);
+	if (grp_lock)
+	    pj_grp_lock_release(tsx->grp_lock);
 	tsx_shutdown(tsx);
 	return status;
@@ -1395,5 +1404,6 @@
 
     /* Unlock transaction and return. */
-    pj_grp_lock_release(tsx->grp_lock);
+    if (grp_lock)
+        pj_grp_lock_release(tsx->grp_lock);
 
     pj_log_push_indent();
