/* wait for incoming connections */ int APP_CC xrdp_listen_main_loop(struct xrdp_listen *self) { int error; int robjs_count; int cont; int timeout = 0; char port[128]; char address[256]; tbus robjs[8]; tbus term_obj; tbus sync_obj; tbus done_obj; int tcp_nodelay; int tcp_keepalive; int bytes; self->status = 1; if (xrdp_listen_get_port_address(port, sizeof(port), address, sizeof(address), &tcp_nodelay, &tcp_keepalive, self->startup_params) != 0) { log_message(LOG_LEVEL_ERROR,"xrdp_listen_main_loop: xrdp_listen_get_port failed"); self->status = -1; return 1; } if (port[0] == '/') { /* set UDS mode */ self->listen_trans->mode = TRANS_MODE_UNIX; /* not valid with UDS */ tcp_nodelay = 0; } /* Create socket */ error = trans_listen_address(self->listen_trans, port, address); if (error == 0) { if (tcp_nodelay) { if (g_tcp_set_no_delay(self->listen_trans->sck)) { log_message(LOG_LEVEL_ERROR,"Error setting tcp_nodelay"); } } if (tcp_keepalive) { if (g_tcp_set_keepalive(self->listen_trans->sck)) { log_message(LOG_LEVEL_ERROR,"Error setting tcp_keepalive"); } } if (self->startup_params->send_buffer_bytes > 0) { bytes = self->startup_params->send_buffer_bytes; log_message(LOG_LEVEL_INFO, "setting send buffer to %d bytes", bytes); if (g_sck_set_send_buffer_bytes(self->listen_trans->sck, bytes) != 0) { log_message(LOG_LEVEL_ERROR, "error setting send buffer"); } else { if (g_sck_get_send_buffer_bytes(self->listen_trans->sck, &bytes) != 0) { log_message(LOG_LEVEL_ERROR, "error getting send buffer"); } else { log_message(LOG_LEVEL_INFO, "send buffer set to %d bytes", bytes); } } } if (self->startup_params->recv_buffer_bytes > 0) { bytes = self->startup_params->recv_buffer_bytes; log_message(LOG_LEVEL_INFO, "setting recv buffer to %d bytes", bytes); if (g_sck_set_recv_buffer_bytes(self->listen_trans->sck, bytes) != 0) { log_message(LOG_LEVEL_ERROR, "error setting recv buffer"); } else { if (g_sck_get_recv_buffer_bytes(self->listen_trans->sck, &bytes) != 0) { log_message(LOG_LEVEL_ERROR, "error getting recv buffer"); } else { log_message(LOG_LEVEL_INFO, "recv buffer set to %d bytes", bytes); } } } self->listen_trans->trans_conn_in = xrdp_listen_conn_in; self->listen_trans->callback_data = self; term_obj = g_get_term_event(); /*Global termination event */ sync_obj = g_get_sync_event(); done_obj = self->pro_done_event; cont = 1; while (cont) { /* build the wait obj list */ robjs_count = 0; robjs[robjs_count++] = term_obj; robjs[robjs_count++] = sync_obj; robjs[robjs_count++] = done_obj; timeout = -1; /* if (self->listen_trans != 0) */ { if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count) != 0) { log_message(LOG_LEVEL_ERROR,"Listening socket is in wrong state we " "terminate listener"); break; } } /* wait - timeout -1 means wait indefinitely*/ if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0) { /* error, should not get here */ g_sleep(100); } if (g_is_wait_obj_set(term_obj)) /* termination called */ { break; } /* some function must be processed by this thread */ if (g_is_wait_obj_set(sync_obj)) { g_reset_wait_obj(sync_obj); g_process_waiting_function(); /* run the function */ } if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { g_reset_wait_obj(done_obj); /* a process has died remove it from lists*/ xrdp_listen_delete_done_pro(self); } /* Run the callback when accept() returns a new socket*/ if (trans_check_wait_objs(self->listen_trans) != 0) { break; } } /* stop listening */ trans_delete(self->listen_trans); self->listen_trans = 0; /* second loop to wait for all process threads to close */ cont = 1; while (cont) { if (self->process_list->count == 0) { break; } timeout = -1; /* build the wait obj list */ robjs_count = 0; robjs[robjs_count++] = sync_obj; robjs[robjs_count++] = done_obj; /* wait - timeout -1 means wait indefinitely*/ if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0) { /* error, should not get here */ g_sleep(100); } /* some function must be processed by this thread */ if (g_is_wait_obj_set(sync_obj)) { g_reset_wait_obj(sync_obj); g_process_waiting_function(); /* run the function that is waiting*/ } if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { g_reset_wait_obj(done_obj); xrdp_listen_delete_done_pro(self); } } } else { log_message(LOG_LEVEL_ERROR,"xrdp_listen_main_loop: listen error, possible port " "already in use"); } self->status = -1; return 0; }
/* wait for incoming connections */ int APP_CC xrdp_listen_main_loop(struct xrdp_listen* self) { int error; int robjs_count; int cont; int timeout = 0; char port[8]; char address[256]; tbus robjs[8]; tbus term_obj; tbus sync_obj; tbus sck_obj; tbus done_obj; self->status = 1; if (xrdp_listen_get_port_address(port, sizeof(port), address, sizeof(address)) != 0) { g_writeln("xrdp_listen_main_loop: xrdp_listen_get_port failed"); self->status = -1; return 1; } error = trans_listen_address(self->listen_trans, port, address); if (error == 0) { self->listen_trans->trans_conn_in = xrdp_listen_conn_in; self->listen_trans->callback_data = self; term_obj = g_get_term_event(); sync_obj = g_get_sync_event(); done_obj = self->pro_done_event; cont = 1; while (cont) { /* build the wait obj list */ robjs_count = 0; robjs[robjs_count++] = term_obj; robjs[robjs_count++] = sync_obj; robjs[robjs_count++] = done_obj; timeout = -1; if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count, &timeout) != 0) { break; } /* wait */ if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0) { /* error, should not get here */ g_sleep(100); } if (g_is_wait_obj_set(term_obj)) /* term */ { break; } if (g_is_wait_obj_set(sync_obj)) /* sync */ { g_reset_wait_obj(sync_obj); g_loop(); } if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { g_reset_wait_obj(done_obj); xrdp_listen_delete_done_pro(self); } if (trans_check_wait_objs(self->listen_trans) != 0) { break; } } /* stop listening */ trans_delete(self->listen_trans); self->listen_trans = 0; /* second loop to wait for all process threads to close */ cont = 1; while (cont) { if (self->process_list->count == 0) { break; } /* build the wait obj list */ robjs_count = 0; robjs[robjs_count++] = sync_obj; robjs[robjs_count++] = done_obj; /* wait */ if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0) { /* error, should not get here */ g_sleep(100); } if (g_is_wait_obj_set(sync_obj)) /* sync */ { g_reset_wait_obj(sync_obj); g_loop(); } if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { g_reset_wait_obj(done_obj); xrdp_listen_delete_done_pro(self); } } } else { DEBUG(("listen error in xrdp_listen_main_loop")); } self->status = -1; return 0; }