summaryrefslogtreecommitdiffstats
path: root/x11vnc/connections.c
diff options
context:
space:
mode:
authorrunge <runge@karlrunge.com>2009-05-21 10:57:03 -0400
committerrunge <runge@karlrunge.com>2009-05-21 10:57:03 -0400
commit94d058b35f075cec2d6e8b6e37ee1a94086ea3f8 (patch)
tree6cec0620ab70b5db6b33645dbcac1071f3c7a556 /x11vnc/connections.c
parent804335f9d296440bb708ca844f5d89b58b50b0c6 (diff)
downloadlibvncserver-94d058b35f075cec2d6e8b6e37ee1a94086ea3f8.zip
libvncserver-94d058b35f075cec2d6e8b6e37ee1a94086ea3f8.tar.gz
Thread safety. Fix -clip -in -rawfb. Try to avoid Xorg stuck
key bug.
Diffstat (limited to 'x11vnc/connections.c')
-rw-r--r--x11vnc/connections.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/x11vnc/connections.c b/x11vnc/connections.c
index 8321d14..b0fa11a 100644
--- a/x11vnc/connections.c
+++ b/x11vnc/connections.c
@@ -80,6 +80,7 @@ void set_x11vnc_remote_prop(char *str);
void read_x11vnc_remote_prop(int);
void check_connect_inputs(void);
void check_gui_inputs(void);
+rfbClientPtr create_new_client(int sock, int start_thread);
enum rfbNewClientAction new_client(rfbClientPtr client);
enum rfbNewClientAction new_client_chat_helper(rfbClientPtr client);
rfbBool password_check_chat_helper(rfbClientPtr cl, const char* response, int len);
@@ -704,6 +705,8 @@ static int accepted_client = 0;
void client_gone(rfbClientPtr client) {
ClientData *cd = NULL;
+ CLIENT_LOCK;
+
client_count--;
if (client_count < 0) client_count = 0;
@@ -800,6 +803,7 @@ void client_gone(rfbClientPtr client) {
}
clean_up_exit(0);
}
+
if (connect_once) {
/*
* This non-exit is done for a bad passwd to be consistent
@@ -814,11 +818,13 @@ void client_gone(rfbClientPtr client) {
"disconnect.\n");
rfbLog("connect_once: waiting for next connection.\n");
accepted_client = 0;
+ CLIENT_UNLOCK;
return;
}
if (shared && client_count > 0) {
rfbLog("connect_once: other shared clients still "
"connected, not exiting.\n");
+ CLIENT_UNLOCK;
return;
}
@@ -827,6 +833,7 @@ void client_gone(rfbClientPtr client) {
rfbLog("killing gui_pid %d\n", gui_pid);
kill(gui_pid, SIGTERM);
}
+ CLIENT_UNLOCK;
clean_up_exit(0);
}
#ifdef MACOSX
@@ -834,6 +841,7 @@ void client_gone(rfbClientPtr client) {
macosxCG_refresh_callback_off();
}
#endif
+ CLIENT_UNLOCK;
}
/*
@@ -2417,7 +2425,7 @@ static int do_reverse_connect(char *str_in) {
write(sock, prestring, prestring_len);
free(prestring);
}
- cl = rfbNewClient(screen, sock);
+ cl = create_new_client(sock, 1);
} else {
return 0;
}
@@ -2426,12 +2434,16 @@ static int do_reverse_connect(char *str_in) {
if (sock >= 0) {
write(sock, prestring, prestring_len);
free(prestring);
- cl = rfbNewClient(screen, sock);
+ cl = create_new_client(sock, 1);
} else {
return 0;
}
} else {
cl = rfbReverseConnection(screen, host, rport);
+ if (cl != NULL && use_threads) {
+ cl->onHold = FALSE;
+ rfbStartOnHoldClient(cl);
+ }
}
free(host);
@@ -2846,6 +2858,27 @@ void check_gui_inputs(void) {
}
}
+rfbClientPtr create_new_client(int sock, int start_thread) {
+ rfbClientPtr cl;
+
+ if (!screen) {
+ return NULL;
+ }
+
+ cl = rfbNewClient(screen, sock);
+
+ if (cl == NULL) {
+ return NULL;
+ }
+ if (use_threads) {
+ cl->onHold = FALSE;
+ if (start_thread) {
+ rfbStartOnHoldClient(cl);
+ }
+ }
+ return cl;
+}
+
static int turn_off_truecolor = 0;
static void turn_off_truecolor_ad(rfbClientPtr client) {
@@ -2925,6 +2958,8 @@ void client_set_net(rfbClientPtr client) {
enum rfbNewClientAction new_client(rfbClientPtr client) {
ClientData *cd;
+ CLIENT_LOCK;
+
last_event = last_input = time(NULL);
latest_client = client;
@@ -2942,16 +2977,19 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
clients_served++;
+
if (use_openssl || use_stunnel) {
if (! ssl_initialized) {
rfbLog("denying additional client: %s ssl not setup"
" yet.\n", client->host);
+ CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
}
if (unixpw_in_progress) {
rfbLog("denying additional client: %s during -unixpw login.\n",
client->host);
+ CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
if (connect_once) {
@@ -2959,13 +2997,16 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
if (! shared && accepted_client) {
rfbLog("denying additional client: %s\n",
client->host);
+ CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
}
}
+
if (! check_access(client->host)) {
rfbLog("denying client: %s does not match %s\n", client->host,
allow_list ? allow_list : "(null)" );
+ CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
@@ -2995,6 +3036,7 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
free_client_data(client);
+ CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
@@ -3075,6 +3117,8 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
bm--;
}
+ if (use_threads) LOCK(client->updateMutex);
+
client->format.trueColour = TRUE;
client->format.redShift = rs;
client->format.greenShift = gs;
@@ -3083,6 +3127,8 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
client->format.greenMax = gm;
client->format.blueMax = bm;
+ if (use_threads) UNLOCK(client->updateMutex);
+
rfbSetTranslateFunction(client);
screen->serverFormat.trueColour = TRUE;
@@ -3124,10 +3170,17 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
rfbLog("new client: %s in non-unixpw_in_rfbPE.\n",
client->host);
}
- /* always put client on hold even if unixpw_in_rfbPE is true */
- return(RFB_CLIENT_ON_HOLD);
+ CLIENT_UNLOCK;
+ if (!use_threads) {
+ /* always put client on hold even if unixpw_in_rfbPE is true */
+ return(RFB_CLIENT_ON_HOLD);
+ } else {
+ /* unixpw threads is still in testing mode, disabled by default. See UNIXPW_THREADS */
+ return(RFB_CLIENT_ACCEPT);
+ }
}
+ CLIENT_UNLOCK;
return(RFB_CLIENT_ACCEPT);
}
OpenPOWER on IntegriCloud