if (notify_waiters) {
fosa_cond_broadcast(&peer->cond);
} else {
- forb_peer_get(peer);
- forb_peer_nolock_insert(forb, peer);
+ forb_peer_nolock_insert(forb, forb_peer_get(peer));
}
- forb_peer_get(peer);
- forb_port_peer_ins_tail(port, peer);
+ forb_port_peer_ins_tail(port, forb_peer_get(peer));
fosa_mutex_unlock(&forb->peer_mutex);
forb_peer_put(peer);
}
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;
&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;
}
}
void
forb_peer_release(forb_ref_t *ref);
-static inline void
+static inline forb_peer_t *
forb_peer_get(forb_peer_t *peer)
{
forb_ref_get(&peer->ref);
+ return peer;
}
static inline void