Added locking to dynamic socket list
authorMartin Willi <martin@revosec.ch>
Wed, 24 Feb 2010 10:45:18 +0000 (11:45 +0100)
committerMartin Willi <martin@revosec.ch>
Fri, 26 Feb 2010 10:44:34 +0000 (11:44 +0100)
src/charon/plugins/socket_dynamic/socket_dynamic_socket.c

index e1f34de..f88c1dd 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <daemon.h>
 #include <threading/thread.h>
 
 #include <daemon.h>
 #include <threading/thread.h>
+#include <threading/rwlock.h>
 #include <utils/hashtable.h>
 
 /* Maximum size of a packet */
 #include <utils/hashtable.h>
 
 /* Maximum size of a packet */
@@ -91,6 +92,11 @@ struct private_socket_dynamic_socket_t {
        hashtable_t *sockets;
 
        /**
        hashtable_t *sockets;
 
        /**
+        * Lock for sockets hashtable
+        */
+       rwlock_t *lock;
+
+       /**
         * Notification pipe to signal receiver
         */
        int notify[2];
         * Notification pipe to signal receiver
         */
        int notify[2];
@@ -146,6 +152,7 @@ static int build_fds(private_socket_dynamic_socket_t *this, fd_set *fds)
        FD_SET(this->notify[0], fds);
        maxfd = this->notify[0];
 
        FD_SET(this->notify[0], fds);
        maxfd = this->notify[0];
 
+       this->lock->read_lock(this->lock);
        enumerator = this->sockets->create_enumerator(this->sockets);
        while (enumerator->enumerate(enumerator, &key, &value))
        {
        enumerator = this->sockets->create_enumerator(this->sockets);
        while (enumerator->enumerate(enumerator, &key, &value))
        {
@@ -153,6 +160,7 @@ static int build_fds(private_socket_dynamic_socket_t *this, fd_set *fds)
                maxfd = max(maxfd, value->fd);
        }
        enumerator->destroy(enumerator);
                maxfd = max(maxfd, value->fd);
        }
        enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
 
        return maxfd + 1;
 }
 
        return maxfd + 1;
 }
@@ -165,6 +173,7 @@ static dynsock_t* scan_fds(private_socket_dynamic_socket_t *this, fd_set *fds)
        enumerator_t *enumerator;
        dynsock_t *key, *value, *selected = NULL;
 
        enumerator_t *enumerator;
        dynsock_t *key, *value, *selected = NULL;
 
+       this->lock->read_lock(this->lock);
        enumerator = this->sockets->create_enumerator(this->sockets);
        while (enumerator->enumerate(enumerator, &key, &value))
        {
        enumerator = this->sockets->create_enumerator(this->sockets);
        while (enumerator->enumerate(enumerator, &key, &value))
        {
@@ -175,6 +184,8 @@ static dynsock_t* scan_fds(private_socket_dynamic_socket_t *this, fd_set *fds)
                }
        }
        enumerator->destroy(enumerator);
                }
        }
        enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+
        return selected;
 }
 
        return selected;
 }
 
@@ -428,7 +439,9 @@ static dynsock_t *find_socket(private_socket_dynamic_socket_t *this,
        char buf[] = {0x01};
        int fd;
 
        char buf[] = {0x01};
        int fd;
 
+       this->lock->read_lock(this->lock);
        skt = this->sockets->get(this->sockets, &lookup);
        skt = this->sockets->get(this->sockets, &lookup);
+       this->lock->unlock(this->lock);
        if (skt)
        {
                return skt;
        if (skt)
        {
                return skt;
@@ -444,7 +457,9 @@ static dynsock_t *find_socket(private_socket_dynamic_socket_t *this,
                .port = port,
                .fd = fd,
        );
                .port = port,
                .fd = fd,
        );
+       this->lock->write_lock(this->lock);
        this->sockets->put(this->sockets, skt, skt);
        this->sockets->put(this->sockets, skt, skt);
+       this->lock->unlock(this->lock);
        /* notify receiver thread to reread socket list */
        ignore_result(write(this->notify[1], buf, sizeof(buf)));
 
        /* notify receiver thread to reread socket list */
        ignore_result(write(this->notify[1], buf, sizeof(buf)));
 
@@ -567,6 +582,7 @@ METHOD(socket_dynamic_socket_t, destroy, void,
        }
        enumerator->destroy(enumerator);
        this->sockets->destroy(this->sockets);
        }
        enumerator->destroy(enumerator);
        this->sockets->destroy(this->sockets);
+       this->lock->destroy(this->lock);
 
        close(this->notify[0]);
        close(this->notify[1]);
 
        close(this->notify[0]);
        close(this->notify[1]);
@@ -588,6 +604,7 @@ socket_dynamic_socket_t *socket_dynamic_socket_create()
                        },
                        .destroy = _destroy,
                },
                        },
                        .destroy = _destroy,
                },
+               .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
        );
 
        if (pipe(this->notify) != 0)
        );
 
        if (pipe(this->notify) != 0)