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;
}
Beispiel #3
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;
}