From e0371a7943009d611a4dc080dcddfcdfba9f589b Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sun, 23 Dec 2007 01:43:39 +0000 Subject: [PATCH] ncurses 5.6 - patch 20071222 + continue implementing support for threading demo by adding mutex for delwin(). --- NEWS | 6 ++++- dist.mk | 4 ++-- ncurses/base/lib_delwin.c | 28 +++++++++++++---------- ncurses/base/lib_freeall.c | 16 +++++++++++-- ncurses/base/lib_newwin.c | 46 ++++++++++++++++++++++---------------- ncurses/base/resizeterm.c | 9 +++++++- ncurses/base/wresize.c | 5 ++++- ncurses/curses.priv.h | 17 ++++++++++++-- test/worm.c | 23 ++++++++++++++++--- 9 files changed, 111 insertions(+), 43 deletions(-) diff --git a/NEWS b/NEWS index b3519209..59659091 100644 --- a/NEWS +++ b/NEWS @@ -25,7 +25,7 @@ -- sale, use or other dealings in this Software without prior written -- -- authorization. -- ------------------------------------------------------------------------------- --- $Id: NEWS,v 1.1187 2007/12/16 00:23:41 tom Exp $ +-- $Id: NEWS,v 1.1188 2007/12/22 23:56:08 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,10 @@ See the AUTHORS file for the corresponding full names. Changes through 1.9.9e did not credit all contributions; it is not possible to add this information. +20071222 + + continue implementing support for threading demo by adding mutex + for delwin(). + 20071215 + add several functions to C++ binding which wrap C functions that pass a WINDOW* parameter (request by Chris Lee). diff --git a/dist.mk b/dist.mk index 7d02e714..a29dd36e 100644 --- a/dist.mk +++ b/dist.mk @@ -25,7 +25,7 @@ # use or other dealings in this Software without prior written # # authorization. # ############################################################################## -# $Id: dist.mk,v 1.619 2007/12/15 22:01:55 tom Exp $ +# $Id: dist.mk,v 1.620 2007/12/22 20:41:31 tom Exp $ # Makefile for creating ncurses distributions. # # This only needs to be used directly as a makefile by developers, but @@ -37,7 +37,7 @@ SHELL = /bin/sh # These define the major/minor/patch versions of ncurses. NCURSES_MAJOR = 5 NCURSES_MINOR = 6 -NCURSES_PATCH = 20071215 +NCURSES_PATCH = 20071222 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/ncurses/base/lib_delwin.c b/ncurses/base/lib_delwin.c index e16f7878..fc68f9d6 100644 --- a/ncurses/base/lib_delwin.c +++ b/ncurses/base/lib_delwin.c @@ -40,7 +40,7 @@ #include -MODULE_ID("$Id: lib_delwin.c,v 1.14 2007/11/03 20:24:15 tom Exp $") +MODULE_ID("$Id: lib_delwin.c,v 1.15 2007/12/22 23:34:26 tom Exp $") static bool cannot_delete(WINDOW *win) @@ -67,19 +67,23 @@ delwin(WINDOW *win) T((T_CALLED("delwin(%p)"), win)); - _nc_lock_global(windowlist); - if (win == 0 - || cannot_delete(win)) { - result = ERR; - } else { + if (_nc_try_global(windowlist) == 0) { + _nc_lock_window(win); + if (win == 0 + || cannot_delete(win)) { + result = ERR; + _nc_unlock_window(win); + } else { - if (win->_flags & _SUBWIN) - touchwin(win->_parent); - else if (curscr != 0) - touchwin(curscr); + if (win->_flags & _SUBWIN) + touchwin(win->_parent); + else if (curscr != 0) + touchwin(curscr); - result = _nc_freewin(win); + _nc_unlock_window(win); + result = _nc_freewin(win); + } + _nc_unlock_global(windowlist); } - _nc_unlock_global(windowlist); returnCode(result); } diff --git a/ncurses/base/lib_freeall.c b/ncurses/base/lib_freeall.c index 0fc86239..dbf0483f 100644 --- a/ncurses/base/lib_freeall.c +++ b/ncurses/base/lib_freeall.c @@ -40,7 +40,7 @@ extern int malloc_errfd; /* FIXME */ #endif -MODULE_ID("$Id: lib_freeall.c,v 1.44 2007/06/02 19:40:25 tom Exp $") +MODULE_ID("$Id: lib_freeall.c,v 1.45 2007/12/22 23:29:37 tom Exp $") /* * Free all ncurses data. This is used for testing only (there's no practical @@ -61,7 +61,11 @@ _nc_freeall(void) } #endif if (SP != 0) { + _nc_lock_global(windowlist); + while (_nc_windows != 0) { + bool deleted = FALSE; + /* Delete only windows that're not a parent */ for (p = _nc_windows; p != 0; p = p->next) { bool found = FALSE; @@ -76,12 +80,20 @@ _nc_freeall(void) } if (!found) { - delwin(&(p->win)); + if (delwin(&(p->win)) != ERR) + deleted = TRUE; break; } } + + /* + * Don't continue to loop if the list is trashed. + */ + if (!deleted) + break; } delscreen(SP); + _nc_unlock_global(windowlist); } if (cur_term != 0) del_curterm(cur_term); diff --git a/ncurses/base/lib_newwin.c b/ncurses/base/lib_newwin.c index 3f7275c1..b0f4603a 100644 --- a/ncurses/base/lib_newwin.c +++ b/ncurses/base/lib_newwin.c @@ -41,7 +41,7 @@ #include -MODULE_ID("$Id: lib_newwin.c,v 1.41 2007/10/20 20:56:07 tom Exp $") +MODULE_ID("$Id: lib_newwin.c,v 1.42 2007/12/22 23:20:18 tom Exp $") static WINDOW * remove_window_from_screen(WINDOW *win) @@ -85,29 +85,34 @@ _nc_freewin(WINDOW *win) int i; int result = ERR; + T((T_CALLED("_nc_freewin(%p)"), win)); + if (win != 0) { - for (p = _nc_windows, q = 0; p != 0; q = p, p = p->next) { - if (&(p->win) == win) { - remove_window_from_screen(win); - if (q == 0) - _nc_windows = p->next; - else - q->next = p->next; - - if (!(win->_flags & _SUBWIN)) { - for (i = 0; i <= win->_maxy; i++) - FreeIfNeeded(win->_line[i].text); + if (_nc_try_global(windowlist) == 0) { + for (p = _nc_windows, q = 0; p != 0; q = p, p = p->next) { + if (&(p->win) == win) { + remove_window_from_screen(win); + if (q == 0) + _nc_windows = p->next; + else + q->next = p->next; + + if (!(win->_flags & _SUBWIN)) { + for (i = 0; i <= win->_maxy; i++) + FreeIfNeeded(win->_line[i].text); + } + free(win->_line); + free(p); + + result = OK; + T(("...deleted win=%p", win)); + break; } - free(win->_line); - free(p); - - result = OK; - T(("...deleted win=%p", win)); - break; } + _nc_unlock_global(windowlist); } } - return result; + returnCode(result); } NCURSES_EXPORT(WINDOW *) @@ -241,6 +246,8 @@ _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) returnWin(0); } + _nc_lock_global(windowlist); + win->_curx = 0; win->_cury = 0; win->_maxy = num_lines - 1; @@ -318,5 +325,6 @@ _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) T((T_CREATE("window %p"), win)); + _nc_unlock_global(windowlist); returnWin(win); } diff --git a/ncurses/base/resizeterm.c b/ncurses/base/resizeterm.c index 02057b18..8bea743a 100644 --- a/ncurses/base/resizeterm.c +++ b/ncurses/base/resizeterm.c @@ -41,7 +41,7 @@ #include #include -MODULE_ID("$Id: resizeterm.c,v 1.23 2007/10/13 20:12:13 tom Exp $") +MODULE_ID("$Id: resizeterm.c,v 1.24 2007/12/22 23:20:31 tom Exp $") #define stolen_lines (screen_lines - SP->_lines_avail) @@ -66,6 +66,7 @@ show_window_sizes(const char *name) { WINDOWLIST *wp; + _nc_lock_global(windowlist); _tracef("%s resizing: %2d x %2d (%2d x %2d)", name, LINES, COLS, screen_lines, screen_columns); for (wp = _nc_windows; wp != 0; wp = wp->next) { @@ -76,6 +77,7 @@ show_window_sizes(const char *name) (long) wp->win._begy, (long) wp->win._begx); } + _nc_unlock_global(windowlist); } #endif @@ -259,6 +261,9 @@ resize_term(int ToLines, int ToCols) if (SP == 0) { returnCode(ERR); } + + _nc_lock_global(windowlist); + was_stolen = (screen_lines - SP->_lines_avail); if (is_term_resized(ToLines, ToCols)) { int myLines = CurLines = screen_lines; @@ -315,6 +320,8 @@ resize_term(int ToLines, int ToCols) SET_LINES(ToLines - was_stolen); SET_COLS(ToCols); + _nc_unlock_global(windowlist); + returnCode(result); } diff --git a/ncurses/base/wresize.c b/ncurses/base/wresize.c index ae62806e..f756f0f2 100644 --- a/ncurses/base/wresize.c +++ b/ncurses/base/wresize.c @@ -32,7 +32,7 @@ #include -MODULE_ID("$Id: wresize.c,v 1.26 2007/09/29 20:37:13 tom Exp $") +MODULE_ID("$Id: wresize.c,v 1.27 2007/12/22 23:20:53 tom Exp $") static int cleanup_lines(struct ldat *data, int length) @@ -54,6 +54,8 @@ repair_subwindows(WINDOW *cmp) struct ldat *pline = cmp->_line; int row; + _nc_lock_global(windowlist); + for (wp = _nc_windows; wp != 0; wp = wp->next) { WINDOW *tst = &(wp->win); @@ -75,6 +77,7 @@ repair_subwindows(WINDOW *cmp) repair_subwindows(tst); } } + _nc_unlock_global(windowlist); } /* diff --git a/ncurses/curses.priv.h b/ncurses/curses.priv.h index 57fd2409..54ffc8ec 100644 --- a/ncurses/curses.priv.h +++ b/ncurses/curses.priv.h @@ -34,7 +34,7 @@ /* - * $Id: curses.priv.h,v 1.351 2007/11/25 00:57:29 tom Exp $ + * $Id: curses.priv.h,v 1.353 2007/12/23 00:15:38 tom Exp $ * * curses.priv.h * @@ -300,10 +300,22 @@ color_t; #define SET_COLS(value) COLS = value #endif +#define TR_MUTEX(data) _tracef("%s@%d: me:%08lX COUNT:%2u/%2d/%6d/%2d/%s%9u: " #data, \ + __FILE__, __LINE__, \ + (unsigned long) (pthread_self()), \ + data.__data.__lock, \ + data.__data.__count, \ + data.__data.__owner, \ + data.__data.__kind, \ + (data.__data.__nusers > 5) ? " OOPS " : "", \ + data.__data.__nusers) +#define TR_GLOBAL_MUTEX(name) TR_MUTEX(_nc_globals.mutex_##name) + #ifdef USE_PTHREADS #if USE_REENTRANT #include #define _nc_lock_global(name) pthread_mutex_lock(&_nc_globals.mutex_##name) +#define _nc_try_global(name) pthread_mutex_trylock(&_nc_globals.mutex_##name) #define _nc_unlock_global(name) pthread_mutex_unlock(&_nc_globals.mutex_##name) extern NCURSES_EXPORT(void) _nc_lock_window(WINDOW *); @@ -314,9 +326,10 @@ extern NCURSES_EXPORT(void) _nc_unlock_window(WINDOW *); #endif #else #define _nc_lock_global(name) /* nothing */ +#define _nc_try_global(name) 0 #define _nc_unlock_global(name) /* nothing */ -#define _nc_lock_window(name) TRUE +#define _nc_lock_window(name) (void) TRUE #define _nc_unlock_window(name) /* nothing */ #endif diff --git a/test/worm.c b/test/worm.c index 534e626e..61d97a9a 100644 --- a/test/worm.c +++ b/test/worm.c @@ -61,7 +61,7 @@ Options: traces will be dumped. The program stops and waits for one character of input at the beginning and end of the interval. - $Id: worm.c,v 1.49 2007/09/29 17:35:57 tom Exp $ + $Id: worm.c,v 1.50 2007/12/22 23:55:13 tom Exp $ */ #include @@ -93,6 +93,8 @@ typedef struct worm { #endif } WORM; +static bool quitting = FALSE; + static WORM worm[40]; static short **refs; @@ -313,11 +315,17 @@ use_window(WINDOW *win, int (*func) (WINDOW *, void *), void *data) #endif #ifdef USE_PTHREADS +static bool +quit_worm(void) +{ + napms(20); /* let the other thread(s) have a chance */ + return quitting; +} + static void * start_worm(void *arg) { - for (;;) { - napms(20); + while (!quit_worm()) { use_window(stdscr, draw_worm, arg); } return NULL; @@ -533,6 +541,7 @@ main(int argc, char *argv[]) * normal operation -T.Dickey */ if (ch == 'q') { + quitting = TRUE; done = TRUE; continue; } else if (ch == 's') { @@ -557,6 +566,14 @@ main(int argc, char *argv[]) free(w->xpos); free(w->ypos); } +#endif +#ifdef USE_PTHREADS + /* + * Do this just in case one of the threads did not really exit. + */ + for (n = 0; n < number; n++) { + pthread_join(worm[n].thread, NULL); + } #endif ExitProgram(EXIT_SUCCESS); } -- 2.45.0