]> rtime.felk.cvut.cz Git - frescor/forb.git/blobdiff - src/peer.c
Added mutex to protect request send from multiple threads
[frescor/forb.git] / src / peer.c
index 6056417b09e7eb6dbd73aefa34d79b2ae02c0b6c..ea04c0c94ccb41f7f88aa8b3867b68aeacf350cf 100644 (file)
@@ -79,6 +79,7 @@ forb_peer_new(void)
                memset(peer, 0, sizeof(*peer));
                fosa_cond_init(&peer->cond);
                forb_ref_init(&peer->ref);
+               fosa_mutex_init(&peer->send_lock, 0);
        }
        return peer;
 }
@@ -87,9 +88,13 @@ void
 forb_peer_release(forb_ref_t *ref)
 {
        forb_peer_t *peer = container_of(ref, forb_peer_t, ref);
-       if (peer->port->proto->peer_destroy) {
-               peer->port->proto->peer_destroy(peer);
+       if (peer->port &&
+           peer->port->desc.proto->peer_destroy) {
+               peer->port->desc.proto->peer_destroy(peer);
        }
+       if (peer->addr)
+               forb_free(peer->addr);
+       
        forb_free(peer);
 }
 
@@ -123,21 +128,21 @@ forb_peer_find_timed(forb_t *forb, forb_server_id *server_id,
                     fosa_abs_time_t *timeout)
 {
        forb_peer_t *peer;
+       bool peer_allocated = false;
        
        fosa_mutex_lock(&forb->peer_mutex);
        peer = forb_peer_nolock_find(forb, server_id);
        if (!peer && !timeout) goto unlock;
        if (peer) {
                forb_peer_get(peer);
-       }
-       if (!peer) {
+       } else {
                /* We are the first who want to contact this peer */
                peer = forb_peer_new();
                if (!peer) goto unlock;
                peer->server_id = *server_id;
                peer->state = FORB_PEER_WANTED;
-               forb_peer_get(peer);
-               forb_peer_nolock_insert(forb, peer);
+               forb_peer_nolock_insert(forb, forb_peer_get(peer));
+               peer_allocated = true;
        }
        while (peer->state == FORB_PEER_WANTED) {
                int ret;
@@ -146,11 +151,13 @@ forb_peer_find_timed(forb_t *forb, forb_server_id *server_id,
                                          &forb->peer_mutex,
                                          timeout);
                if (ret == FOSA_ETIMEDOUT) {
+                       /* No peer discovered within timeout */
+                       if (peer_allocated) {
+                               forb_peer_nolock_delete(forb, peer);
+                               forb_peer_put(peer);
+                       }
                        forb_peer_put(peer);
                        peer = NULL;
-                       /* TODO: How to remove the peer from the tree?
-                        * We should check refcnt and if equal to 1,
-                        * we should remove it.  */
                        break;
                }
        }