engine: add engine_peer_list for per-peer status
Enumerates a torrent's connected peers (ip/port/state/rate/bytes/have) for the UI's peer list — the per-peer detail lost in the engine swap. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
d8208685a2
commit
f85278fcf2
2 changed files with 47 additions and 0 deletions
|
|
@ -139,6 +139,24 @@ uint32_t engine_loop_count(engine *e);
|
|||
|
||||
void engine_torrent_status(engine *e, uint32_t torrent_id, torrent_status *out);
|
||||
|
||||
/* One connected peer's live state, for the UI's per-peer list. */
|
||||
typedef struct {
|
||||
char ip[64];
|
||||
uint16_t port;
|
||||
int32_t state; /* peer_state */
|
||||
int32_t unchoked; /* peer has unchoked us */
|
||||
uint64_t bytes_received; /* total payload bytes from this peer */
|
||||
double rate_bps; /* current download rate from this peer */
|
||||
uint32_t have_pieces; /* pieces this peer advertises */
|
||||
uint32_t num_pieces; /* torrent piece count (for progress ratio) */
|
||||
} engine_peer_info;
|
||||
|
||||
/* Fill `out` with up to `max` connected peers (handshake completed) of a
|
||||
* torrent; returns the number written. Best-effort snapshot read on the caller
|
||||
* thread (like engine_torrent_status), so fine for status, not control. */
|
||||
uint32_t engine_peer_list(engine *e, uint32_t torrent_id, engine_peer_info *out,
|
||||
uint32_t max);
|
||||
|
||||
/* Diagnostic: write a human-readable dump of one torrent's piece-selection and
|
||||
* per-connection state to `out`. Reports, for every still-wanted piece
|
||||
* (priority > 0), whether a peer has claimed it (requested), how many connected
|
||||
|
|
|
|||
29
src/engine.c
29
src/engine.c
|
|
@ -461,6 +461,35 @@ void engine_torrent_status(engine *e, uint32_t torrent_id, torrent_status *out)
|
|||
out->rtt_min_ms = rttmin;
|
||||
}
|
||||
|
||||
uint32_t engine_peer_list(engine *e, uint32_t torrent_id, engine_peer_info *out,
|
||||
uint32_t max) {
|
||||
if (!e || !out || max == 0) return 0;
|
||||
torrent *t = find_locked(e, torrent_id);
|
||||
if (!t) return 0;
|
||||
loop *lp = t->lp;
|
||||
uint32_t n = 0;
|
||||
for (conn *c = lp->conns; c && n < max; c = c->next) {
|
||||
if (c->tor != t) continue;
|
||||
int st = atomic_load_explicit(&c->astate, memory_order_relaxed);
|
||||
if (st != PEER_STATE_RUNNING && st != PEER_STATE_CHOKED) continue;
|
||||
engine_peer_info *p = &out[n++];
|
||||
snprintf(p->ip, sizeof p->ip, "%s", c->ip);
|
||||
p->port = c->port;
|
||||
p->state = st;
|
||||
p->unchoked = c->unchoked;
|
||||
p->bytes_received =
|
||||
atomic_load_explicit(&c->bytes_received, memory_order_relaxed);
|
||||
p->rate_bps = c->rate_bps;
|
||||
p->num_pieces = t->num_pieces;
|
||||
uint32_t have = 0;
|
||||
if (c->have_bits)
|
||||
for (uint32_t i = 0; i < t->num_pieces; i++)
|
||||
if (have_bit(c->have_bits, i)) have++;
|
||||
p->have_pieces = have;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static const char *peer_state_name(int state) {
|
||||
switch (state) {
|
||||
case PEER_STATE_IDLE: return "idle";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue