ike-sa-manager: Signal entries that we don't actually check out
authorTobias Brunner <tobias@strongswan.org>
Thu, 5 Nov 2015 17:52:27 +0000 (18:52 +0100)
committerTobias Brunner <tobias@strongswan.org>
Mon, 9 Nov 2015 14:18:37 +0000 (15:18 +0100)
In some cases we call wait_for_entry() but don't actually check out the
entry afterwards (e.g. because it doesn't match certain criteria).  So
there won't be a call to checkin() for such entries causing waiting
threads to get signaled.  Instead, such threads would be blocked until
another thread properly checks out/in the entry (or does a blocking
enumeration).

src/libcharon/sa/ike_sa_manager.c

index 4adf22c..24bde31 100644 (file)
@@ -1384,7 +1384,8 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
                        continue;
                }
                if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
-               {       /* skip IKE_SAs which are not usable */
+               {       /* skip IKE_SAs which are not usable, wake other waiting threads */
+                       entry->condvar->signal(entry->condvar);
                        continue;
                }
 
@@ -1402,6 +1403,8 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
                                break;
                        }
                }
+               /* other threads might be waiting for this entry */
+               entry->condvar->signal(entry->condvar);
        }
        enumerator->destroy(enumerator);
 
@@ -1434,6 +1437,8 @@ METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*,
                                entry->checked_out = TRUE;
                                break;
                        }
+                       /* other threads might be waiting for this entry */
+                       entry->condvar->signal(entry->condvar);
                }
        }
        enumerator->destroy(enumerator);
@@ -1490,6 +1495,8 @@ METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*,
                                                ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
                                break;
                        }
+                       /* other threads might be waiting for this entry */
+                       entry->condvar->signal(entry->condvar);
                }
        }
        enumerator->destroy(enumerator);