1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-09-29 04:25:36 +02:00

use pthread for mplex detach polling for better portability

This commit is contained in:
Jfreegman 2015-03-11 18:38:07 -04:00
parent 0c39e7b158
commit 442d9e22b4
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
4 changed files with 77 additions and 70 deletions

View File

@ -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;

View File

@ -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;
} }

View File

@ -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 */

View File

@ -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;