void net_client_connect (NetClient *client, NetClientConnection *connection) { struct sockaddr_in address; int result; int i; if (!client) { error_code (InvalidArgument, 1); return; } if (!connection) { error_code (InvalidArgument, 2); return; } if (inet_pton (AF_INET, connection->ip, &address.sin_addr) != 1) { error_code (SystemCall, 1); worker_connect_error (client, connection); return; } address.sin_family = AF_INET; address.sin_port = htons (connection->port); if ((connection->socket = socket (AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) { error_code (SystemCall, 2); worker_connect_error (client, connection); return; } for (i = 0; i < 3; i++) { result = connect (connection->socket, (struct sockaddr *)&address, sizeof (struct sockaddr)); if (result == 0) { worker_connect (client, connection); return; } if (result == -1 && (errno == EINPROGRESS || errno == EWOULDBLOCK)) { /* Obscure epoll bug can cause EPOLLOUT+EPOLLHUP if epoll_ctl is * done before a connect, so we do it after connect. * To reproduce, just move this line before the for loop and run * the test with 1-10 iterations. */ if (!net_client_epoll_monitor (client->epoll, connection->socket, connection)) { error_code (FunctionCall, 1); worker_connect_error (client, connection); return; } return; } if (result == -1 && errno == EINTR) { continue; } break; } error_code (SystemCall, 2); worker_connect_error (client, connection); return; }
App::App(const Wt::WEnvironment& env) : Wt::WApplication(env) { setTheme(new Wt::WBootstrapTheme()); useStyleSheet("style.css"); root()->addWidget(config_wdgt = new Config_wdgt(session)); root()->addWidget(new Wt::WBreak()); root()->addWidget(stat_wdgt = new Stat_wdgt(session)); root()->addWidget(new Wt::WBreak()); root()->addWidget(line_wdgt = new Line_wdgt(session)); root()->addWidget(new Wt::WBreak()); root()->addWidget(prog_wdgt = new Prog_wdgt(session)); enableUpdates(true); worker_connect(this); }
static void worker (Thread *thread) { NetClient *client = thread->argument; NetClientEpollEvent event; int count; int i; while (net_client_epoll_events_count (client->epoll, &count)) { for (i = 0; i < count; i++) { event = net_client_epoll_event (client->epoll, i); if (event.stop) { return; } else if (event.connect) { worker_connect (client, event.pointer); } else { worker_connect_error (client, event.pointer); } } } client->on_error (client); return; }