Merge pull request #2511 from Nexarian/egfx_tests
A simple working unit test for the newly introduced EGFX functions
This commit is contained in:
commit
29ef7f896a
@ -1692,12 +1692,7 @@ int
|
||||
g_set_wait_obj(tintptr obj)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (obj == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
SetEvent((HANDLE)obj);
|
||||
return 0;
|
||||
#error "Win32 is no longer supported."
|
||||
#else
|
||||
int error;
|
||||
int fd;
|
||||
@ -1709,7 +1704,7 @@ g_set_wait_obj(tintptr obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fd = obj & 0xffff;
|
||||
fd = obj & USHRT_MAX;
|
||||
if (g_fd_can_read(fd))
|
||||
{
|
||||
/* already signalled */
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include "xrdp_rail.h"
|
||||
|
||||
struct list;
|
||||
|
||||
/* struct xrdp_client_info moved to xrdp_client_info.h */
|
||||
|
||||
struct xrdp_brush
|
||||
|
@ -19,6 +19,8 @@
|
||||
#if !defined(_XRDP_ORDERS_RAIL_H)
|
||||
#define _XRDP_ORDERS_RAIL_H
|
||||
|
||||
#include "libxrdp.h"
|
||||
|
||||
int
|
||||
xrdp_orders_send_window_delete(struct xrdp_orders *self, int window_id);
|
||||
int
|
||||
|
@ -26,6 +26,7 @@ check_PROGRAMS = test_xrdp
|
||||
test_xrdp_SOURCES = \
|
||||
test_xrdp.h \
|
||||
test_xrdp_main.c \
|
||||
test_xrdp_egfx.c \
|
||||
test_bitmap_load.c
|
||||
|
||||
test_xrdp_CFLAGS = \
|
||||
@ -37,5 +38,24 @@ test_xrdp_LDADD = \
|
||||
$(top_builddir)/xrdp/xrdp_bitmap_common.o \
|
||||
$(top_builddir)/xrdp/funcs.o \
|
||||
$(top_builddir)/common/libcommon.la \
|
||||
$(top_builddir)/libipm/libipm.la \
|
||||
$(top_builddir)/libxrdp/libxrdp.la \
|
||||
$(top_builddir)/libpainter/src/libpainter.la \
|
||||
$(top_builddir)/librfxcodec/src/librfxencode.la \
|
||||
$(top_builddir)/xrdp/lang.o \
|
||||
$(top_builddir)/xrdp/xrdp_mm.o \
|
||||
$(top_builddir)/xrdp/xrdp_wm.o \
|
||||
$(top_builddir)/xrdp/xrdp_font.o \
|
||||
$(top_builddir)/xrdp/xrdp_egfx.o \
|
||||
$(top_builddir)/xrdp/xrdp_cache.o \
|
||||
$(top_builddir)/xrdp/xrdp_region.o \
|
||||
$(top_builddir)/xrdp/xrdp_listen.o \
|
||||
$(top_builddir)/xrdp/xrdp_bitmap.o \
|
||||
$(top_builddir)/xrdp/xrdp_painter.o \
|
||||
$(top_builddir)/xrdp/xrdp_encoder.o \
|
||||
$(top_builddir)/xrdp/xrdp_process.o \
|
||||
$(top_builddir)/xrdp/xrdp_login_wnd.o \
|
||||
$(top_builddir)/xrdp/xrdp_main_utils.o \
|
||||
$(PIXMAN_LIBS) \
|
||||
$(IMLIB2_LIBS) \
|
||||
@CHECK_LIBS@
|
||||
|
@ -4,5 +4,6 @@
|
||||
#include <check.h>
|
||||
|
||||
Suite *make_suite_test_bitmap_load(void);
|
||||
Suite *make_suite_egfx_base_functions(void);
|
||||
|
||||
#endif /* TEST_XRDP_H */
|
||||
|
76
tests/xrdp/test_xrdp_egfx.c
Normal file
76
tests/xrdp/test_xrdp_egfx.c
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Test driver for XRDP routines
|
||||
*
|
||||
* If you want to run this driver under valgrind to check for memory leaks,
|
||||
* use the following command line:-
|
||||
*
|
||||
* CK_FORK=no valgrind --leak-check=full --show-leak-kinds=all \
|
||||
* .libs/test_xrdp
|
||||
*
|
||||
* without the 'CK_FORK=no', memory still allocated by the test driver will
|
||||
* be logged
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config_ac.h"
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "os_calls.h"
|
||||
#include <stdlib.h>
|
||||
#include "xrdp_egfx.h"
|
||||
#include "test_xrdp.h"
|
||||
|
||||
START_TEST(test_xrdp_egfx_send_create_surface__happy_path)
|
||||
{
|
||||
struct xrdp_egfx_bulk *bulk = g_new0(struct xrdp_egfx_bulk, 1);
|
||||
|
||||
const int surface_id = 0xFF;
|
||||
const int width = 640;
|
||||
const int height = 480;
|
||||
const int pixel_format = 32;
|
||||
|
||||
struct stream *s = xrdp_egfx_create_surface(
|
||||
bulk, surface_id, width, height, pixel_format);
|
||||
s->p = s->data;
|
||||
|
||||
unsigned char descriptor;
|
||||
in_uint8(s, descriptor);
|
||||
ck_assert_int_eq(0xE0, descriptor);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/******************************************************************************/
|
||||
Suite *
|
||||
make_suite_egfx_base_functions(void)
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc_process_monitors;
|
||||
|
||||
s = suite_create("test_xrdp_egfx_base_functions");
|
||||
|
||||
tc_process_monitors = tcase_create("xrdp_egfx_base_functions");
|
||||
tcase_add_test(tc_process_monitors,
|
||||
test_xrdp_egfx_send_create_surface__happy_path);
|
||||
|
||||
suite_add_tcase(s, tc_process_monitors);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ int main (void)
|
||||
log_config_free(logging);
|
||||
|
||||
sr = srunner_create (make_suite_test_bitmap_load());
|
||||
srunner_add_suite(sr, make_suite_egfx_base_functions());
|
||||
|
||||
srunner_set_tap(sr, "-");
|
||||
srunner_run_all (sr, CK_ENV);
|
||||
|
@ -60,7 +60,8 @@ xrdp_SOURCES = \
|
||||
xrdp_types.h \
|
||||
xrdp_egfx.c \
|
||||
xrdp_egfx.h \
|
||||
xrdp_wm.c
|
||||
xrdp_wm.c \
|
||||
xrdp_main_utils.c
|
||||
|
||||
xrdp_LDADD = \
|
||||
$(top_builddir)/common/libcommon.la \
|
||||
|
205
xrdp/xrdp.c
205
xrdp/xrdp.c
@ -33,21 +33,7 @@
|
||||
#define PACKAGE_VERSION "???"
|
||||
#endif
|
||||
|
||||
#define THREAD_WAITING 100
|
||||
|
||||
static struct xrdp_listen *g_listen = 0;
|
||||
static long g_threadid = 0; /* main threadid */
|
||||
|
||||
static long g_sync_mutex = 0;
|
||||
static long g_sync1_mutex = 0;
|
||||
static tbus g_term_event = 0;
|
||||
static tbus g_sync_event = 0;
|
||||
/* synchronize stuff */
|
||||
static int g_sync_command = 0;
|
||||
static long g_sync_result = 0;
|
||||
static long g_sync_param1 = 0;
|
||||
static long g_sync_param2 = 0;
|
||||
static long (*g_sync_func)(long param1, long param2);
|
||||
|
||||
/*****************************************************************************/
|
||||
static void
|
||||
@ -84,63 +70,6 @@ print_help(void)
|
||||
g_writeln(" --dump-config display config on stdout on startup");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* 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
|
||||
g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
|
||||
long sync_param2)
|
||||
{
|
||||
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);
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "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;
|
||||
/* 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);
|
||||
/* 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);
|
||||
/* 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); /* loop until g_process_waiting_function()
|
||||
* has processed the request */
|
||||
tc_mutex_unlock(g_sync1_mutex);
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "g_xrdp_sync processed BY main thread -> continue");
|
||||
}
|
||||
|
||||
return sync_result;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Signal handler for SIGINT and SIGTERM
|
||||
* Note: only signal safe code (eg. setting wait event) should be executed in
|
||||
@ -149,10 +78,7 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
|
||||
static void
|
||||
xrdp_shutdown(int sig)
|
||||
{
|
||||
if (!g_is_wait_obj_set(g_term_event))
|
||||
{
|
||||
g_set_wait_obj(g_term_event);
|
||||
}
|
||||
g_set_wait_obj(g_get_term());
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -168,95 +94,6 @@ xrdp_child(int sig)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* No-op signal handler.
|
||||
* Note: only signal safe code (eg. setting wait event) should be executed in
|
||||
* this function. For more details see `man signal-safety`
|
||||
*/
|
||||
static void
|
||||
xrdp_sig_no_op(int sig)
|
||||
{
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* called in child just after fork */
|
||||
int
|
||||
xrdp_child_fork(void)
|
||||
{
|
||||
int pid;
|
||||
char text[256];
|
||||
|
||||
/* close, don't delete these */
|
||||
g_close_wait_obj(g_term_event);
|
||||
g_close_wait_obj(g_sync_event);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_is_term(void)
|
||||
{
|
||||
return g_is_wait_obj_set(g_term_event);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
g_set_term(int in_val)
|
||||
{
|
||||
if (in_val)
|
||||
{
|
||||
g_set_wait_obj(g_term_event);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_reset_wait_obj(g_term_event);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
tbus
|
||||
g_get_term_event(void)
|
||||
{
|
||||
return g_term_event;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
tbus
|
||||
g_get_sync_event(void)
|
||||
{
|
||||
return g_sync_event;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*Some function must be called from the main thread.
|
||||
if g_sync_command==THREAD_WAITING a function is waiting to be processed*/
|
||||
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 == THREAD_WAITING)
|
||||
{
|
||||
g_sync_result = g_sync_func(g_sync_param1, g_sync_param2);
|
||||
}
|
||||
}
|
||||
|
||||
g_sync_command = 0;
|
||||
}
|
||||
|
||||
tc_mutex_unlock(g_sync_mutex);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief looks for a case-insensitive match of a string in a list
|
||||
@ -284,6 +121,16 @@ static int nocase_matches(const char *candidate, ...)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* No-op signal handler.
|
||||
* Note: only signal safe code (eg. setting wait event) should be executed in
|
||||
* this function. For more details see `man signal-safety`
|
||||
*/
|
||||
static void
|
||||
xrdp_sig_no_op(int sig)
|
||||
{
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
@ -672,29 +519,29 @@ main(int argc, char **argv)
|
||||
/* end of daemonizing code */
|
||||
}
|
||||
|
||||
g_threadid = tc_get_threadid();
|
||||
g_set_threadid(tc_get_threadid());
|
||||
g_listen = xrdp_listen_create();
|
||||
g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */
|
||||
g_signal_pipe(xrdp_sig_no_op); /* SIGPIPE */
|
||||
g_signal_terminate(xrdp_shutdown); /* SIGTERM */
|
||||
g_signal_child_stop(xrdp_child); /* SIGCHLD */
|
||||
g_signal_hang_up(xrdp_sig_no_op); /* SIGHUP */
|
||||
g_sync_mutex = tc_mutex_create();
|
||||
g_sync1_mutex = tc_mutex_create();
|
||||
g_set_sync_mutex(tc_mutex_create());
|
||||
g_set_sync1_mutex(tc_mutex_create());
|
||||
pid = g_getpid();
|
||||
LOG(LOG_LEVEL_INFO, "starting xrdp with pid %d", pid);
|
||||
g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid);
|
||||
g_term_event = g_create_wait_obj(text);
|
||||
g_set_term_event(g_create_wait_obj(text));
|
||||
|
||||
if (g_term_event == 0)
|
||||
if (g_get_term() == 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "error creating g_term_event");
|
||||
}
|
||||
|
||||
g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid);
|
||||
g_sync_event = g_create_wait_obj(text);
|
||||
g_set_sync_event(g_create_wait_obj(text));
|
||||
|
||||
if (g_sync_event == 0)
|
||||
if (g_get_sync_event() == 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "error creating g_sync_event");
|
||||
}
|
||||
@ -702,10 +549,18 @@ main(int argc, char **argv)
|
||||
g_listen->startup_params = &startup_params;
|
||||
exit_status = xrdp_listen_main_loop(g_listen);
|
||||
xrdp_listen_delete(g_listen);
|
||||
tc_mutex_delete(g_sync_mutex);
|
||||
tc_mutex_delete(g_sync1_mutex);
|
||||
g_delete_wait_obj(g_term_event);
|
||||
g_delete_wait_obj(g_sync_event);
|
||||
|
||||
tc_mutex_delete(g_get_sync_mutex());
|
||||
g_set_sync_mutex(0);
|
||||
|
||||
tc_mutex_delete(g_get_sync1_mutex());
|
||||
g_set_sync1_mutex(0);
|
||||
|
||||
g_delete_wait_obj(g_get_term());
|
||||
g_set_term_event(0);
|
||||
|
||||
g_delete_wait_obj(g_get_sync_event());
|
||||
g_set_sync_event(0);
|
||||
|
||||
/* only main process should delete pid file */
|
||||
if (daemon && (pid == g_getpid()))
|
||||
|
20
xrdp/xrdp.h
20
xrdp/xrdp.h
@ -41,13 +41,29 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
|
||||
long sync_param2);
|
||||
int
|
||||
xrdp_child_fork(void);
|
||||
long
|
||||
g_get_sync_mutex(void);
|
||||
void
|
||||
g_set_sync_mutex(long mutex);
|
||||
long
|
||||
g_get_sync1_mutex(void);
|
||||
void
|
||||
g_set_sync1_mutex(long mutex);
|
||||
void
|
||||
g_set_term_event(tbus event);
|
||||
void
|
||||
g_set_sync_event(tbus event);
|
||||
long
|
||||
g_get_threadid(void);
|
||||
void
|
||||
g_set_threadid(long id);
|
||||
tbus
|
||||
g_get_term(void);
|
||||
int
|
||||
g_is_term(void);
|
||||
void
|
||||
g_set_term(int in_val);
|
||||
tbus
|
||||
g_get_term_event(void);
|
||||
tbus
|
||||
g_get_sync_event(void);
|
||||
void
|
||||
g_process_waiting_function(void);
|
||||
|
@ -18,6 +18,14 @@
|
||||
* MS-RDPEGFX
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @file xrdp_egfx.c
|
||||
* @brief Stream functions for the EGFX extension to the MSRDP protocol.
|
||||
* @author Jay Sorg, Christopher Pitstick
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
@ -29,7 +37,6 @@
|
||||
#include "arch.h"
|
||||
#include "os_calls.h"
|
||||
#include "parse.h"
|
||||
#include "xrdp.h"
|
||||
#include "xrdp_egfx.h"
|
||||
#include "libxrdp.h"
|
||||
#include "xrdp_channel.h"
|
||||
|
@ -18,9 +18,19 @@
|
||||
* MS-RDPEGFX
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @file xrdp_egfx.h
|
||||
* @brief Stream function headers for the EGFX extension to the MSRDP protocol.
|
||||
* @author Jay Sorg, Christopher Pitstick
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _XRDP_EGFX_H
|
||||
#define _XRDP_EGFX_H
|
||||
|
||||
#include "xrdp.h"
|
||||
|
||||
#define XR_RDPGFX_CAPVERSION_8 0x00080004
|
||||
#define XR_RDPGFX_CAPVERSION_81 0x00080105
|
||||
#define XR_RDPGFX_CAPVERSION_10 0x000A0002
|
||||
|
@ -481,7 +481,7 @@ proc_enc_msg(void *arg)
|
||||
mutex = self->mutex;
|
||||
event_to_proc = self->xrdp_encoder_event_to_proc;
|
||||
|
||||
term_obj = g_get_term_event();
|
||||
term_obj = g_get_term();
|
||||
lterm_obj = self->xrdp_encoder_term;
|
||||
|
||||
cont = 1;
|
||||
|
@ -875,7 +875,7 @@ xrdp_listen_main_loop(struct xrdp_listen *self)
|
||||
self->status = -1;
|
||||
return 1;
|
||||
}
|
||||
term_obj = g_get_term_event(); /*Global termination event */
|
||||
term_obj = g_get_term(); /*Global termination event */
|
||||
sync_obj = g_get_sync_event();
|
||||
done_obj = self->pro_done_event;
|
||||
cont = 1;
|
||||
|
239
xrdp/xrdp_main_utils.c
Normal file
239
xrdp/xrdp_main_utils.c
Normal file
@ -0,0 +1,239 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2014
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @file xrdp_main_utils.c
|
||||
* @brief Functions used by XRDP's main() routine and needed elsewhere.
|
||||
* @author Jay Sorg, Christopher Pitstick
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include "xrdp.h"
|
||||
#include "log.h"
|
||||
|
||||
#define THREAD_WAITING 100
|
||||
|
||||
static long g_threadid = 0; /* main threadid */
|
||||
|
||||
static long g_sync_mutex = 0;
|
||||
static long g_sync1_mutex = 0;
|
||||
static tbus g_term_event = 0;
|
||||
static tbus g_sync_event = 0;
|
||||
/* synchronize stuff */
|
||||
static int g_sync_command = 0;
|
||||
static long g_sync_result = 0;
|
||||
static long g_sync_param1 = 0;
|
||||
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
|
||||
g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
|
||||
long sync_param2)
|
||||
{
|
||||
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);
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "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;
|
||||
/* 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);
|
||||
/* 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);
|
||||
/* 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); /* loop until g_process_waiting_function()
|
||||
* has processed the request */
|
||||
tc_mutex_unlock(g_sync1_mutex);
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "g_xrdp_sync processed BY main thread -> continue");
|
||||
}
|
||||
|
||||
return sync_result;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* called in child just after fork */
|
||||
int
|
||||
xrdp_child_fork(void)
|
||||
{
|
||||
int pid;
|
||||
char text[256];
|
||||
|
||||
/* close, don't delete these */
|
||||
g_close_wait_obj(g_term_event);
|
||||
g_close_wait_obj(g_sync_event);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
long
|
||||
g_get_sync_mutex(void)
|
||||
{
|
||||
return g_sync_mutex;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
g_set_sync_mutex(long mutex)
|
||||
{
|
||||
g_sync_mutex = mutex;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
long
|
||||
g_get_sync1_mutex(void)
|
||||
{
|
||||
return g_sync1_mutex;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
g_set_sync1_mutex(long mutex)
|
||||
{
|
||||
g_sync1_mutex = mutex;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
g_set_term_event(tbus event)
|
||||
{
|
||||
g_term_event = event;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
tbus
|
||||
g_get_sync_event(void)
|
||||
{
|
||||
return g_sync_event;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
g_set_sync_event(tbus event)
|
||||
{
|
||||
g_sync_event = event;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
long
|
||||
g_get_threadid(void)
|
||||
{
|
||||
return g_threadid;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
g_set_threadid(long id)
|
||||
{
|
||||
g_threadid = id;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
tbus
|
||||
g_get_term(void)
|
||||
{
|
||||
return g_term_event;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_is_term(void)
|
||||
{
|
||||
return g_is_wait_obj_set(g_term_event);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
g_set_term(int in_val)
|
||||
{
|
||||
if (in_val)
|
||||
{
|
||||
g_set_wait_obj(g_term_event);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_reset_wait_obj(g_term_event);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*Some function must be called from the main thread.
|
||||
if g_sync_command==THREAD_WAITING a function is waiting to be processed*/
|
||||
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 == THREAD_WAITING)
|
||||
{
|
||||
g_sync_result = g_sync_func(g_sync_param1, g_sync_param2);
|
||||
}
|
||||
}
|
||||
|
||||
g_sync_command = 0;
|
||||
}
|
||||
|
||||
tc_mutex_unlock(g_sync_mutex);
|
||||
}
|
@ -249,7 +249,7 @@ xrdp_process_main_loop(struct xrdp_process *self)
|
||||
{
|
||||
init_stream(self->server_trans->in_s, 32 * 1024);
|
||||
|
||||
term_obj = g_get_term_event();
|
||||
term_obj = g_get_term();
|
||||
cont = 1;
|
||||
|
||||
while (cont)
|
||||
|
@ -122,13 +122,6 @@ g_set_term(int in_val)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
tbus
|
||||
g_get_term_event(void)
|
||||
{
|
||||
return g_term_event;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
tbus
|
||||
g_get_sync_event(void)
|
||||
|
Loading…
Reference in New Issue
Block a user