Release screen mutex if thread dies
We did not setup a thread cleanup procedure which resulted in calcurse freezing if a thread tried to draw on the screen after another thread was canceled while locking the screen. Note that this kind of cleanup handlers should be added to other mutexes as well. This patch just removes the most common case of triggering a deadlock. Also note that we cannot move pthread_cleanup_push() and pthread_cleanup_pop() into the locking/unlocking functions since both pthread_cleanup_push() and pthread_cleanup_pop() may be implemented as macros that must be used in pairs within the same lexical scope. Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
parent
a80f8dcf2c
commit
0ea23c24bf
@ -456,6 +456,22 @@ enum win {
|
|||||||
#define FLAG_STA (1 << STA)
|
#define FLAG_STA (1 << STA)
|
||||||
#define FLAG_ALL ((1 << NBWINS) - 1)
|
#define FLAG_ALL ((1 << NBWINS) - 1)
|
||||||
|
|
||||||
|
#define WINS_NBAR_LOCK \
|
||||||
|
pthread_cleanup_push(wins_nbar_cleanup, NULL); \
|
||||||
|
wins_nbar_lock();
|
||||||
|
|
||||||
|
#define WINS_NBAR_UNLOCK \
|
||||||
|
wins_nbar_unlock(); \
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
|
|
||||||
|
#define WINS_CALENDAR_LOCK \
|
||||||
|
pthread_cleanup_push(wins_calendar_cleanup, NULL); \
|
||||||
|
wins_calendar_lock();
|
||||||
|
|
||||||
|
#define WINS_CALENDAR_UNLOCK \
|
||||||
|
wins_calendar_unlock(); \
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
|
|
||||||
enum ui_mode {
|
enum ui_mode {
|
||||||
UI_CURSES,
|
UI_CURSES,
|
||||||
UI_CMDLINE,
|
UI_CMDLINE,
|
||||||
@ -977,8 +993,10 @@ void vars_init(void);
|
|||||||
extern struct window win[NBWINS];
|
extern struct window win[NBWINS];
|
||||||
unsigned wins_nbar_lock(void);
|
unsigned wins_nbar_lock(void);
|
||||||
void wins_nbar_unlock(void);
|
void wins_nbar_unlock(void);
|
||||||
|
void wins_nbar_cleanup(void *);
|
||||||
unsigned wins_calendar_lock(void);
|
unsigned wins_calendar_lock(void);
|
||||||
void wins_calendar_unlock(void);
|
void wins_calendar_unlock(void);
|
||||||
|
void wins_calendar_cleanup(void *);
|
||||||
int wins_refresh(void);
|
int wins_refresh(void);
|
||||||
int wins_wrefresh(WINDOW *);
|
int wins_wrefresh(WINDOW *);
|
||||||
int wins_doupdate(void);
|
int wins_doupdate(void);
|
||||||
|
@ -297,7 +297,7 @@ draw_monthly_view(struct window *cwin, struct date *current_day,
|
|||||||
c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L);
|
c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L);
|
||||||
|
|
||||||
/* Write the current month and year on top of the calendar */
|
/* Write the current month and year on top of the calendar */
|
||||||
wins_calendar_lock();
|
WINS_CALENDAR_LOCK;
|
||||||
custom_apply_attr(cwin->p, ATTR_HIGHEST);
|
custom_apply_attr(cwin->p, ATTR_HIGHEST);
|
||||||
mvwprintw(cwin->p, ofs_y,
|
mvwprintw(cwin->p, ofs_y,
|
||||||
(SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2,
|
(SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2,
|
||||||
@ -311,7 +311,7 @@ draw_monthly_view(struct window *cwin, struct date *current_day,
|
|||||||
mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, _(daynames[1 + j - sunday_first]));
|
mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, _(daynames[1 + j - sunday_first]));
|
||||||
}
|
}
|
||||||
custom_remove_attr(cwin->p, ATTR_HIGHEST);
|
custom_remove_attr(cwin->p, ATTR_HIGHEST);
|
||||||
wins_calendar_unlock();
|
WINS_CALENDAR_UNLOCK;
|
||||||
|
|
||||||
day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7;
|
day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7;
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ draw_monthly_view(struct window *cwin, struct date *current_day,
|
|||||||
ofs_x = OFFX - day_1_sav - 4 * c_day;
|
ofs_x = OFFX - day_1_sav - 4 * c_day;
|
||||||
}
|
}
|
||||||
|
|
||||||
wins_calendar_lock();
|
WINS_CALENDAR_LOCK;
|
||||||
if (c_day == current_day->dd
|
if (c_day == current_day->dd
|
||||||
&& current_day->mm == slctd_day.mm
|
&& current_day->mm == slctd_day.mm
|
||||||
&& current_day->yyyy == slctd_day.yyyy
|
&& current_day->yyyy == slctd_day.yyyy
|
||||||
@ -355,7 +355,7 @@ draw_monthly_view(struct window *cwin, struct date *current_day,
|
|||||||
mvwprintw(cwin->p, ofs_y + 1,
|
mvwprintw(cwin->p, ofs_y + 1,
|
||||||
ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
|
ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
|
||||||
}
|
}
|
||||||
wins_calendar_unlock();
|
WINS_CALENDAR_UNLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,11 +459,11 @@ draw_weekly_view(struct window *cwin, struct date *current_day,
|
|||||||
|
|
||||||
/* Print the week number. */
|
/* Print the week number. */
|
||||||
weeknum = ISO8601weeknum(&t);
|
weeknum = ISO8601weeknum(&t);
|
||||||
wins_calendar_lock();
|
WINS_CALENDAR_LOCK;
|
||||||
custom_apply_attr(cwin->p, ATTR_HIGHEST);
|
custom_apply_attr(cwin->p, ATTR_HIGHEST);
|
||||||
mvwprintw(cwin->p, 2, cwin->w - 9, "(# %02d)", weeknum);
|
mvwprintw(cwin->p, 2, cwin->w - 9, "(# %02d)", weeknum);
|
||||||
custom_remove_attr(cwin->p, ATTR_HIGHEST);
|
custom_remove_attr(cwin->p, ATTR_HIGHEST);
|
||||||
wins_calendar_unlock();
|
WINS_CALENDAR_UNLOCK;
|
||||||
|
|
||||||
/* Now draw calendar view. */
|
/* Now draw calendar view. */
|
||||||
for (j = 0; j < WEEKINDAYS; j++) {
|
for (j = 0; j < WEEKINDAYS; j++) {
|
||||||
@ -495,28 +495,28 @@ draw_weekly_view(struct window *cwin, struct date *current_day,
|
|||||||
else
|
else
|
||||||
attr = 0;
|
attr = 0;
|
||||||
|
|
||||||
wins_calendar_lock();
|
WINS_CALENDAR_LOCK;
|
||||||
if (attr)
|
if (attr)
|
||||||
custom_apply_attr(cwin->p, attr);
|
custom_apply_attr(cwin->p, attr);
|
||||||
mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday);
|
mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday);
|
||||||
if (attr)
|
if (attr)
|
||||||
custom_remove_attr(cwin->p, attr);
|
custom_remove_attr(cwin->p, attr);
|
||||||
wins_calendar_unlock();
|
WINS_CALENDAR_UNLOCK;
|
||||||
|
|
||||||
/* Draw slices indicating appointment times. */
|
/* Draw slices indicating appointment times. */
|
||||||
memset(slices, 0, DAYSLICESNO * sizeof *slices);
|
memset(slices, 0, DAYSLICESNO * sizeof *slices);
|
||||||
if (day_chk_busy_slices(date, DAYSLICESNO, slices)) {
|
if (day_chk_busy_slices(date, DAYSLICESNO, slices)) {
|
||||||
for (i = 0; i < DAYSLICESNO; i++) {
|
for (i = 0; i < DAYSLICESNO; i++) {
|
||||||
if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) {
|
if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) {
|
||||||
wins_calendar_lock();
|
WINS_CALENDAR_LOCK;
|
||||||
mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2);
|
mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2);
|
||||||
wins_calendar_unlock();
|
WINS_CALENDAR_UNLOCK;
|
||||||
}
|
}
|
||||||
if (slices[i]) {
|
if (slices[i]) {
|
||||||
int highlight;
|
int highlight;
|
||||||
|
|
||||||
highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0;
|
highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0;
|
||||||
wins_calendar_lock();
|
WINS_CALENDAR_LOCK;
|
||||||
if (highlight)
|
if (highlight)
|
||||||
custom_apply_attr(cwin->p, attr);
|
custom_apply_attr(cwin->p, attr);
|
||||||
wattron(cwin->p, A_REVERSE);
|
wattron(cwin->p, A_REVERSE);
|
||||||
@ -525,7 +525,7 @@ draw_weekly_view(struct window *cwin, struct date *current_day,
|
|||||||
wattroff(cwin->p, A_REVERSE);
|
wattroff(cwin->p, A_REVERSE);
|
||||||
if (highlight)
|
if (highlight)
|
||||||
custom_remove_attr(cwin->p, attr);
|
custom_remove_attr(cwin->p, attr);
|
||||||
wins_calendar_unlock();
|
WINS_CALENDAR_UNLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,13 +535,13 @@ draw_weekly_view(struct window *cwin, struct date *current_day,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Draw marks to indicate midday on the sides of the calendar. */
|
/* Draw marks to indicate midday on the sides of the calendar. */
|
||||||
wins_calendar_lock();
|
WINS_CALENDAR_LOCK;
|
||||||
custom_apply_attr(cwin->p, ATTR_HIGHEST);
|
custom_apply_attr(cwin->p, ATTR_HIGHEST);
|
||||||
mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1);
|
mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1);
|
||||||
mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2,
|
mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2,
|
||||||
OFFX + WCALWIDTH - 3, ACS_S9, 1);
|
OFFX + WCALWIDTH - 3, ACS_S9, 1);
|
||||||
custom_remove_attr(cwin->p, ATTR_HIGHEST);
|
custom_remove_attr(cwin->p, ATTR_HIGHEST);
|
||||||
wins_calendar_unlock();
|
WINS_CALENDAR_UNLOCK;
|
||||||
|
|
||||||
#undef DAYSLICESNO
|
#undef DAYSLICESNO
|
||||||
}
|
}
|
||||||
@ -554,10 +554,10 @@ void calendar_update_panel(struct window *cwin)
|
|||||||
|
|
||||||
calendar_store_current_date(¤t_day);
|
calendar_store_current_date(¤t_day);
|
||||||
|
|
||||||
wins_calendar_lock();
|
WINS_CALENDAR_LOCK;
|
||||||
erase_window_part(cwin->p, 1, 3, cwin->w - 2, cwin->h - 2);
|
erase_window_part(cwin->p, 1, 3, cwin->w - 2, cwin->h - 2);
|
||||||
mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2);
|
mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2);
|
||||||
wins_calendar_unlock();
|
WINS_CALENDAR_UNLOCK;
|
||||||
|
|
||||||
sunday_first = calendar_week_begins_on_monday()? 0 : 1;
|
sunday_first = calendar_week_begins_on_monday()? 0 : 1;
|
||||||
|
|
||||||
|
12
src/notify.c
12
src/notify.c
@ -240,13 +240,13 @@ void notify_update_bar(void)
|
|||||||
app_pos = file_pos + strlen(notify.apts_file) + 2 + space;
|
app_pos = file_pos + strlen(notify.apts_file) + 2 + space;
|
||||||
txt_max_len = col - (app_pos + 12 + space);
|
txt_max_len = col - (app_pos + 12 + space);
|
||||||
|
|
||||||
wins_nbar_lock();
|
WINS_NBAR_LOCK;
|
||||||
custom_apply_attr(notify.win, ATTR_HIGHEST);
|
custom_apply_attr(notify.win, ATTR_HIGHEST);
|
||||||
wattron(notify.win, A_UNDERLINE | A_REVERSE);
|
wattron(notify.win, A_UNDERLINE | A_REVERSE);
|
||||||
mvwhline(notify.win, 0, 0, ACS_HLINE, col);
|
mvwhline(notify.win, 0, 0, ACS_HLINE, col);
|
||||||
mvwprintw(notify.win, 0, date_pos, "[ %s | %s ]", notify.date, notify.time);
|
mvwprintw(notify.win, 0, date_pos, "[ %s | %s ]", notify.date, notify.time);
|
||||||
mvwprintw(notify.win, 0, file_pos, "(%s)", notify.apts_file);
|
mvwprintw(notify.win, 0, file_pos, "(%s)", notify.apts_file);
|
||||||
wins_nbar_unlock();
|
WINS_NBAR_UNLOCK;
|
||||||
|
|
||||||
pthread_mutex_lock(¬ify_app.mutex);
|
pthread_mutex_lock(¬ify_app.mutex);
|
||||||
if (notify_app.got_app) {
|
if (notify_app.got_app) {
|
||||||
@ -273,7 +273,7 @@ void notify_update_bar(void)
|
|||||||
else
|
else
|
||||||
blinking = 0;
|
blinking = 0;
|
||||||
|
|
||||||
wins_nbar_lock();
|
WINS_NBAR_LOCK;
|
||||||
if (blinking)
|
if (blinking)
|
||||||
wattron(notify.win, A_BLINK);
|
wattron(notify.win, A_BLINK);
|
||||||
if (too_long)
|
if (too_long)
|
||||||
@ -284,7 +284,7 @@ void notify_update_bar(void)
|
|||||||
hours_left, minutes_left, notify_app.txt);
|
hours_left, minutes_left, notify_app.txt);
|
||||||
if (blinking)
|
if (blinking)
|
||||||
wattroff(notify.win, A_BLINK);
|
wattroff(notify.win, A_BLINK);
|
||||||
wins_nbar_unlock();
|
WINS_NBAR_UNLOCK;
|
||||||
|
|
||||||
if (blinking)
|
if (blinking)
|
||||||
notify_launch_cmd();
|
notify_launch_cmd();
|
||||||
@ -299,10 +299,10 @@ void notify_update_bar(void)
|
|||||||
}
|
}
|
||||||
pthread_mutex_unlock(¬ify_app.mutex);
|
pthread_mutex_unlock(¬ify_app.mutex);
|
||||||
|
|
||||||
wins_nbar_lock();
|
WINS_NBAR_LOCK;
|
||||||
wattroff(notify.win, A_UNDERLINE | A_REVERSE);
|
wattroff(notify.win, A_UNDERLINE | A_REVERSE);
|
||||||
custom_remove_attr(notify.win, ATTR_HIGHEST);
|
custom_remove_attr(notify.win, ATTR_HIGHEST);
|
||||||
wins_nbar_unlock();
|
WINS_NBAR_UNLOCK;
|
||||||
wins_wrefresh(notify.win);
|
wins_wrefresh(notify.win);
|
||||||
|
|
||||||
pthread_mutex_unlock(¬ify.mutex);
|
pthread_mutex_unlock(¬ify.mutex);
|
||||||
|
42
src/wins.c
42
src/wins.c
@ -40,6 +40,14 @@
|
|||||||
|
|
||||||
#include "calcurse.h"
|
#include "calcurse.h"
|
||||||
|
|
||||||
|
#define SCREEN_ACQUIRE \
|
||||||
|
pthread_cleanup_push(screen_cleanup, (void *)NULL); \
|
||||||
|
screen_acquire();
|
||||||
|
|
||||||
|
#define SCREEN_RELEASE \
|
||||||
|
screen_release(); \
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
|
|
||||||
/* Variables to handle calcurse windows. */
|
/* Variables to handle calcurse windows. */
|
||||||
struct window win[NBWINS];
|
struct window win[NBWINS];
|
||||||
|
|
||||||
@ -76,6 +84,11 @@ static void screen_release(void)
|
|||||||
pthread_mutex_unlock(&screen_mutex);
|
pthread_mutex_unlock(&screen_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void screen_cleanup(void *arg)
|
||||||
|
{
|
||||||
|
screen_release();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: The following functions currently lock the whole screen. Use both
|
* FIXME: The following functions currently lock the whole screen. Use both
|
||||||
* window-level and screen-level mutexes (or use use_screen() and use_window(),
|
* window-level and screen-level mutexes (or use use_screen() and use_window(),
|
||||||
@ -92,6 +105,11 @@ void wins_nbar_unlock(void)
|
|||||||
screen_release();
|
screen_release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wins_nbar_cleanup(void *arg)
|
||||||
|
{
|
||||||
|
wins_nbar_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
unsigned wins_calendar_lock(void)
|
unsigned wins_calendar_lock(void)
|
||||||
{
|
{
|
||||||
return screen_acquire();
|
return screen_acquire();
|
||||||
@ -102,14 +120,18 @@ void wins_calendar_unlock(void)
|
|||||||
screen_release();
|
screen_release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wins_calendar_cleanup(void *arg)
|
||||||
|
{
|
||||||
|
wins_calendar_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
int wins_refresh(void)
|
int wins_refresh(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!screen_acquire())
|
SCREEN_ACQUIRE;
|
||||||
return ERR;
|
|
||||||
rc = refresh();
|
rc = refresh();
|
||||||
screen_release();
|
SCREEN_RELEASE;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -118,10 +140,11 @@ int wins_wrefresh(WINDOW * win)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!win || !screen_acquire())
|
if (!win)
|
||||||
return ERR;
|
return ERR;
|
||||||
|
SCREEN_ACQUIRE;
|
||||||
rc = wrefresh(win);
|
rc = wrefresh(win);
|
||||||
screen_release();
|
SCREEN_RELEASE;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -130,10 +153,9 @@ int wins_doupdate(void)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!screen_acquire())
|
SCREEN_ACQUIRE;
|
||||||
return ERR;
|
|
||||||
rc = doupdate();
|
rc = doupdate();
|
||||||
screen_release();
|
SCREEN_RELEASE;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -502,12 +524,12 @@ static void border_nocolor(WINDOW * window)
|
|||||||
void wins_update_border(int flags)
|
void wins_update_border(int flags)
|
||||||
{
|
{
|
||||||
if (flags & FLAG_CAL) {
|
if (flags & FLAG_CAL) {
|
||||||
wins_calendar_lock();
|
WINS_CALENDAR_LOCK;
|
||||||
if (slctd_win == CAL)
|
if (slctd_win == CAL)
|
||||||
border_color(win[CAL].p);
|
border_color(win[CAL].p);
|
||||||
else
|
else
|
||||||
border_nocolor(win[CAL].p);
|
border_nocolor(win[CAL].p);
|
||||||
wins_calendar_unlock();
|
WINS_CALENDAR_UNLOCK;
|
||||||
}
|
}
|
||||||
if (flags & FLAG_APP) {
|
if (flags & FLAG_APP) {
|
||||||
if (slctd_win == APP)
|
if (slctd_win == APP)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user