void cos_init(void *arg) { int c, accept_fd, ret; long eid; cvect_init_static(&evts); cvect_init_static(&tor_from); cvect_init_static(&tor_to); eid = evt_get(); c = net_create_tcp_connection(cos_spd_id(), cos_get_thd_id(), eid); if (c < 0) BUG(); ret = net_bind(cos_spd_id(), c, 0, 200); if (ret < 0) BUG(); ret = net_listen(cos_spd_id(), c, 255); if (ret < 0) BUG(); accept_fd = c; evt_add(c, eid); while (1) { struct tor_conn tc; int t; long evt; memset(&tc, 0, sizeof(struct tor_conn)); printc("waiting...\n"); evt = evt_grp_wait(cos_spd_id()); t = evt_torrent(evt); if (t > 0) { tc.feid = evt; tc.from = t; if (t == accept_fd) { tc.to = 0; printc("accepting event.\n"); accept_new(accept_fd); } else { tc.to = tor_get_to(t); assert(tc.to > 0); printc("data from net.\n"); from_data_new(&tc); } } else { t *= -1; tc.teid = evt; tc.to = t; tc.from = tor_get_from(t); assert(tc.from > 0); printc("data from torrent.\n"); to_data_new(&tc); } cos_mpd_update(); } }
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; }