From 5381d0f825108ff00d861cd712fb01f1c62c2dbb Mon Sep 17 00:00:00 2001 From: Shuanglei Tao Date: Sun, 15 Sep 2019 18:09:48 +0800 Subject: [PATCH] all: remove pthread --- CMakeLists.txt | 2 +- src/http.c | 5 +-- src/protocol.c | 90 +++++++++++++------------------------------------- src/server.c | 34 +++++++++---------- src/server.h | 7 ++-- 5 files changed, 46 insertions(+), 92 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4929624..132fa76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/src/http.c b/src/http.c index 747965e..195ede2 100644 --- a/src/http.c +++ b/src/http.c @@ -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]; diff --git a/src/protocol.c b/src/protocol.c index f837183..108284f 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -7,9 +7,6 @@ #include #include #include -#include -#include -#include #if defined(__OpenBSD__) || defined(__APPLE__) #include @@ -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; diff --git a/src/server.c b/src/server.c index 8e1855b..4e90374 100644 --- a/src/server.c +++ b/src/server.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -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); diff --git a/src/server.h b/src/server.h index 43a2327..1539435 100644 --- a/src/server.h +++ b/src/server.h @@ -1,4 +1,3 @@ -#include #include #include #include @@ -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); -- 2.43.4