diff --git a/common/os_calls.c b/common/os_calls.c index 211adc82..80e5bad3 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -1069,28 +1069,39 @@ g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount, ptime = &time; } FD_ZERO(&rfds); - FD_ZERO(&wfds); - for (i = 0; i < rcount; i++) - { - sck = (int)(read_objs[i]); - if (sck > 0) { - FD_SET(sck, &rfds); - if (sck > max) - { - max = sck; + FD_ZERO(&wfds); + /*Find the highest descriptor number in read_obj */ + if(read_objs!=NULL){ + for (i = 0; i < rcount; i++) + { + sck = (int)(read_objs[i]); + if (sck > 0) { + FD_SET(sck, &rfds); + if (sck > max) + { + max = sck; /*max holds the highest socket/descriptor number */ + } } } + }else if(rcount>0){ + g_writeln("Programming error read_objs is null"); + return 1; /*error*/ } - for (i = 0; i < wcount; i++) - { - sck = (int)(write_objs[i]); - if (sck > 0) { - FD_SET(sck, &wfds); - if (sck > max) - { - max = sck; + if(write_objs!=NULL){ + for (i = 0; i < wcount; i++) + { + sck = (int)(write_objs[i]); + if (sck > 0) { + FD_SET(sck, &wfds); + if (sck > max) + { + max = sck; /*max holds the highest socket/descriptor number */ + } } } + }else if(wcount>0){ + g_writeln("Programming error write_objs is null"); + return 1; /*error*/ } res = select(max + 1, &rfds, &wfds, 0, ptime); if (res < 0) @@ -1103,7 +1114,7 @@ g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount, { return 0; } - return 1; + return 1; /*error*/ } return 0; #endif diff --git a/common/trans.c b/common/trans.c index 377b90ba..6b762d00 100644 --- a/common/trans.c +++ b/common/trans.c @@ -69,7 +69,7 @@ trans_delete(struct trans* self) /*****************************************************************************/ int APP_CC -trans_get_wait_objs(struct trans* self, tbus* objs, int* count, int* timeout) +trans_get_wait_objs(struct trans* self, tbus* objs, int* count) { if (self == 0) { diff --git a/common/trans.h b/common/trans.h index bb0f42c0..8e8d942a 100644 --- a/common/trans.h +++ b/common/trans.h @@ -64,7 +64,7 @@ trans_create(int mode, int in_size, int out_size); void APP_CC trans_delete(struct trans* self); int APP_CC -trans_get_wait_objs(struct trans* self, tbus* objs, int* count, int* timeout); +trans_get_wait_objs(struct trans* self, tbus* objs, int* count); int APP_CC trans_check_wait_objs(struct trans* self); int APP_CC diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index f2ca961d..e9d596cf 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -447,7 +447,7 @@ channel_thread_loop(void* in_val) num_objs = 0; objs[num_objs] = g_term_event; num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout); + trans_get_wait_objs(g_lis_trans, objs, &num_objs); while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) { if (g_is_wait_obj_set(g_term_event)) @@ -492,8 +492,8 @@ channel_thread_loop(void* in_val) num_objs = 0; objs[num_objs] = g_term_event; num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout); - trans_get_wait_objs(g_con_trans, objs, &num_objs, &timeout); + trans_get_wait_objs(g_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_con_trans, objs, &num_objs); clipboard_get_wait_objs(objs, &num_objs, &timeout); sound_get_wait_objs(objs, &num_objs, &timeout); dev_redir_get_wait_objs(objs, &num_objs, &timeout); diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index 95936cef..ac2aae45 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -22,6 +22,8 @@ #include "xrdp.h" +#define THREAD_WAITING 100 + static struct xrdp_listen* g_listen = 0; static long g_threadid = 0; /* main threadid */ @@ -37,6 +39,9 @@ static long g_sync_param2 = 0; static long (*g_sync_func)(long param1, long param2); /*****************************************************************************/ +/* This function is used to run a function from the main thread. + Sync_func is the function pointer that will run from main thread + The function can have two long in parameters and must return long */ long APP_CC g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, long sync_param2) @@ -44,32 +49,46 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, long sync_result; int sync_command; + /* If the function is called from the main thread, the function can + * be called directly. g_threadid= main thread ID*/ if (tc_threadid_equal(tc_get_threadid(), g_threadid)) { /* this is the main thread, call the function directly */ /* in fork mode, this always happens too */ sync_result = sync_func(sync_param1, sync_param2); + /*g_writeln("g_xrdp_sync processed IN main thread -> continue");*/ } else { + /* All threads have to wait here until the main thread + * process the function. g_process_waiting_function() is called + * from the listening thread. g_process_waiting_function() process the function*/ tc_mutex_lock(g_sync1_mutex); tc_mutex_lock(g_sync_mutex); g_sync_param1 = sync_param1; g_sync_param2 = sync_param2; g_sync_func = sync_func; - g_sync_command = 100; + /* set a value THREAD_WAITING so the g_process_waiting_function function + * know if any function must be processed */ + g_sync_command = THREAD_WAITING; tc_mutex_unlock(g_sync_mutex); - g_set_wait_obj(g_sync_event); + /* set this event so that the main thread know if + * g_process_waiting_function() must be called */ + g_set_wait_obj(g_sync_event); do { g_sleep(100); tc_mutex_lock(g_sync_mutex); - sync_command = g_sync_command; + /* load new value from global to see if the g_process_waiting_function() + * function has processed the function */ + sync_command = g_sync_command; sync_result = g_sync_result; tc_mutex_unlock(g_sync_mutex); } - while (sync_command != 0); + while (sync_command != 0); /* loop until g_process_waiting_function() + * has processed the request*/ tc_mutex_unlock(g_sync1_mutex); + /*g_writeln("g_xrdp_sync processed BY main thread -> continue");*/ } return sync_result; } @@ -159,15 +178,17 @@ pipe_sig(int sig_num) } /*****************************************************************************/ +/*Some function must be called from the main thread. + if g_sync_command==THREAD_WAITING a function is waiting to be processed*/ void APP_CC -g_loop(void) +g_process_waiting_function(void) { tc_mutex_lock(g_sync_mutex); if (g_sync_command != 0) { if (g_sync_func != 0) { - if (g_sync_command == 100) + if (g_sync_command == THREAD_WAITING) { g_sync_result = g_sync_func(g_sync_param1, g_sync_param2); } @@ -464,13 +485,17 @@ main(int argc, char** argv) pid = g_getpid(); g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); - g_sync_event = g_create_wait_obj(text); if (g_term_event == 0) { g_writeln("error creating g_term_event"); } - g_listen->startup_params = startup_params; + g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); + g_sync_event = g_create_wait_obj(text); + if (g_sync_event == 0) + { + g_writeln("error creating g_sync_event"); + } + g_listen->startup_params = startup_params; xrdp_listen_main_loop(g_listen); xrdp_listen_delete(g_listen); tc_mutex_delete(g_sync_mutex); diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 0bc4a24d..2ef81659 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -52,7 +52,7 @@ g_get_term_event(void); tbus APP_CC g_get_sync_event(void); void APP_CC -g_loop(void); +g_process_waiting_function(void); /* xrdp_cache.c */ struct xrdp_cache* APP_CC diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index bbdd729a..b79ce1c2 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -37,6 +37,10 @@ xrdp_listen_create_pro_done(struct xrdp_listen* self) pid = g_getpid(); g_snprintf(text, 255, "xrdp_%8.8x_listen_pro_done_event", pid); self->pro_done_event = g_create_wait_obj(text); + if(self->pro_done_event == 0) + { + g_writeln("Failure creating pro_done_event"); + } return 0; } @@ -295,7 +299,7 @@ xrdp_listen_main_loop(struct xrdp_listen* self) { self->listen_trans->trans_conn_in = xrdp_listen_conn_in; self->listen_trans->callback_data = self; - term_obj = g_get_term_event(); + term_obj = g_get_term_event(); /*Global termination event */ sync_obj = g_get_sync_event(); done_obj = self->pro_done_event; cont = 1; @@ -307,31 +311,33 @@ xrdp_listen_main_loop(struct xrdp_listen* self) 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) + if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count) != 0) { + g_writeln("Listening socket is in wrong state we terminate listener") ; break; } - /* wait */ + /* 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)) /* term */ + if (g_is_wait_obj_set(term_obj)) /* termination called */ { break; } - if (g_is_wait_obj_set(sync_obj)) /* sync */ + if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */ { g_reset_wait_obj(sync_obj); - g_loop(); + g_process_waiting_function(); /* run the function */ } if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { - g_reset_wait_obj(done_obj); + 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; @@ -348,20 +354,21 @@ xrdp_listen_main_loop(struct xrdp_listen* self) { break; } + timeout = -1; /* 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) + /* 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(sync_obj)) /* sync */ + if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */ { g_reset_wait_obj(sync_obj); - g_loop(); + g_process_waiting_function(); /* run the function that is waiting*/ } if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 223b128b..2d14351f 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -62,6 +62,7 @@ xrdp_mm_sync_load(long param1, long param2) static void APP_CC xrdp_mm_module_cleanup(struct xrdp_mm* self) { + g_writeln("xrdp_mm_module_cleanup"); if (self->mod != 0) { if (self->mod_exit != 0) @@ -72,7 +73,7 @@ xrdp_mm_module_cleanup(struct xrdp_mm* self) } if (self->mod_handle != 0) { - /* main thread unload */ + /* Let the main thread unload the module.*/ g_xrdp_sync(xrdp_mm_sync_unload, self->mod_handle, 0); } trans_delete(self->chan_trans); @@ -280,6 +281,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self) } if (self->mod_handle == 0) { + /* Let the main thread load the lib,*/ self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (long)lib, 0); if (self->mod_handle != 0) { @@ -1084,11 +1086,11 @@ xrdp_mm_get_wait_objs(struct xrdp_mm* self, rv = 0; if ((self->sesman_trans != 0) && self->sesman_trans_up) { - trans_get_wait_objs(self->sesman_trans, read_objs, rcount, timeout); + trans_get_wait_objs(self->sesman_trans, read_objs, rcount); } if ((self->chan_trans != 0) && self->chan_trans_up) { - trans_get_wait_objs(self->chan_trans, read_objs, rcount, timeout); + trans_get_wait_objs(self->chan_trans, read_objs, rcount); } if (self->mod != 0) { diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index df69d057..7a88d524 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -161,7 +161,7 @@ xrdp_process_main_loop(struct xrdp_process* self) robjs[robjs_count++] = self->self_term_event; xrdp_wm_get_wait_objs(self->wm, robjs, &robjs_count, wobjs, &wobjs_count, &timeout); - trans_get_wait_objs(self->server_trans, robjs, &robjs_count, &timeout); + trans_get_wait_objs(self->server_trans, robjs, &robjs_count); /* wait */ if (g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout) != 0) { diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c index d2c2d0f3..849f7112 100644 --- a/xrdp/xrdpwin.c +++ b/xrdp/xrdpwin.c @@ -140,7 +140,7 @@ pipe_sig(int sig_num) /*****************************************************************************/ void APP_CC -g_loop(void) +g_process_waiting_function(void) { tc_mutex_lock(g_sync_mutex); if (g_sync_command != 0)