int net_startmonitor(FAR struct socket *psock) { FAR struct uip_conn *conn = psock->s_conn; DEBUGASSERT(psock && conn); /* Set up to receive callbacks on connection-related events */ conn->connection_private = (void*)psock; conn->connection_event = connection_event; /* Check if the connection has already been closed before any callbacks have * been registered. (Maybe the connection is lost before accept has registered * the monitoring callback.) */ if (conn->tcpstateflags == UIP_CLOSED) { connection_event(conn, UIP_CLOSE); } return OK; }
int main(void) { int sfd, epfd; struct connection main_c; struct epoll_event new_evts[MAX_CONNECTIONS]; if (unittest_http_parse(0)) return -1; prep_signals(); epfd = epoll_create(MAX_CONNECTIONS); sfd = connmgr_create_server(8000); main_c.evt_id = sfd; event_new(epfd, &main_c); cos_init(NULL); while (1) { int nevts, i, accept_event = 0; nevts = epoll_wait(epfd, new_evts, MAX_CONNECTIONS, -1); if (nevts < 0) { perror("waiting for events"); return -1; } for (i = 0 ; i < nevts ; i++) { struct epoll_event *e = &new_evts[i]; struct connection *c = (struct connection *)e->data.ptr; if (c == &main_c) { if (e->events & (EPOLLERR | EPOLLHUP)) { printf("errors on the listen fd\n"); return -1; } accept_event = 1; } else if (e->events & (EPOLLERR | EPOLLHUP)) { event_delete(epfd, c); close(c->evt_id); http_close_connection(c->conn_id); /* FIXME: free requests for connection */ } else { int ret; ret = connection_event(c); if (ret > 0) { event_delete(epfd, c); close(c->evt_id); http_close_connection(c->conn_id); } else if (ret < 0) { return -1; } } } if (accept_event) { struct connection *c; c = connmgr_accept(main_c.evt_id); if (NULL == c) { printf("Not a large enough connection namespace."); } else { event_new(epfd, c); } } } return 0; }
int net_startmonitor(FAR struct socket *psock) { FAR struct tcp_conn_s *conn; FAR struct devif_callback_s *cb; net_lock_t save; DEBUGASSERT(psock != NULL && psock->s_conn != NULL); conn = (FAR struct tcp_conn_s *)psock->s_conn; /* Check if the connection has already been closed before any callbacks * have been registered. (Maybe the connection is lost before accept has * registered the monitoring callback.) */ save = net_lock(); if (!(conn->tcpstateflags == TCP_ESTABLISHED || conn->tcpstateflags == TCP_SYN_RCVD)) { /* Invoke the TCP_CLOSE connection event now */ (void)connection_event(NULL, conn, psock, TCP_CLOSE); /* Make sure that the monitor is stopped */ conn->connection_private = NULL; conn->connection_devcb = NULL; conn->connection_event = NULL; /* And return -ENOTCONN to indicate the the monitor was not started * because the socket was already disconnected. */ net_unlock(save); return -ENOTCONN; } DEBUGASSERT(conn->connection_event == NULL && conn->connection_devcb == NULL); /* Allocate a callback structure that we will use to get callbacks if * the network goes down. */ cb = tcp_monitor_callback_alloc(conn); if (cb != NULL) { cb->event = connection_event; cb->priv = (void*)psock; cb->flags = NETDEV_DOWN; } conn->connection_devcb = cb; /* Set up to receive callbacks on connection-related events */ conn->connection_private = (void*)psock; conn->connection_event = connection_event; net_unlock(save); return OK; }