1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-23 02:23:02 +01:00

Fix more threading issues

This commit is contained in:
Jfreegman 2015-08-27 21:29:34 -04:00
parent 28dd43608d
commit b4464eda4d
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
8 changed files with 187 additions and 104 deletions

View File

@ -140,7 +140,10 @@ DeviceError init_devices()
DeviceError terminate_devices() DeviceError terminate_devices()
{ {
/* Cleanup if needed */ /* Cleanup if needed */
lock;
thread_running = false; thread_running = false;
unlock;
usleep(20000); usleep(20000);
if (pthread_mutex_destroy(&mutex) != 0) if (pthread_mutex_destroy(&mutex) != 0)
@ -406,8 +409,15 @@ void* thread_poll (void* arg) // TODO: maybe use thread for every input source
int32_t sample = 0; int32_t sample = 0;
while (thread_running) while (true)
{ {
lock;
if (!thread_running) {
unlock;
break;
}
unlock;
if (thread_paused) usleep(10000); /* Wait for unpause. */ if (thread_paused) usleep(10000); /* Wait for unpause. */
else else
{ {

View File

@ -624,10 +624,12 @@ static void draw_del_popup(void)
wprintw(PendingDelete.popup, "Delete contact "); wprintw(PendingDelete.popup, "Delete contact ");
wattron(PendingDelete.popup, A_BOLD); wattron(PendingDelete.popup, A_BOLD);
pthread_mutex_lock(&Winthread.lock);
if (blocklist_view == 0) if (blocklist_view == 0)
wprintw(PendingDelete.popup, "%s", Friends.list[PendingDelete.num].name); wprintw(PendingDelete.popup, "%s", Friends.list[PendingDelete.num].name);
else else
wprintw(PendingDelete.popup, "%s", Blocked.list[PendingDelete.num].name); wprintw(PendingDelete.popup, "%s", Blocked.list[PendingDelete.num].name);
pthread_mutex_unlock(&Winthread.lock);
wattroff(PendingDelete.popup, A_BOLD); wattroff(PendingDelete.popup, A_BOLD);
wprintw(PendingDelete.popup, "? y/n"); wprintw(PendingDelete.popup, "? y/n");
@ -888,12 +890,13 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
return; return;
} }
uint64_t cur_time = get_unix_time(); uint64_t cur_time = time(NULL);
struct tm cur_loc_tm = *localtime((const time_t *) &cur_time); struct tm cur_loc_tm = *localtime((const time_t *) &cur_time);
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
wprintw(self->window, " Online: "); wprintw(self->window, " Online: ");
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
wprintw(self->window, "%d/%d \n\n", Friends.num_online, Friends.num_friends); wprintw(self->window, "%d/%d \n\n", Friends.num_online, Friends.num_friends);
if ((y2 - FLIST_OFST) <= 0) if ((y2 - FLIST_OFST) <= 0)
@ -902,18 +905,30 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
uint32_t selected_num = 0; uint32_t selected_num = 0;
/* Determine which portion of friendlist to draw based on current position */ /* Determine which portion of friendlist to draw based on current position */
pthread_mutex_lock(&Winthread.lock);
int page = Friends.num_selected / (y2 - FLIST_OFST); int page = Friends.num_selected / (y2 - FLIST_OFST);
pthread_mutex_unlock(&Winthread.lock);
int start = (y2 - FLIST_OFST) * page; int start = (y2 - FLIST_OFST) * page;
int end = y2 - FLIST_OFST + start; int end = y2 - FLIST_OFST + start;
pthread_mutex_lock(&Winthread.lock);
size_t num_friends = Friends.num_friends;
pthread_mutex_unlock(&Winthread.lock);
int i; int i;
for (i = start; i < Friends.num_friends && i < end; ++i) { for (i = start; i < num_friends && i < end; ++i) {
pthread_mutex_lock(&Winthread.lock);
uint32_t f = Friends.index[i]; uint32_t f = Friends.index[i];
bool is_active = Friends.list[f].active;
int num_selected = Friends.num_selected;
pthread_mutex_unlock(&Winthread.lock);
bool f_selected = false; bool f_selected = false;
if (Friends.list[f].active) { if (is_active) {
if (i == Friends.num_selected) { if (i == num_selected) {
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
wprintw(self->window, " > "); wprintw(self->window, " > ");
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
@ -923,8 +938,12 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
wprintw(self->window, " "); wprintw(self->window, " ");
} }
if (Friends.list[f].connection_status != TOX_CONNECTION_NONE) { pthread_mutex_lock(&Winthread.lock);
TOX_CONNECTION connection_status = Friends.list[f].connection_status;
TOX_USER_STATUS status = Friends.list[f].status; TOX_USER_STATUS status = Friends.list[f].status;
pthread_mutex_unlock(&Winthread.lock);
if (connection_status != TOX_CONNECTION_NONE) {
int colour = MAGENTA; int colour = MAGENTA;
switch (status) { switch (status) {
@ -947,7 +966,9 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
wattron(self->window, COLOR_PAIR(BLUE)); wattron(self->window, COLOR_PAIR(BLUE));
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
pthread_mutex_lock(&Winthread.lock);
wprintw(self->window, "%s", Friends.list[f].name); wprintw(self->window, "%s", Friends.list[f].name);
pthread_mutex_unlock(&Winthread.lock);
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
if (f_selected) if (f_selected)
@ -960,17 +981,23 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
tox_friend_get_status_message(m, Friends.list[f].num, (uint8_t *) statusmsg, NULL); tox_friend_get_status_message(m, Friends.list[f].num, (uint8_t *) statusmsg, NULL);
size_t s_len = tox_friend_get_status_message_size(m, Friends.list[f].num, NULL); size_t s_len = tox_friend_get_status_message_size(m, Friends.list[f].num, NULL);
statusmsg[s_len] = '\0';
pthread_mutex_unlock(&Winthread.lock); pthread_mutex_unlock(&Winthread.lock);
statusmsg[s_len] = '\0';
filter_str(statusmsg, s_len); filter_str(statusmsg, s_len);
pthread_mutex_lock(&Winthread.lock);
snprintf(Friends.list[f].statusmsg, sizeof(Friends.list[f].statusmsg), "%s", statusmsg); snprintf(Friends.list[f].statusmsg, sizeof(Friends.list[f].statusmsg), "%s", statusmsg);
Friends.list[f].statusmsg_len = strlen(Friends.list[f].statusmsg); Friends.list[f].statusmsg_len = strlen(Friends.list[f].statusmsg);
pthread_mutex_unlock(&Winthread.lock);
} }
/* Truncate note if it doesn't fit on one line */ /* Truncate note if it doesn't fit on one line */
size_t maxlen = x2 - getcurx(self->window) - 2; size_t maxlen = x2 - getcurx(self->window) - 2;
pthread_mutex_lock(&Winthread.lock);
if (Friends.list[f].statusmsg_len > maxlen) { if (Friends.list[f].statusmsg_len > maxlen) {
Friends.list[f].statusmsg[maxlen - 3] = '\0'; Friends.list[f].statusmsg[maxlen - 3] = '\0';
strcat(Friends.list[f].statusmsg, "..."); strcat(Friends.list[f].statusmsg, "...");
@ -981,6 +1008,8 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
if (Friends.list[f].statusmsg_len > 0) if (Friends.list[f].statusmsg_len > 0)
wprintw(self->window, " %s", Friends.list[f].statusmsg); wprintw(self->window, " %s", Friends.list[f].statusmsg);
pthread_mutex_unlock(&Winthread.lock);
wprintw(self->window, "\n"); wprintw(self->window, "\n");
} else { } else {
wprintw(self->window, "%s ", OFFLINE_CHAR); wprintw(self->window, "%s ", OFFLINE_CHAR);
@ -989,21 +1018,29 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
wattron(self->window, COLOR_PAIR(BLUE)); wattron(self->window, COLOR_PAIR(BLUE));
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
pthread_mutex_lock(&Winthread.lock);
wprintw(self->window, "%s", Friends.list[f].name); wprintw(self->window, "%s", Friends.list[f].name);
pthread_mutex_unlock(&Winthread.lock);
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
if (f_selected) if (f_selected)
wattroff(self->window, COLOR_PAIR(BLUE)); wattroff(self->window, COLOR_PAIR(BLUE));
pthread_mutex_lock(&Winthread.lock);
uint64_t last_seen = Friends.list[f].last_online.last_on; uint64_t last_seen = Friends.list[f].last_online.last_on;
pthread_mutex_unlock(&Winthread.lock);
if (last_seen != 0) { if (last_seen != 0) {
pthread_mutex_lock(&Winthread.lock);
int day_dist = ( int day_dist = (
cur_loc_tm.tm_yday - Friends.list[f].last_online.tm.tm_yday cur_loc_tm.tm_yday - Friends.list[f].last_online.tm.tm_yday
+ ((cur_loc_tm.tm_year - Friends.list[f].last_online.tm.tm_year) * 365) + ((cur_loc_tm.tm_year - Friends.list[f].last_online.tm.tm_year) * 365)
); );
const char *hourmin = Friends.list[f].last_online.hour_min_str; const char *hourmin = Friends.list[f].last_online.hour_min_str;
pthread_mutex_unlock(&Winthread.lock);
switch (day_dist) { switch (day_dist) {
case 0: case 0:
wprintw(self->window, " Last seen: Today %s\n", hourmin); wprintw(self->window, " Last seen: Today %s\n", hourmin);
@ -1026,7 +1063,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
self->x = x2; self->x = x2;
if (Friends.num_friends) { if (num_friends) {
wmove(self->window, y2 - 1, 1); wmove(self->window, y2 - 1, 1);
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);

View File

@ -54,6 +54,7 @@ void hst_to_net(uint8_t *num, uint16_t numbytes)
return; return;
} }
/* Note: The time functions are not thread safe */
void update_unix_time(void) void update_unix_time(void)
{ {
current_unix_time = (uint64_t) time(NULL); current_unix_time = (uint64_t) time(NULL);

View File

@ -53,16 +53,16 @@ int hex_string_to_bin(const char *hex_string, size_t hex_len, char *output, size
/* convert a hex string to bytes. returns 0 on success, -1 on failure */ /* convert a hex string to bytes. returns 0 on success, -1 on failure */
int hex_string_to_bytes(char *buf, int size, const char *keystr); int hex_string_to_bytes(char *buf, int size, const char *keystr);
/* get the current unix time */ /* get the current unix time (not thread safe) */
uint64_t get_unix_time(void); uint64_t get_unix_time(void);
/* Puts the current time in buf in the format of [HH:mm:ss] */ /* Puts the current time in buf in the format of [HH:mm:ss] (not thread safe) */
void get_time_str(char *buf, int bufsize); void get_time_str(char *buf, int bufsize);
/* Converts seconds to string in format HH:mm:ss; truncates hours and minutes when necessary */ /* Converts seconds to string in format HH:mm:ss; truncates hours and minutes when necessary */
void get_elapsed_time_str(char *buf, int bufsize, uint64_t secs); void get_elapsed_time_str(char *buf, int bufsize, uint64_t secs);
/* get the current local time */ /* get the current local time (not thread safe) */
struct tm *get_time(void); struct tm *get_time(void);
/* updates current unix time (should be run once per do_toxic loop) */ /* updates current unix time (should be run once per do_toxic loop) */

View File

@ -257,7 +257,7 @@ void* do_playing(void* _p)
} }
} }
#ifdef BOX_NOTIFY #ifdef BOX_NOTIFY
else if (actives[i].box && get_unix_time() >= actives[i].n_timeout) else if (actives[i].box && time(NULL) >= actives[i].n_timeout)
{ {
GError* ignore; GError* ignore;
notify_notification_close(actives[i].box, &ignore); notify_notification_close(actives[i].box, &ignore);
@ -278,7 +278,7 @@ void* do_playing(void* _p)
/* device is opened and no activity in under DEVICE_COOLDOWN time, close device*/ /* device is opened and no activity in under DEVICE_COOLDOWN time, close device*/
if (device_opened && !has_looping && if (device_opened && !has_looping &&
(get_unix_time() - last_opened_update) > DEVICE_COOLDOWN) { (time(NULL) - last_opened_update) > DEVICE_COOLDOWN) {
m_close_device(); m_close_device();
} }
has_looping = false; has_looping = false;
@ -323,7 +323,7 @@ void* do_playing(void* _p)
int i; int i;
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) { for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) {
if (actives[i].box && get_unix_time() >= actives[i].n_timeout) if (actives[i].box && time(NULL) >= actives[i].n_timeout)
{ {
GError* ignore; GError* ignore;
notify_notification_close(actives[i].box, &ignore); notify_notification_close(actives[i].box, &ignore);
@ -391,7 +391,7 @@ int init_notify(int login_cooldown, int notification_timeout)
} }
#endif #endif
Control.cooldown = get_unix_time() + login_cooldown; Control.cooldown = time(NULL) + login_cooldown;
#ifdef BOX_NOTIFY #ifdef BOX_NOTIFY

View File

@ -260,14 +260,23 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]); mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);
StatusBar *statusbar = self->stb; StatusBar *statusbar = self->stb;
mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2); mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2);
wmove(statusbar->topline, 0, 0); wmove(statusbar->topline, 0, 0);
if (statusbar->connection != TOX_CONNECTION_NONE) { pthread_mutex_lock(&Winthread.lock);
TOX_CONNECTION connection = statusbar->connection;
pthread_mutex_unlock(&Winthread.lock);
if (connection != TOX_CONNECTION_NONE) {
int colour = MAGENTA; int colour = MAGENTA;
const char *status_text = "ERROR"; const char *status_text = "ERROR";
switch (statusbar->status) { pthread_mutex_lock(&Winthread.lock);
TOX_USER_STATUS status = statusbar->status;
pthread_mutex_unlock(&Winthread.lock);
switch (status) {
case TOX_USER_STATUS_NONE: case TOX_USER_STATUS_NONE:
status_text = "Online"; status_text = "Online";
colour = GREEN; colour = GREEN;
@ -287,12 +296,16 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
wattron(statusbar->topline, A_BOLD); wattron(statusbar->topline, A_BOLD);
pthread_mutex_lock(&Winthread.lock);
wprintw(statusbar->topline, " %s", statusbar->nick); wprintw(statusbar->topline, " %s", statusbar->nick);
pthread_mutex_unlock(&Winthread.lock);
wattroff(statusbar->topline, A_BOLD); wattroff(statusbar->topline, A_BOLD);
} else { } else {
wprintw(statusbar->topline, " [Offline]"); wprintw(statusbar->topline, " [Offline]");
wattron(statusbar->topline, A_BOLD); wattron(statusbar->topline, A_BOLD);
pthread_mutex_lock(&Winthread.lock);
wprintw(statusbar->topline, " %s", statusbar->nick); wprintw(statusbar->topline, " %s", statusbar->nick);
pthread_mutex_unlock(&Winthread.lock);
wattroff(statusbar->topline, A_BOLD); wattroff(statusbar->topline, A_BOLD);
} }
@ -304,10 +317,9 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
size_t slen = tox_self_get_status_message_size(m); size_t slen = tox_self_get_status_message_size(m);
tox_self_get_status_message (m, (uint8_t*) statusmsg); tox_self_get_status_message (m, (uint8_t*) statusmsg);
statusmsg[slen] = '\0'; statusmsg[slen] = '\0';
pthread_mutex_unlock(&Winthread.lock);
snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg); snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
statusbar->statusmsg_len = strlen(statusbar->statusmsg); statusbar->statusmsg_len = strlen(statusbar->statusmsg);
pthread_mutex_unlock(&Winthread.lock);
} }
self->x = x2; self->x = x2;
@ -315,6 +327,8 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
/* Truncate note if it doesn't fit in statusbar */ /* Truncate note if it doesn't fit in statusbar */
uint16_t maxlen = x2 - getcurx(statusbar->topline) - 3; uint16_t maxlen = x2 - getcurx(statusbar->topline) - 3;
pthread_mutex_lock(&Winthread.lock);
if (statusbar->statusmsg_len > maxlen) { if (statusbar->statusmsg_len > maxlen) {
statusbar->statusmsg[maxlen - 3] = '\0'; statusbar->statusmsg[maxlen - 3] = '\0';
strcat(statusbar->statusmsg, "..."); strcat(statusbar->statusmsg, "...");
@ -324,6 +338,8 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
if (statusbar->statusmsg[0]) if (statusbar->statusmsg[0])
wprintw(statusbar->topline, " : %s", statusbar->statusmsg); wprintw(statusbar->topline, " : %s", statusbar->statusmsg);
pthread_mutex_unlock(&Winthread.lock);
mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2); mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2);
int y, x; int y, x;

View File

@ -807,10 +807,14 @@ static void do_bootstrap(Tox *m)
static void do_toxic(Tox *m, ToxWindow *prompt) static void do_toxic(Tox *m, ToxWindow *prompt)
{ {
if (arg_opts.no_connect)
return;
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
update_unix_time();
if (arg_opts.no_connect) {
pthread_mutex_unlock(&Winthread.lock);
return;
}
tox_iterate(m); tox_iterate(m);
do_bootstrap(m); do_bootstrap(m);
check_file_transfer_timeouts(m); check_file_transfer_timeouts(m);
@ -822,6 +826,7 @@ static void do_toxic(Tox *m, ToxWindow *prompt)
void *thread_winref(void *data) void *thread_winref(void *data)
{ {
Tox *m = (Tox *) data; Tox *m = (Tox *) data;
uint8_t draw_count = 0; uint8_t draw_count = 0;
init_signal_catchers(); init_signal_catchers();
@ -1105,14 +1110,16 @@ static useconds_t optimal_msleepval(uint64_t *looptimer, uint64_t *loopcount, ui
return new_sleep; return new_sleep;
} }
// this doesn't do anything (yet)
#ifdef X11 #ifdef X11
// FIXME
void DnD_callback(const char* asdv, DropType dt) void DnD_callback(const char* asdv, DropType dt)
{ {
if (dt != DT_plain) // if (dt != DT_plain)
return; // return;
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, asdv); // pthread_mutex_lock(&Winthread.lock);
// line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, asdv);
pthread_mutex_unlock(&Winthread.lock);
} }
#endif /* X11 */ #endif /* X11 */
@ -1181,6 +1188,7 @@ int main(int argc, char *argv[])
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);
#ifdef AUDIO #ifdef AUDIO
av = init_audio(prompt, m); av = init_audio(prompt, m);
@ -1214,7 +1222,10 @@ int main(int argc, char *argv[])
if (init_mplex_away_timer(m) == -1) if (init_mplex_away_timer(m) == -1)
queue_init_message("Failed to init mplex auto-away."); queue_init_message("Failed to init mplex auto-away.");
pthread_mutex_lock(&Winthread.lock);
print_init_messages(prompt); print_init_messages(prompt);
pthread_mutex_unlock(&Winthread.lock);
cleanup_init_messages(); cleanup_init_messages();
/* set user avatar from config file. if no path is supplied tox_unset_avatar is called */ /* set user avatar from config file. if no path is supplied tox_unset_avatar is called */
@ -1228,7 +1239,6 @@ int main(int argc, char *argv[])
uint64_t loopcount = 0; uint64_t loopcount = 0;
while (true) { while (true) {
update_unix_time();
do_toxic(m, prompt); do_toxic(m, prompt);
uint64_t cur_time = get_unix_time(); uint64_t cur_time = get_unix_time();

View File

@ -454,10 +454,16 @@ void on_window_resize(void)
static void draw_window_tab(ToxWindow *toxwin) static void draw_window_tab(ToxWindow *toxwin)
{ {
pthread_mutex_lock(&Winthread.lock);
if (toxwin->alert != WINDOW_ALERT_NONE) attron(COLOR_PAIR(toxwin->alert)); if (toxwin->alert != WINDOW_ALERT_NONE) attron(COLOR_PAIR(toxwin->alert));
pthread_mutex_unlock(&Winthread.lock);
clrtoeol(); clrtoeol();
printw(" [%s]", toxwin->name); printw(" [%s]", toxwin->name);
pthread_mutex_lock(&Winthread.lock);
if (toxwin->alert != WINDOW_ALERT_NONE) attroff(COLOR_PAIR(toxwin->alert)); if (toxwin->alert != WINDOW_ALERT_NONE) attroff(COLOR_PAIR(toxwin->alert));
pthread_mutex_unlock(&Winthread.lock);
} }
static void draw_bar(void) static void draw_bar(void)
@ -505,7 +511,10 @@ static void draw_bar(void)
void draw_active_window(Tox *m) void draw_active_window(Tox *m)
{ {
ToxWindow *a = active_window; ToxWindow *a = active_window;
pthread_mutex_lock(&Winthread.lock);
a->alert = WINDOW_ALERT_NONE; a->alert = WINDOW_ALERT_NONE;
pthread_mutex_unlock(&Winthread.lock);
wint_t ch = 0; wint_t ch = 0;