Skip to content
Snippets Groups Projects
Commit e28ab10b authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Tie all the input and output threads together with an atomic_bool

Since we're using it in one place, use it everywhere.  While we're
here, read()/recv() of 0 after select indicates a closed connection
as well, an ensure we check terminate flags in inner loops.

This should help with SyncTERM issues where it appears to be
connected until you press a key, or it "hangs" and you have to
manually disconnect due to the connection actually having been
torn down at one end or the other.
parent 82efb641
No related branches found
No related tags found
No related merge requests found
Pipeline #7634 passed
......@@ -5,6 +5,7 @@
#ifdef __unix__
#include <signal.h> // kill()
#include <stdatomic.h>
#include <sys/wait.h> // WEXITSTATUS
#include <unistd.h> /* _POSIX_VDISABLE - needed when termios.h is broken */
......@@ -146,6 +147,7 @@
#include "uifcinit.h"
#include "window.h"
extern int default_font;
static atomic_bool terminated;
#ifdef NEEDS_CFMAKERAW
......@@ -315,7 +317,7 @@ pty_input_thread(void *args)
SetThreadName("PTY Input");
conn_api.input_thread_running = 1;
while (master != -1 && !conn_api.terminate) {
while (master != -1 && !conn_api.terminate && !terminated) {
if ((i = waitpid(child_pid, &status, WNOHANG)))
break;
FD_ZERO(&rds);
......@@ -330,17 +332,18 @@ pty_input_thread(void *args)
}
if (rd == 1) {
rd = read(master, conn_api.rd_buf, conn_api.rd_buf_size);
if (rd < 0)
continue;
if (rd <= 0)
break;
}
buffered = 0;
while (buffered < rd) {
while (buffered < rd && !conn_api.terminate && !terminated) {
pthread_mutex_lock(&(conn_inbuf.mutex));
buffer = conn_buf_wait_free(&conn_inbuf, rd - buffered, 100);
buffered += conn_buf_put(&conn_inbuf, conn_api.rd_buf + buffered, buffer);
pthread_mutex_unlock(&(conn_inbuf.mutex));
}
}
terminated = true;
conn_api.input_thread_running = 2;
}
......@@ -359,7 +362,7 @@ pty_output_thread(void *args)
SetThreadName("PTY Output");
conn_api.output_thread_running = 1;
while (master != -1 && !conn_api.terminate) {
while (master != -1 && !conn_api.terminate && !terminated) {
if (waitpid(child_pid, &status, WNOHANG))
break;
pthread_mutex_lock(&(conn_outbuf.mutex));
......@@ -369,7 +372,7 @@ pty_output_thread(void *args)
wr = conn_buf_get(&conn_outbuf, conn_api.wr_buf, conn_api.wr_buf_size);
pthread_mutex_unlock(&(conn_outbuf.mutex));
sent = 0;
while (master != -1 && sent < wr) {
while (master != -1 && sent < wr && !conn_api.terminate && !terminated) {
FD_ZERO(&wds);
FD_SET(master, &wds);
tv.tv_sec = 0;
......@@ -382,8 +385,10 @@ pty_output_thread(void *args)
}
if (ret == 1) {
ret = write(master, conn_api.wr_buf + sent, wr - sent);
if (ret == -1)
continue;
if (ret <= 0) {
ret = -1;
break;
}
sent += ret;
}
}
......@@ -394,6 +399,7 @@ pty_output_thread(void *args)
if (ret == -1)
break;
}
terminated = true;
conn_api.output_thread_running = 2;
}
......@@ -558,6 +564,7 @@ pty_connect(struct bbslist *bbs)
}
conn_api.wr_buf_size = BUFFER_SIZE;
terminated = false;
_beginthread(pty_output_thread, 0, NULL);
_beginthread(pty_input_thread, 0, NULL);
......@@ -571,6 +578,7 @@ pty_close(void)
char garbage[1024];
int oldmaster;
terminated = true;
conn_api.terminate = 1;
start = time(NULL);
kill(child_pid, SIGHUP);
......
......@@ -149,6 +149,7 @@ telnet_connect(struct bbslist *bbs)
conn_api.rx_parse_cb = telnet_rx_parse_cb;
conn_api.tx_parse_cb = telnet_tx_parse_cb;
rlogin_clear_terminated();
_beginthread(rlogin_output_thread, 0, NULL);
_beginthread(rlogin_input_thread, 0, bbs);
// Suppress Go Aheads (both directions)
......
......@@ -2,6 +2,7 @@
/* $Id: modem.c,v 1.32 2020/06/27 08:27:39 deuce Exp $ */
#include <stdatomic.h>
#include <stdbool.h>
#include <stdlib.h>
......@@ -16,6 +17,7 @@
static COM_HANDLE com = COM_HANDLE_INVALID;
static bool seven_bits = false;
static atomic_bool terminated;
void
modem_input_thread(void *args)
......@@ -31,7 +33,7 @@ modem_input_thread(void *args)
if ((comGetModemStatus(com) & COM_DSR) == 0)
monitor_dsr = false;
}
while (com != COM_HANDLE_INVALID && !conn_api.terminate) {
while (com != COM_HANDLE_INVALID && !conn_api.terminate && !terminated) {
rd = comReadBuf(com, (char *)conn_api.rd_buf, conn_api.rd_buf_size, NULL, 100);
// Strip high bits... we *should* check the parity
if (seven_bits) {
......@@ -39,7 +41,7 @@ modem_input_thread(void *args)
conn_api.rd_buf[i] &= 0x7f;
}
buffered = 0;
while (com != COM_HANDLE_INVALID && buffered < rd) {
while (com != COM_HANDLE_INVALID && buffered < rd && !conn_api.terminate && !terminated) {
pthread_mutex_lock(&(conn_inbuf.mutex));
buffer = conn_buf_wait_free(&conn_inbuf, rd - buffered, 100);
buffered += conn_buf_put(&conn_inbuf, conn_api.rd_buf + buffered, buffer);
......@@ -54,6 +56,7 @@ modem_input_thread(void *args)
break;
}
}
terminated = true;
if (args != NULL)
comLowerDTR(com);
conn_api.input_thread_running = 2;
......@@ -74,7 +77,7 @@ modem_output_thread(void *args)
if ((comGetModemStatus(com) & COM_DSR) == 0)
monitor_dsr = false;
}
while (com != COM_HANDLE_INVALID && !conn_api.terminate) {
while (com != COM_HANDLE_INVALID && !conn_api.terminate && !terminated) {
pthread_mutex_lock(&(conn_outbuf.mutex));
wr = conn_buf_wait_bytes(&conn_outbuf, 1, 100);
if (wr) {
......@@ -85,7 +88,7 @@ modem_output_thread(void *args)
conn_api.wr_buf[i] &= 0x7f;
}
sent = 0;
while (com != COM_HANDLE_INVALID && sent < wr && !conn_api.terminate) {
while (com != COM_HANDLE_INVALID && sent < wr && !conn_api.terminate && !terminated) {
// coverity[overflow:SUPPRESS]
ret = comWriteBuf(com, conn_api.wr_buf + sent, wr - sent);
if (ret > 0)
......@@ -106,6 +109,7 @@ modem_output_thread(void *args)
break;
}
}
terminated = true;
conn_api.output_thread_running = 2;
}
......@@ -382,6 +386,7 @@ modem_connect(struct bbslist *bbs)
}
conn_api.wr_buf_size = BUFFER_SIZE;
terminated = false;
if ((bbs->conn_type == CONN_TYPE_SERIAL) || (bbs->conn_type == CONN_TYPE_SERIAL_NORTS)) {
_beginthread(modem_output_thread, 0, (void *)-1);
_beginthread(modem_input_thread, 0, (void *)-1);
......@@ -419,6 +424,7 @@ modem_close(void)
char garbage[1024];
COM_HANDLE oldcom;
terminated = true;
conn_api.terminate = 1;
if ((comGetModemStatus(com) & COM_DCD) == 0) /* DCD already low */
......
......@@ -2,6 +2,7 @@
/* $Id: rlogin.c,v 1.38 2020/06/27 00:04:50 deuce Exp $ */
#include <stdatomic.h>
#include <stdlib.h>
#include "bbslist.h"
......@@ -10,6 +11,12 @@
#include "uifcinit.h"
SOCKET rlogin_sock = INVALID_SOCKET;
static bool terminated;
void rlogin_clear_terminated(void)
{
terminated = false;
}
#ifdef __BORLANDC__
#pragma argsused
......@@ -24,13 +31,13 @@ rlogin_input_thread(void *args)
SetThreadName("RLogin Input");
conn_api.input_thread_running = 1;
while (rlogin_sock != INVALID_SOCKET && !conn_api.terminate) {
while (rlogin_sock != INVALID_SOCKET && !conn_api.terminate && !terminated) {
if (socket_readable(rlogin_sock, 100)) {
rd = recv(rlogin_sock, conn_api.rd_buf, conn_api.rd_buf_size, 0);
if (rd <= 0)
break;
buffered = 0;
while (rlogin_sock != INVALID_SOCKET && buffered < rd) {
while (rlogin_sock != INVALID_SOCKET && buffered < rd && !conn_api.terminate && !terminated) {
pthread_mutex_lock(&(conn_inbuf.mutex));
buffer = conn_buf_wait_free(&conn_inbuf, rd - buffered, 1000);
buffered += conn_buf_put(&conn_inbuf, conn_api.rd_buf + buffered, buffer);
......@@ -38,6 +45,7 @@ rlogin_input_thread(void *args)
}
}
}
terminated = true;
conn_api.input_thread_running = 2;
}
......@@ -54,7 +62,7 @@ rlogin_output_thread(void *args)
SetThreadName("RLogin Output");
conn_api.output_thread_running = 1;
while (rlogin_sock != INVALID_SOCKET && !conn_api.terminate) {
while (rlogin_sock != INVALID_SOCKET && !conn_api.terminate && !terminated) {
pthread_mutex_lock(&(conn_outbuf.mutex));
ret = 0;
wr = conn_buf_wait_bytes(&conn_outbuf, 1, 100);
......@@ -62,13 +70,13 @@ rlogin_output_thread(void *args)
wr = conn_buf_get(&conn_outbuf, conn_api.wr_buf, conn_api.wr_buf_size);
pthread_mutex_unlock(&(conn_outbuf.mutex));
sent = 0;
while (rlogin_sock != INVALID_SOCKET && sent < wr && !conn_api.terminate) {
while (rlogin_sock != INVALID_SOCKET && sent < wr && !conn_api.terminate && !terminated) {
if (socket_writable(rlogin_sock, 100)) {
// coverity[overflow:SUPPRESS]
ret = sendsocket(rlogin_sock, conn_api.wr_buf + sent, wr - sent);
if (ret > 0)
sent += ret;
if (ret < 0)
else
break;
}
}
......@@ -79,6 +87,7 @@ rlogin_output_thread(void *args)
if (ret < 0)
break;
}
terminated = true;
conn_api.output_thread_running = 2;
}
......@@ -199,6 +208,7 @@ rlogin_connect(struct bbslist *bbs)
return -1;
}
terminated = false;
_beginthread(rlogin_output_thread, 0, NULL);
_beginthread(rlogin_input_thread, 0, NULL);
......@@ -214,6 +224,7 @@ rlogin_close(void)
char garbage[1024];
SOCKET oldsock;
terminated = true;
conn_api.terminate = 1;
oldsock = rlogin_sock;
rlogin_sock = INVALID_SOCKET;
......
......@@ -2,6 +2,7 @@
#ifndef _RLOGIN_H_
#define _RLOGIN_H_
void rlogin_clear_terminated(void);
int rlogin_connect(struct bbslist *bbs);
int rlogin_close(void);
void rlogin_input_thread(void *args);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment