aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2006-07-28 09:45:18 +0000
committerMartin Willi <martin@strongswan.org>2006-07-28 09:45:18 +0000
commitf698448ea3d587451f2cc60c2e6e65aae5275d38 (patch)
tree2cfaed9de29551b4dd63d104be8232e68c8e2b82
parentfe04e93a8b3306cf67ab726cd0ad06312a7ed3f6 (diff)
downloadstrongswan-f698448ea3d587451f2cc60c2e6e65aae5275d38.tar.bz2
strongswan-f698448ea3d587451f2cc60c2e6e65aae5275d38.tar.xz
implemented proper refcounting using atomic operations
-rw-r--r--src/charon/config/connections/connection.c6
-rw-r--r--src/charon/config/connections/connection.h3
-rw-r--r--src/charon/config/policies/policy.c6
-rw-r--r--src/charon/config/policies/policy.h3
-rw-r--r--src/charon/daemon.c1
-rw-r--r--src/charon/doc/Todo-list.txt2
-rw-r--r--src/libstrongswan/types.c38
-rw-r--r--src/libstrongswan/types.h26
8 files changed, 79 insertions, 6 deletions
diff --git a/src/charon/config/connections/connection.c b/src/charon/config/connections/connection.c
index 3ecc08a16..281d43d9c 100644
--- a/src/charon/config/connections/connection.c
+++ b/src/charon/config/connections/connection.c
@@ -63,7 +63,7 @@ struct private_connection_t {
/**
* Number of references hold by others to this connection
*/
- u_int refcount;
+ refcount_t refcount;
/**
* Name of the connection
@@ -326,7 +326,7 @@ static u_int32_t get_hard_lifetime(private_connection_t *this)
*/
static void get_ref(private_connection_t *this)
{
- this->refcount++;
+ ref_get(&this->refcount);
}
/**
@@ -334,7 +334,7 @@ static void get_ref(private_connection_t *this)
*/
static void destroy(private_connection_t *this)
{
- if (--this->refcount == 0)
+ if (ref_put(&this->refcount))
{
proposal_t *proposal;
diff --git a/src/charon/config/connections/connection.h b/src/charon/config/connections/connection.h
index 068dd710b..61ca9cfc0 100644
--- a/src/charon/config/connections/connection.h
+++ b/src/charon/config/connections/connection.h
@@ -259,6 +259,9 @@ struct connection_t {
*
* Get a new reference to this connection by increasing
* it's internal reference counter.
+ * Do not call get_ref or any other function until you
+ * already have a reference. Otherwise the object may get
+ * destroyed while calling get_ref(),
*
* @param this calling object
*/
diff --git a/src/charon/config/policies/policy.c b/src/charon/config/policies/policy.c
index 14fa93b4e..49983ade7 100644
--- a/src/charon/config/policies/policy.c
+++ b/src/charon/config/policies/policy.c
@@ -46,7 +46,7 @@ struct private_policy_t {
/**
* Number of references hold by others to this policy
*/
- u_int refcount;
+ refcount_t refcount;
/**
* Name of the policy, used to query it
@@ -377,7 +377,7 @@ static u_int32_t get_hard_lifetime(private_policy_t *this)
*/
static void get_ref(private_policy_t *this)
{
- this->refcount++;
+ ref_get(&this->refcount);
}
/**
@@ -385,7 +385,7 @@ static void get_ref(private_policy_t *this)
*/
static void destroy(private_policy_t *this)
{
- if (--this->refcount == 0)
+ if (ref_put(&this->refcount))
{
proposal_t *proposal;
traffic_selector_t *traffic_selector;
diff --git a/src/charon/config/policies/policy.h b/src/charon/config/policies/policy.h
index 1659a7070..454f69c12 100644
--- a/src/charon/config/policies/policy.h
+++ b/src/charon/config/policies/policy.h
@@ -227,6 +227,9 @@ struct policy_t {
*
* Get a new reference to this policy by increasing
* it's internal reference counter.
+ * Do not call get_ref or any other function until you
+ * already have a reference. Otherwise the object may get
+ * destroyed while calling get_ref(),
*
* @param this calling object
*/
diff --git a/src/charon/daemon.c b/src/charon/daemon.c
index 5e4a67a20..a368ee428 100644
--- a/src/charon/daemon.c
+++ b/src/charon/daemon.c
@@ -32,6 +32,7 @@
#include <execinfo.h>
#include <string.h>
#include <getopt.h>
+#include <errno.h>
#include "daemon.h"
diff --git a/src/charon/doc/Todo-list.txt b/src/charon/doc/Todo-list.txt
index 788a06c54..296820e58 100644
--- a/src/charon/doc/Todo-list.txt
+++ b/src/charon/doc/Todo-list.txt
@@ -54,6 +54,8 @@
+ proper delete messages
- notifys on connection setup failure
+ create child sa message/rekeying
+/ IKE_SA rekeying
+ - handle all simultaneous rekeying/delete/create cases
- implement a mechanism against thread exhaustion
when a blocked IKE_SA receives a lot of messages
diff --git a/src/libstrongswan/types.c b/src/libstrongswan/types.c
index b60a604b8..e0337274e 100644
--- a/src/libstrongswan/types.c
+++ b/src/libstrongswan/types.c
@@ -25,6 +25,7 @@
#include <time.h>
#include <stdio.h>
#include <stdarg.h>
+#include <pthread.h>
#include "types.h"
@@ -198,6 +199,43 @@ void *clalloc(void * pointer, size_t size)
return (data);
}
+/**
+ * We use a single mutex for all refcount variables. This
+ * is not optimal for performance, but the critical section
+ * is not that long...
+ * TODO: Consider to include a mutex in each refcount_t variable.
+ */
+static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Described in header.
+ *
+ * TODO: May be implemented with atomic CPU instructions
+ * instead of a mutex.
+ */
+void ref_get(refcount_t *ref)
+{
+ pthread_mutex_lock(&ref_mutex);
+ (*ref)++;
+ pthread_mutex_unlock(&ref_mutex);
+}
+
+/**
+ * Described in header.
+ *
+ * TODO: May be implemented with atomic CPU instructions
+ * instead of a mutex.
+ */
+bool ref_put(refcount_t *ref)
+{
+ bool more_refs;
+
+ pthread_mutex_lock(&ref_mutex);
+ more_refs = --(*ref);
+ pthread_mutex_unlock(&ref_mutex);
+ return !more_refs;
+}
+
/*
* Names of the months used by timetoa()
*/
diff --git a/src/libstrongswan/types.h b/src/libstrongswan/types.h
index 631e5025b..9874d5bc0 100644
--- a/src/libstrongswan/types.h
+++ b/src/libstrongswan/types.h
@@ -200,6 +200,32 @@ void chunk_to_hex(char *buf, size_t buflen, chunk_t chunk);
*/
void *clalloc(void *pointer, size_t size);
+/**
+ * Special type to count references
+ */
+typedef volatile u_int refcount_t;
+
+/**
+ * @brief Get a new reference.
+ *
+ * Increments the reference counter atomic.
+ *
+ * @param ref pointer to ref counter
+ */
+void ref_get(refcount_t *ref);
+
+/**
+ * @brief Put back a unused reference.
+ *
+ * Decrements the reference counter atomic and
+ * says if more references available.
+ *
+ * @param ref pointer to ref counter
+ * @return TRUE if no more references counted
+ */
+bool ref_put(refcount_t *ref);
+
+
#define UNDEFINED_TIME 0
#define TIMETOA_BUF 30