mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-26 13:53:26 +01:00
use pthread for mplex detach polling for better portability
This commit is contained in:
parent
0c39e7b158
commit
442d9e22b4
@ -34,6 +34,7 @@
|
|||||||
#include "groupchat.h"
|
#include "groupchat.h"
|
||||||
#include "prompt.h"
|
#include "prompt.h"
|
||||||
#include "help.h"
|
#include "help.h"
|
||||||
|
#include "term_mplex.h"
|
||||||
|
|
||||||
extern char *DATA_FILE;
|
extern char *DATA_FILE;
|
||||||
extern ToxWindow *prompt;
|
extern ToxWindow *prompt;
|
||||||
@ -524,7 +525,7 @@ void cmd_requests(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
{
|
{
|
||||||
bool have_note = false;
|
bool have_note = false;
|
||||||
const char *errmsg;
|
const char *errmsg;
|
||||||
|
|
||||||
|
@ -23,11 +23,9 @@
|
|||||||
#include <limits.h> /* PATH_MAX */
|
#include <limits.h> /* PATH_MAX */
|
||||||
#include <stdio.h> /* fgets, popen, pclose */
|
#include <stdio.h> /* fgets, popen, pclose */
|
||||||
#include <stdlib.h> /* malloc, realloc, free, getenv */
|
#include <stdlib.h> /* malloc, realloc, free, getenv */
|
||||||
#include <string.h> /* strlen, strcpy, strstr, strchr, strrchr, strcat, strncmp
|
#include <string.h> /* strlen, strcpy, strstr, strchr, strrchr, strcat, strncmp */
|
||||||
*/
|
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -71,7 +69,24 @@ static char buffer [BUFFER_SIZE];
|
|||||||
static mplex_status mplex = MPLEX_NONE;
|
static mplex_status mplex = MPLEX_NONE;
|
||||||
static TOX_USERSTATUS prev_status = TOX_USERSTATUS_NONE;
|
static TOX_USERSTATUS prev_status = TOX_USERSTATUS_NONE;
|
||||||
static char prev_note [TOX_MAX_STATUSMESSAGE_LENGTH] = "";
|
static char prev_note [TOX_MAX_STATUSMESSAGE_LENGTH] = "";
|
||||||
static Tox *tox = NULL;
|
|
||||||
|
/* mutex for access to status data, for sync between:
|
||||||
|
- user command /status from ncurses thread
|
||||||
|
- auto-away POSIX timer, which runs from a separate thread
|
||||||
|
after init, should be accessed only by cmd_status()
|
||||||
|
*/
|
||||||
|
pthread_mutex_t status_lock;
|
||||||
|
pthread_t mplex_tid;
|
||||||
|
|
||||||
|
void lock_status ()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock (&status_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock_status ()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock (&status_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static char *read_into_dyn_buffer (FILE *stream)
|
static char *read_into_dyn_buffer (FILE *stream)
|
||||||
{
|
{
|
||||||
@ -294,7 +309,7 @@ static int mplex_is_detached ()
|
|||||||
return gnu_screen_is_detached () || tmux_is_detached ();
|
return gnu_screen_is_detached () || tmux_is_detached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mplex_timer_handler (union sigval param)
|
static void mplex_timer_handler (Tox *m)
|
||||||
{
|
{
|
||||||
int detached;
|
int detached;
|
||||||
TOX_USERSTATUS current_status, new_status;
|
TOX_USERSTATUS current_status, new_status;
|
||||||
@ -304,7 +319,10 @@ static void mplex_timer_handler (union sigval param)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
detached = mplex_is_detached ();
|
detached = mplex_is_detached ();
|
||||||
current_status = tox_get_self_user_status (tox);
|
|
||||||
|
pthread_mutex_lock (&Winthread.lock);
|
||||||
|
current_status = tox_get_self_user_status (m);
|
||||||
|
pthread_mutex_unlock (&Winthread.lock);
|
||||||
|
|
||||||
if (current_status == TOX_USERSTATUS_AWAY && !detached)
|
if (current_status == TOX_USERSTATUS_AWAY && !detached)
|
||||||
{
|
{
|
||||||
@ -316,9 +334,9 @@ static void mplex_timer_handler (union sigval param)
|
|||||||
{
|
{
|
||||||
prev_status = current_status;
|
prev_status = current_status;
|
||||||
new_status = TOX_USERSTATUS_AWAY;
|
new_status = TOX_USERSTATUS_AWAY;
|
||||||
tox_get_self_status_message (tox,
|
pthread_mutex_lock (&Winthread.lock);
|
||||||
(uint8_t*) prev_note,
|
tox_get_self_status_message (m, (uint8_t*) prev_note, sizeof (prev_note));
|
||||||
sizeof (prev_note));
|
pthread_mutex_unlock (&Winthread.lock);
|
||||||
new_note = user_settings->mplex_away_note;
|
new_note = user_settings->mplex_away_note;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -332,33 +350,38 @@ static void mplex_timer_handler (union sigval param)
|
|||||||
strcpy (argv[2] + 1, new_note);
|
strcpy (argv[2] + 1, new_note);
|
||||||
strcat (argv[2], "\"");
|
strcat (argv[2], "\"");
|
||||||
pthread_mutex_lock (&Winthread.lock);
|
pthread_mutex_lock (&Winthread.lock);
|
||||||
cmd_status (prompt->chatwin->history, prompt, tox, 2, argv);
|
cmd_status (prompt->chatwin->history, prompt, m, 2, argv);
|
||||||
pthread_mutex_unlock (&Winthread.lock);
|
pthread_mutex_unlock (&Winthread.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_mplex_away_timer (Tox *m)
|
/* Time in seconds between calls to mplex_timer_handler */
|
||||||
{
|
#define MPLEX_TIMER_INTERVAL 5
|
||||||
struct sigevent sev;
|
|
||||||
timer_t timer_id;
|
|
||||||
struct itimerspec its;
|
|
||||||
|
|
||||||
|
void *mplex_timer_thread(void *data)
|
||||||
|
{
|
||||||
|
Tox *m = (Tox *) data;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
sleep(MPLEX_TIMER_INTERVAL);
|
||||||
|
mplex_timer_handler(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int init_mplex_away_timer (Tox *m)
|
||||||
|
{
|
||||||
if (! detect_mplex ())
|
if (! detect_mplex ())
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if (! user_settings->mplex_away)
|
if (! user_settings->mplex_away)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
sev.sigev_notify = SIGEV_THREAD;
|
/* status access mutex */
|
||||||
sev.sigev_notify_function = mplex_timer_handler;
|
if (pthread_mutex_init (&status_lock, NULL) != 0)
|
||||||
sev.sigev_notify_attributes = NULL;
|
return -1;
|
||||||
|
|
||||||
if (timer_create (CLOCK_REALTIME, &sev, &timer_id) == -1)
|
if (pthread_create(&mplex_tid, NULL, mplex_timer_thread, (void *) m) != 0)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
its.it_interval.tv_sec = 5;
|
return 0;
|
||||||
its.it_interval.tv_nsec = 0;
|
|
||||||
its.it_value = its.it_interval;
|
|
||||||
|
|
||||||
timer_settime (timer_id, 0, &its, NULL);
|
|
||||||
tox = m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
yes, it initializes a timer which periodically checks the attached/detached
|
yes, it initializes a timer which periodically checks the attached/detached
|
||||||
state of the terminal and updates away status accordingly.
|
state of the terminal and updates away status accordingly.
|
||||||
*/
|
*/
|
||||||
void init_mplex_away_timer (Tox *m);
|
int init_mplex_away_timer (Tox *m);
|
||||||
|
|
||||||
|
void lock_status ();
|
||||||
|
void unlock_status ();
|
||||||
|
|
||||||
#endif /* #define TERM_MPLEX_H */
|
#endif /* #define TERM_MPLEX_H */
|
||||||
|
60
src/toxic.c
60
src/toxic.c
@ -85,23 +85,6 @@ struct audio_thread audio_thread;
|
|||||||
struct arg_opts arg_opts;
|
struct arg_opts arg_opts;
|
||||||
struct user_settings *user_settings = NULL;
|
struct user_settings *user_settings = NULL;
|
||||||
|
|
||||||
/* mutex for access to status data, for sync between:
|
|
||||||
- user command /status from ncurses thread
|
|
||||||
- auto-away POSIX timer, which runs from a separate thread
|
|
||||||
after init, should be accessed only by cmd_status()
|
|
||||||
*/
|
|
||||||
static pthread_mutex_t status_lock;
|
|
||||||
|
|
||||||
void lock_status ()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock (&status_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlock_status ()
|
|
||||||
{
|
|
||||||
pthread_mutex_unlock (&status_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MIN_PASSWORD_LEN 6
|
#define MIN_PASSWORD_LEN 6
|
||||||
#define MAX_PASSWORD_LEN 64
|
#define MAX_PASSWORD_LEN 64
|
||||||
|
|
||||||
@ -154,14 +137,14 @@ void exit_toxic_success(Tox *m)
|
|||||||
|
|
||||||
tox_kill(m);
|
tox_kill(m);
|
||||||
endwin();
|
endwin();
|
||||||
|
|
||||||
#ifdef X11
|
#ifdef X11
|
||||||
/* We have to terminate xtra last coz reasons
|
/* We have to terminate xtra last coz reasons
|
||||||
* Please don't call this anywhere else coz trust me
|
* Please don't call this anywhere else coz trust me
|
||||||
*/
|
*/
|
||||||
terminate_xtra();
|
terminate_xtra();
|
||||||
#endif /* X11 */
|
#endif /* X11 */
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,7 +519,7 @@ static void first_time_encrypt(const char *msg)
|
|||||||
system("clear");
|
system("clear");
|
||||||
printf("%s ", msg);
|
printf("%s ", msg);
|
||||||
|
|
||||||
if (!strcasecmp(ch, "y\n") || !strcasecmp(ch, "n\n") || !strcasecmp(ch, "yes\n")
|
if (!strcasecmp(ch, "y\n") || !strcasecmp(ch, "n\n") || !strcasecmp(ch, "yes\n")
|
||||||
|| !strcasecmp(ch, "no\n") || !strcasecmp(ch, "q\n"))
|
|| !strcasecmp(ch, "no\n") || !strcasecmp(ch, "q\n"))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1061,41 +1044,37 @@ int main(int argc, char *argv[])
|
|||||||
if (init_xtra(DnD_callback) == -1)
|
if (init_xtra(DnD_callback) == -1)
|
||||||
queue_init_message("X failed to initialize");
|
queue_init_message("X failed to initialize");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Tox *m = init_tox();
|
Tox *m = init_tox();
|
||||||
|
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
exit_toxic_err("failed in main", FATALERR_NETWORKINIT);
|
exit_toxic_err("failed in main", FATALERR_NETWORKINIT);
|
||||||
|
|
||||||
if (!arg_opts.ignore_data_file) {
|
if (!arg_opts.ignore_data_file) {
|
||||||
if (arg_opts.encrypt_data && !datafile_exists)
|
if (arg_opts.encrypt_data && !datafile_exists)
|
||||||
arg_opts.encrypt_data = 0;
|
arg_opts.encrypt_data = 0;
|
||||||
|
|
||||||
load_data(m, DATA_FILE);
|
load_data(m, DATA_FILE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init_term();
|
init_term();
|
||||||
prompt = init_windows(m);
|
prompt = init_windows(m);
|
||||||
prompt_init_statusbar(prompt, m);
|
prompt_init_statusbar(prompt, m);
|
||||||
|
|
||||||
/* thread for ncurses stuff */
|
/* thread for ncurses stuff */
|
||||||
if (pthread_mutex_init(&Winthread.lock, NULL) != 0)
|
if (pthread_mutex_init(&Winthread.lock, NULL) != 0)
|
||||||
exit_toxic_err("failed in main", FATALERR_MUTEX_INIT);
|
exit_toxic_err("failed in main", FATALERR_MUTEX_INIT);
|
||||||
|
|
||||||
if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0)
|
if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0)
|
||||||
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);
|
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);
|
||||||
|
|
||||||
/* thread for message queue */
|
/* thread for message queue */
|
||||||
if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0)
|
if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0)
|
||||||
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);
|
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);
|
||||||
|
|
||||||
/* status access mutex */
|
|
||||||
if (pthread_mutex_init (&status_lock, NULL) != 0)
|
|
||||||
exit_toxic_err("failed in main", FATALERR_MUTEX_INIT);
|
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
|
|
||||||
av = init_audio(prompt, m);
|
av = init_audio(prompt, m);
|
||||||
|
|
||||||
/* audio thread */
|
/* audio thread */
|
||||||
@ -1110,11 +1089,11 @@ int main(int argc, char *argv[])
|
|||||||
queue_init_message("Failed to init audio devices");
|
queue_init_message("Failed to init audio devices");
|
||||||
|
|
||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
init_notify(60, 3000);
|
init_notify(60, 3000);
|
||||||
|
|
||||||
const char *msg;
|
const char *msg;
|
||||||
|
|
||||||
if (config_err) {
|
if (config_err) {
|
||||||
msg = "Unable to determine configuration directory. Defaulting to 'data' for data file...";
|
msg = "Unable to determine configuration directory. Defaulting to 'data' for data file...";
|
||||||
queue_init_message("%s", msg);
|
queue_init_message("%s", msg);
|
||||||
@ -1123,6 +1102,10 @@ int main(int argc, char *argv[])
|
|||||||
if (settings_err == -1)
|
if (settings_err == -1)
|
||||||
queue_init_message("Failed to load user settings");
|
queue_init_message("Failed to load user settings");
|
||||||
|
|
||||||
|
/* screen/tmux auto-away timer */
|
||||||
|
if (init_mplex_away_timer (m) == -1)
|
||||||
|
queue_init_message("Failed to init mplex auto-away.");
|
||||||
|
|
||||||
print_init_messages(prompt);
|
print_init_messages(prompt);
|
||||||
cleanup_init_messages();
|
cleanup_init_messages();
|
||||||
|
|
||||||
@ -1131,9 +1114,6 @@ int main(int argc, char *argv[])
|
|||||||
snprintf(avatarstr, sizeof(avatarstr), "/avatar \"%s\"", user_settings->avatar_path);
|
snprintf(avatarstr, sizeof(avatarstr), "/avatar \"%s\"", user_settings->avatar_path);
|
||||||
execute(prompt->chatwin->history, prompt, m, avatarstr, GLOBAL_COMMAND_MODE);
|
execute(prompt->chatwin->history, prompt, m, avatarstr, GLOBAL_COMMAND_MODE);
|
||||||
|
|
||||||
/* screen/tmux auto-away timer */
|
|
||||||
init_mplex_away_timer (m);
|
|
||||||
|
|
||||||
uint64_t last_save = (uint64_t) time(NULL);
|
uint64_t last_save = (uint64_t) time(NULL);
|
||||||
uint64_t looptimer = last_save;
|
uint64_t looptimer = last_save;
|
||||||
useconds_t msleepval = 40000;
|
useconds_t msleepval = 40000;
|
||||||
|
Loading…
Reference in New Issue
Block a user