static void accept_new(int accept_fd) { int from, to, feid, teid; while (1) { from = net_accept(cos_spd_id(), accept_fd); assert(from != accept_fd); if (-EAGAIN == from) { return; } else if (from < 0) { BUG(); return; } feid = evt_get(); assert(feid > 0); if (0 < net_accept_data(cos_spd_id(), from, feid)) BUG(); teid = evt_get(); assert(teid > 0); to = tsplit(cos_spd_id(), td_root, "", 0, TOR_RW, teid); if (to < 0) { printc("torrent split returned %d", to); BUG(); } mapping_add(from, to, feid, teid); } }
td_t tsplit(spdid_t spdid, td_t tid, char *param, int len, tor_flags_t tflags, long evtid) { td_t ret = -EINVAL; struct torrent *t; net_connection_t nc = 0; int accept = 0; if (tor_isnull(tid)) return -EINVAL; NET_LOCK_TAKE(); /* creating a new connection */ if (tid == td_root || len == 0 || strstr(param, "accept")) { if (tid == td_root) { /* new connection */ nc = net_create_tcp_connection(spdid, cos_get_thd_id(), evtid); if (nc <= 0) ERR_THROW(-ENOMEM, done); } else { /* len == 0 || strstr(param, "accept"), accept on connection */ t = tor_lookup(tid); if (!t) goto done; nc = net_accept(spdid, (net_connection_t)t->data); if (nc == -EAGAIN) { /* printc("net accept return EAGAIN\n"); */ ERR_THROW(-EAGAIN, done); } if (nc < 0) ERR_THROW(-EINVAL, done); if (0 < net_accept_data(spdid, nc, evtid)) BUG(); accept = 1; } t = tor_alloc((void*)nc, tflags); if (!t) ERR_THROW(-ENOMEM, free); ret = t->td; } else { /* modifying an existing connection */ t = tor_lookup(tid); if (!t) goto done; nc = (net_connection_t)t->data; } if (!accept && len != 0) { int r; NET_LOCK_RELEASE(); r = modify_connection(spdid, nc, param, len); if (r < 0) ret = r; NET_LOCK_TAKE(); } done: NET_LOCK_RELEASE(); assert(lock_contested(&net_lock) != cos_get_thd_id()); return ret; free: net_close(spdid, nc); goto done; }