]> prime8.dev >> repos - ttyd.git/commitdiff
all: remove pthread
authorShuanglei Tao <tsl0922@gmail.com>
Sun, 15 Sep 2019 10:09:48 +0000 (18:09 +0800)
committerShuanglei Tao <tsl0922@gmail.com>
Sun, 15 Sep 2019 10:39:30 +0000 (18:39 +0800)
CMakeLists.txt
src/http.c
src/protocol.c
src/server.c
src/server.h

index 4929624475f52b86e7b9fa3301880f241abca51d..132fa76c69f0befb2de49b141da1984e7a03e535 100644 (file)
@@ -67,7 +67,7 @@ add_custom_command(OUTPUT html.h
 list(APPEND SOURCE_FILES html.h)
 
 set(INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR} ${LIBWEBSOCKETS_INCLUDE_DIR} ${JSON-C_INCLUDE_DIR})
-set(LINK_LIBS pthread ${OPENSSL_LIBRARIES} ${LIBWEBSOCKETS_LIBRARIES} ${JSON-C_LIBRARY})
+set(LINK_LIBS ${OPENSSL_LIBRARIES} ${LIBWEBSOCKETS_LIBRARIES} ${JSON-C_LIBRARY})
 
 if(APPLE)
     # required for the new homebrew version of libwebsockets
index 747965e2bb032b84ba394e22ef59d283aa343c1b..195ede22db3d6daa78c7ccf85de3b460930e48c6 100644 (file)
@@ -61,10 +61,11 @@ check_auth(struct lws *wsi, struct pss_http *pss) {
     return AUTH_FAIL;
 }
 
