diff --git a/sesman/lock.c b/sesman/lock.c index 912084a2..4c404fdc 100644 --- a/sesman/lock.c +++ b/sesman/lock.c @@ -34,6 +34,9 @@ pthread_mutexattr_t lock_chain_attr; /* mutex attributes */ pthread_mutex_t lock_config; /* configuration access lock */ pthread_mutexattr_t lock_config_attr; /* mutex attributes */ +static tbus g_sync_mutex; +static tbus g_sync_sem; + sem_t lock_socket; void DEFAULT_CC @@ -49,6 +52,9 @@ lock_init(void) /* initializing config lock */ pthread_mutexattr_init(&lock_config_attr); pthread_mutex_init(&lock_config, &lock_config_attr); + + g_sync_mutex = tc_mutex_create(); + g_sync_sem = tc_sem_create(0); } /******************************************************************************/ @@ -87,3 +93,38 @@ lock_socket_release(void) sem_post(&lock_socket); } +/******************************************************************************/ +void APP_CC +lock_sync_acquire(void) +{ + /* lock sync variable */ + LOG_DBG(&(g_cfg->log), "lock_sync_acquire()"); + tc_mutex_lock(g_sync_mutex); +} + +/******************************************************************************/ +void APP_CC +lock_sync_release(void) +{ + /* unlock socket variable */ + LOG_DBG(&(g_cfg->log), "lock_socket_release()"); + tc_mutex_unlock(g_sync_mutex); +} + +/******************************************************************************/ +void APP_CC +lock_sync_sem_acquire(void) +{ + /* dec sem */ + LOG_DBG(&(g_cfg->log), "lock_sync_dec()"); + tc_sem_dec(g_sync_sem); +} + +/******************************************************************************/ +void APP_CC +lock_sync_sem_release(void) +{ + /* inc sem */ + LOG_DBG(&(g_cfg->log), "lock_sync_inc()"); + tc_sem_inc(g_sync_sem); +} diff --git a/sesman/lock.h b/sesman/lock.h index 4d2a8655..5ea5e7f4 100644 --- a/sesman/lock.h +++ b/sesman/lock.h @@ -78,5 +78,36 @@ lock_socket_acquire(void); void DEFAULT_CC lock_socket_release(void); -#endif +/** + * + * @brief request the main sync lock + * + */ +void APP_CC +lock_sync_acquire(void); +/** + * + * @brief releases the main sync lock + * + */ +void APP_CC +lock_sync_release(void); + +/** + * + * @brief request the sync sem lock + * + */ +void APP_CC +lock_sync_sem_acquire(void); + +/** + * + * @brief releases the sync sem lock + * + */ +void APP_CC +lock_sync_sem_release(void); + +#endif diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index e006ad33..918badc9 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -34,7 +34,7 @@ void DEFAULT_CC scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) { int display = 0; - long data; + tbus data; struct session_item* s_item; data = auth_userpass(s->username, s->password); diff --git a/sesman/sesman.c b/sesman/sesman.c index c9c5992e..4ce3cdfd 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -33,6 +33,7 @@ unsigned char g_fixedkey[8] = { 23, 82, 107, 6, 35, 78, 88, 7 }; struct config_sesman* g_cfg; /* config.h */ tbus g_term_event = 0; +tbus g_sync_event = 0; extern int g_thread_sck; /* in thread.c */ @@ -70,6 +71,7 @@ sesman_main_loop(void) robjs_count = 0; robjs[robjs_count++] = sck_obj; robjs[robjs_count++] = g_term_event; + robjs[robjs_count++] = g_sync_event; /* wait */ if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0) { @@ -80,6 +82,11 @@ sesman_main_loop(void) { break; } + if (g_is_wait_obj_set(g_sync_event)) /* sync */ + { + g_reset_wait_obj(g_sync_event); + session_sync_start(); + } if (g_is_wait_obj_set(sck_obj)) /* incomming connection */ { in_sck = g_tcp_accept(g_sck); @@ -318,10 +325,13 @@ main(int argc, char** argv) g_snprintf(text, 255, "xrdp-sesman_%8.8x_main_term", g_pid); g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp-sesman_%8.8x_main_sync", g_pid); + g_sync_event = g_create_wait_obj(text); sesman_main_loop(); g_delete_wait_obj(g_term_event); + g_delete_wait_obj(g_sync_event); if (!daemon) { diff --git a/sesman/session.c b/sesman/session.c index 08e5efad..1e67ae1a 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -31,11 +31,21 @@ #include //#include +extern tbus g_sync_event; extern unsigned char g_fixedkey[8]; extern struct config_sesman* g_cfg; /* config.h */ struct session_chain* g_sessions; int g_session_count; +static int g_sync_width; +static int g_sync_height; +static int g_sync_bpp; +static char* g_sync_username; +static char* g_sync_password; +static tbus g_sync_data; +static tui8 g_sync_type; +static int g_sync_result; + /******************************************************************************/ struct session_item* DEFAULT_CC session_get_bydata(char* name, int width, int height, int bpp) @@ -171,9 +181,10 @@ session_start_sessvc(int xpid, int wmpid, long data) } /******************************************************************************/ -int DEFAULT_CC -session_start(int width, int height, int bpp, char* username, char* password, - long data, unsigned char type) +/* called with the main thread */ +static int APP_CC +session_start_fork(int width, int height, int bpp, char* username, + char* password, tbus data, tui8 type) { int display; int pid; @@ -191,21 +202,14 @@ session_start(int width, int height, int bpp, char* username, char* password, time_t ltime; struct tm stime; - /*THREAD-FIX lock to control g_session_count*/ - lock_chain_acquire(); /* check to limit concurrent sessions */ if (g_session_count >= g_cfg->sess.max_sessions) { - /*THREAD-FIX unlock chain*/ - lock_chain_release(); log_message(&(g_cfg->log), LOG_LEVEL_INFO, "max concurrent session limit exceeded. login \ for user %s denied", username); return 0; } - /*THREAD-FIX unlock chain*/ - lock_chain_release(); - temp = (struct session_chain*)g_malloc(sizeof(struct session_chain), 0); if (temp == 0) { @@ -228,8 +232,6 @@ for user %s denied", username); /* we search for a free display up to max_sessions */ /* we should need no more displays than this */ - /* block all the threads running to enable forking */ - scp_lock_fork_request(); while (x_server_running(display)) { display++; @@ -412,9 +414,6 @@ for user %s denied", username); } else /* parent sesman process */ { - /* let the other threads go on */ - scp_lock_fork_release(); - temp->item->pid = pid; temp->item->display = display; temp->item->width = width; @@ -436,19 +435,59 @@ for user %s denied", username); temp->item->type=type; temp->item->status=SESMAN_SESSION_STATUS_ACTIVE; - /*THREAD-FIX lock the chain*/ - lock_chain_acquire(); temp->next=g_sessions; g_sessions=temp; g_session_count++; - /*THERAD-FIX free the chain*/ - lock_chain_release(); + } + return display; +} +/******************************************************************************/ +/* called by a worker thread, ask the main thread to call session_sync_start + and wait till done */ +int DEFAULT_CC +session_start(int width, int height, int bpp, char* username, char* password, + long data, unsigned char type) +{ + int display; + + /* lock mutex */ + lock_sync_acquire(); + /* set shared vars */ + g_sync_width = width; + g_sync_height = height; + g_sync_bpp = bpp; + g_sync_username = username; + g_sync_password = password; + g_sync_data = data; + g_sync_type = type; + /* set event for main thread to see */ + g_set_wait_obj(g_sync_event); + /* wait for main thread to get done */ + lock_sync_sem_acquire(); + /* read result(display) from shared var */ + display = g_sync_result; + /* unlock mutex */ + lock_sync_release(); + if (display != 0) + { g_sleep(5000); } return display; } +/******************************************************************************/ +/* called with the main thread */ +int APP_CC +session_sync_start(void) +{ + g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp, + g_sync_username, g_sync_password, + g_sync_data, g_sync_type); + lock_sync_sem_release(); + return 0; +} + /******************************************************************************/ int DEFAULT_CC session_kill(int pid) diff --git a/sesman/session.h b/sesman/session.h index 41acea2a..c434a104 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -103,7 +103,16 @@ session_get_bydata(char* name, int width, int height, int bpp); */ int DEFAULT_CC session_start(int width, int height, int bpp, char* username, char* password, - long data, unsigned char type); + tbus data, tui8 type); + +/** + * + * @brief starts a session + * @return error + * + */ +int APP_CC +session_sync_start(void); /** *