Browse Source

* Don't hold a net_buf on allocation. Do it when it's really needed instead.

* Add function net_unsend to safely remove network buffers from a peer's
  outq. Use it where needed in peer.c.
master
Richard Nyberg 19 years ago
parent
commit
af31e76618
3 changed files with 39 additions and 35 deletions
  1. +28
    -2
      btpd/net.c
  2. +1
    -1
      btpd/net.h
  3. +10
    -32
      btpd/peer.c

+ 28
- 2
btpd/net.c View File

@@ -97,7 +97,6 @@ nb_create_alloc(short type, size_t len)
nb->buf = (char *)(nb + 1);
nb->len = len;
nb->kill_buf = kill_buf_no;
nb_hold(nb);
return nb;
}

@@ -110,7 +109,6 @@ nb_create_set(short type, char *buf, size_t len,
nb->buf = buf;
nb->len = len;
nb->kill_buf = kill_buf;
nb_hold(nb);
return nb;
}

@@ -209,6 +207,7 @@ net_send(struct peer *p, struct net_buf *nb)
{
struct nb_link *nl = btpd_calloc(1, sizeof(*nl));
nl->nb = nb;
nb_hold(nb);

if (BTPDQ_EMPTY(&p->outq)) {
assert(p->outq_off == 0);
@@ -217,6 +216,33 @@ net_send(struct peer *p, struct net_buf *nb)
BTPDQ_INSERT_TAIL(&p->outq, nl, entry);
}


/*
* Remove a network buffer from the peer's outq.
* If a part of the buffer already have been written
* to the network it cannot be removed.
*
* Returns 1 if the buffer is removed, 0 if not.
*/
int
net_unsend(struct peer *p, struct nb_link *nl)
{
if (!(nl == BTPDQ_FIRST(&p->outq) && p->outq_off > 0)) {
BTPDQ_REMOVE(&p->outq, nl, entry);
nb_drop(nl->nb);
free(nl);
if (BTPDQ_EMPTY(&p->outq)) {
if (p->flags & PF_ON_WRITEQ) {
BTPDQ_REMOVE(&btpd.writeq, p, wq_entry);
p->flags &= ~PF_ON_WRITEQ;
} else
event_del(&p->out_ev);
}
return 1;
} else
return 0;
}

void
net_write32(void *buf, uint32_t num)
{


+ 1
- 1
btpd/net.h View File

@@ -120,7 +120,7 @@ void net_send_request(struct peer *p, struct piece_req *req);
void net_send_piece(struct peer *p, uint32_t index, uint32_t begin,
char *block, size_t blen);
void net_send_cancel(struct peer *p, struct piece_req *req);
int net_unsend(struct peer *p, struct nb_link *nl);
void net_handshake(struct peer *p, int incoming);

void net_read_cb(int sd, short type, void *arg);


+ 10
- 32
btpd/peer.c View File

@@ -110,16 +110,11 @@ peer_choke(struct peer *p)
struct nb_link *nl = BTPDQ_FIRST(&p->outq);
while (nl != NULL) {
struct nb_link *next = BTPDQ_NEXT(nl, entry);
if (nl->nb->info.type == NB_PIECE
&& (nl != BTPDQ_FIRST(&p->outq) && p->outq_off > 0)) {
nb_drop(nl->nb);
BTPDQ_REMOVE(&p->outq, nl, entry);
free(nl);
nl = next;
if (nl->nb->info.type == NB_PIECE) {
struct nb_link *data = next;
next = BTPDQ_NEXT(next, entry);
nb_drop(nl->nb);
BTPDQ_REMOVE(&p->outq, nl, entry);
free(nl);
if (net_unsend(p, nl))
net_unsend(p, data);
}
nl = next;
}
@@ -309,34 +304,17 @@ void
peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin,
uint32_t length)
{
struct nb_link *nl = BTPDQ_FIRST(&p->outq);
if (nl == NULL)
return;
while (nl != NULL) {
struct nb_link *nl;
BTPDQ_FOREACH(nl, &p->outq, entry)
if (nl->nb->info.type == NB_PIECE
&& nl->nb->info.index == index
&& nl->nb->info.begin == begin
&& nl->nb->info.length == length
&& (nl != BTPDQ_FIRST(&p->outq) && p->outq_off > 0)) {
btpd_log(BTPD_L_MSG, "cancel matched.\n");
&& nl->nb->info.length == length) {
struct nb_link *data = BTPDQ_NEXT(nl, entry);
nb_drop(nl->nb);
BTPDQ_REMOVE(&p->outq, nl, entry);
free(nl);
nb_drop(data->nb);
BTPDQ_REMOVE(&p->outq, data, entry);
free(data);
if (net_unsend(p, nl))
net_unsend(p, data);
break;
}
nl = BTPDQ_NEXT(nl, entry);
}

if (BTPDQ_EMPTY(&p->outq)) {
if (p->flags & PF_ON_WRITEQ) {
BTPDQ_REMOVE(&btpd.writeq, p, wq_entry);
p->flags &= ~PF_ON_WRITEQ;
} else
event_del(&p->out_ev);
}
}

int


Loading…
Cancel
Save