-void access_log(struct lws *wsi, const char *path) {
+void
+access_log(struct lws *wsi, const char *path) {
     char rip[50];
 
-#if LWS_LIBRARY_VERSION_MAJOR > 2 || (LWS_LIBRARY_VERSION_MAJOR ==2 && LWS_LIBRARY_VERSION_MINOR >=4)
+#if LWS_LIBRARY_VERSION_NUMBER >= 2004000
     lws_get_peer_simple(lws_get_network_wsi(wsi), rip, sizeof(rip));
 #else
     char name[100];
index f8371831a735f9739b312383506cdb62bc4ad179..108284fe3c4fe9280ee3a678002e805caf3ddc87 100644 (file)
@@ -7,9 +7,6 @@
 #include <errno.h>
 #include <sys/ioctl.h>
 #include <sys/queue.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <pthread.h>
 
 #if defined(__OpenBSD__) || defined(__APPLE__)
 #include <util.h>
@@ -111,7 +108,6 @@ check_host_origin(struct lws *wsi) {
 
 void
 tty_client_remove(struct tty_client *client) {
-    pthread_mutex_lock(&server->mutex);
     struct tty_client *iterator;
     LIST_FOREACH(iterator, &server->clients, list) {
         if (iterator == client) {
@@ -120,7 +116,6 @@ tty_client_remove(struct tty_client *client) {
             break;
         }
     }
-    pthread_mutex_unlock(&server->mutex);
 }
 
 void
@@ -130,12 +125,6 @@ tty_client_destroy(struct tty_client *client) {
 
     client->running = false;
 
-    if (pthread_mutex_trylock(&client->mutex) == 0) {
-        client->state = STATE_DONE;
-        pthread_cond_signal(&client->cond);
-        pthread_mutex_unlock(&client->mutex);
-    }
-
     // kill process (group) and free resource
     int pgid = getpgid(client->pid);
     int pid = pgid > 0 ? -pgid : client->pid;
@@ -159,8 +148,6 @@ cleanup:
         free(client->args[i]);
     }
 
-    pthread_mutex_destroy(&client->mutex);
-
 #if LWS_LIBRARY_VERSION_NUMBER >= 3002000
     lws_sul_schedule(context, 0, &client->sul_stagger, NULL, LWS_SET_TIMER_USEC_CANCEL);
 #endif
@@ -169,20 +156,8 @@ cleanup:
     tty_client_remove(client);
 }
 
-#if LWS_LIBRARY_VERSION_NUMBER >= 3002000
-void
-stagger_callback(lws_sorted_usec_list_t *sul) {
-    struct tty_client *client = lws_container_of(sul, struct tty_client, sul_stagger);
-
-    lws_callback_on_writable(client->wsi);
-    lws_sul_schedule(context, 0, sul, stagger_callback, 10 * LWS_US_PER_MS);
-}
-#endif
-
-void *
-thread_run_command(void *args) {
-    struct tty_client *client = (struct tty_client *) args;
-
+int
+spawn_process(struct tty_client *client) {
     // append url args to arguments
     char *argv[server->argc + client->argc + 1];
     int i, n = 0;
@@ -195,11 +170,10 @@ thread_run_command(void *args) {
     argv[n] = NULL;
 
     int pty;
-    fd_set des_set;
     pid_t pid = forkpty(&pty, NULL, NULL, NULL);
     if (pid < 0) { /* error */
         lwsl_err("forkpty failed: %d (%s)\n", errno, strerror(errno));
-        pthread_exit((void *) 1);
+        return 1;
     } else if (pid == 0) { /* child */
         setenv("TERM", server->terminal_type, true);
         // Don't pass the web socket onto child processes
@@ -217,32 +191,24 @@ thread_run_command(void *args) {
     if (client->size.ws_row > 0 && client->size.ws_col > 0)
         ioctl(client->pty, TIOCSWINSZ, &client->size);
 
-    while (client->running) {
-        FD_ZERO (&des_set);
-        FD_SET (pty, &des_set);
-        struct timeval tv = { 1, 0 };
-        int ret = select(pty + 1, &des_set, NULL, NULL, &tv);
-        if (ret == 0) continue;
-        if (ret < 0) break;
-
-        if (FD_ISSET (pty, &des_set)) {
-            while (client->running) {
-                pthread_mutex_lock(&client->mutex);
-                while (client->state == STATE_READY) {
-                    pthread_cond_wait(&client->cond, &client->mutex);
-                }
-                memset(client->pty_buffer, 0, sizeof(client->pty_buffer));
-                client->pty_len = read(pty, client->pty_buffer + LWS_PRE + 1, BUF_SIZE);
-                client->state = STATE_READY;
-                pthread_mutex_unlock(&client->mutex);
-                break;
-            }
-        }
+    return 0;
+}
 
-        if (client->pty_len <= 0) break;
-    }
+void
+tty_client_poll(struct tty_client *client) {
+    if (!client->running || client->state == STATE_READY) return;
 
-    pthread_exit((void *) 0);
+    fd_set des_set;
+    FD_ZERO (&des_set);
+    FD_SET (client->pty, &des_set);
+    struct timeval tv = { 0, 0 };
+    if (select(client->pty + 1, &des_set, NULL, NULL, &tv) <= 0) return;
+
+    if (FD_ISSET (client->pty, &des_set)) {
+        memset(client->pty_buffer, 0, sizeof(client->pty_buffer));
+        client->pty_len = read(client->pty, client->pty_buffer + LWS_PRE + 1, BUF_SIZE);
+        client->state = STATE_READY;
+    }
 }
 
 int
@@ -294,17 +260,12 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
                 }
             }
 
-            pthread_mutex_init(&client->mutex, NULL);
-            pthread_cond_init(&client->cond, NULL);
-
-            pthread_mutex_lock(&server->mutex);
             LIST_INSERT_HEAD(&server->clients, client, list);
             server->client_count++;
-            pthread_mutex_unlock(&server->mutex);
 
             lws_hdr_copy(wsi, buf, sizeof(buf), WSI_TOKEN_GET_URI);
 
-#if LWS_LIBRARY_VERSION_MAJOR > 2 || (LWS_LIBRARY_VERSION_MAJOR ==2 && LWS_LIBRARY_VERSION_MINOR >=4)
+#if LWS_LIBRARY_VERSION_NUMBER >= 2004000
             lws_get_peer_simple(lws_get_network_wsi(wsi), client->address, sizeof(client->address));
 #else
             char name[100];
@@ -328,8 +289,9 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
                 lws_callback_on_writable(wsi);
                 break;
             }
-            if (client->state != STATE_READY)
+            if (client->state != STATE_READY) {
                 break;
+            }
 
             // read error or client exited, close connection
             if (client->pty_len == 0) {
@@ -371,10 +333,6 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
             // check if there are more fragmented messages
             if (lws_remaining_packet_payload(wsi) > 0 || !lws_is_final_fragment(wsi)) {
                 return 0;
-            } else {
-                #if LWS_LIBRARY_VERSION_NUMBER >= 3002000
-                lws_sul_schedule(context, 0, &client->sul_stagger, stagger_callback, 10);
-                #endif
             }
 
             switch (command) {
@@ -414,9 +372,7 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
                             return -1;
                         }
                     }
-                    int err = pthread_create(&client->thread, NULL, thread_run_command, client);
-                    if (err != 0) {
-                        lwsl_err("pthread_create return: %d\n", err);
+                    if (spawn_process(client) != 0) {
                         return 1;
                     }
                     break;
index 8e1855b89e82b859cfc29fddf8a3e813a9e6e38a..4e903749e00367f00e9603ea10a64a2ea3168455 100644 (file)
@@ -4,7 +4,6 @@
 #include <string.h>
 #include <errno.h>
 #include <getopt.h>
-#include <pthread.h>
 #include <signal.h>
 #include <sys/stat.h>
 
@@ -165,7 +164,6 @@ tty_server_free(struct tty_server *ts) {
             unlink(ts->socket_path);
         }
     }
-    pthread_mutex_destroy(&ts->mutex);
     free(ts);
 }
 
@@ -229,6 +227,15 @@ calc_command_start(int argc, char **argv) {
     return start;
 }
 
+#if LWS_LIBRARY_VERSION_NUMBER >= 3002000
+void
+stagger_callback(lws_sorted_usec_list_t *sul) {
+    struct tty_client *client = lws_container_of(sul, struct tty_client, sul_stagger);
+
+    lws_callback_on_writable(client->wsi);
+}
+#endif
+
 int
 main(int argc, char **argv) {
     if (argc == 1) {
@@ -238,7 +245,6 @@ main(int argc, char **argv) {
 
     int start = calc_command_start(argc, argv);
     server = tty_server_new(argc, argv, start);
-    pthread_mutex_init(&server->mutex, NULL);
 
     struct lws_context_creation_info info;
     memset(&info, 0, sizeof(info));
@@ -476,26 +482,20 @@ main(int argc, char **argv) {
         open_uri(url);
     }
 
-    // libwebsockets main loop
     while (!force_exit) {
-        pthread_mutex_lock(&server->mutex);
         if (!LIST_EMPTY(&server->clients)) {
             struct tty_client *client;
             LIST_FOREACH(client, &server->clients, list) {
-                if (client->running && pthread_mutex_trylock(&client->mutex) == 0) {
-                    if (client->state != STATE_DONE)
-                        lws_callback_on_writable(client->wsi);
-                    else
-                        pthread_cond_signal(&client->cond);
-                    pthread_mutex_unlock(&client->mutex);
-                }
-            }
-        }
-        pthread_mutex_unlock(&server->mutex);
-        lws_service(context, 10);
+                tty_client_poll(client);
 #if LWS_LIBRARY_VERSION_NUMBER >= 3002000
-        usleep(10 * LWS_US_PER_MS);
+                lws_sul_schedule(context, 0, &client->sul_stagger, stagger_callback, 0);
+#else
+                lws_callback_on_writable(client->wsi);
 #endif
+            }
+        }
+        lws_service(context, 0);
+        usleep(10 * 1000); // 10ms
     }
 
     lws_context_destroy(context);
index 43a2327e59e95b92766a9892a73c59cfd64fd02f..1539435216d05f606da1ff17639d329243ec7f76 100644 (file)
@@ -1,4 +1,3 @@
-#include <pthread.h>
 #include <stdbool.h>
 #include <sys/ioctl.h>
 #include <sys/queue.h>
@@ -48,9 +47,6 @@ struct tty_client {
     enum pty_state state;
     char pty_buffer[LWS_PRE + 1 + BUF_SIZE];
     ssize_t pty_len;
-    pthread_t thread;
-    pthread_mutex_t mutex;
-    pthread_cond_t cond;
 
     LIST_ENTRY(tty_client) list;
 };
@@ -80,7 +76,6 @@ struct tty_server {
     bool once;                                // whether accept only one client and exit on disconnection
     char socket_path[255];                    // UNIX domain socket path
     char terminal_type[30];                   // terminal type to report
-    pthread_mutex_t mutex;
 };
 
 extern int
@@ -89,3 +84,5 @@ callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, voi
 extern int
 callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
 
+extern void
+tty_client_poll(struct tty_client *client);