ncurses 5.6 - patch 20071222
authorThomas E. Dickey <dickey@invisible-island.net>
Sun, 23 Dec 2007 01:43:39 +0000 (01:43 +0000)
committerThomas E. Dickey <dickey@invisible-island.net>
Sun, 23 Dec 2007 01:43:39 +0000 (01:43 +0000)
+ continue implementing support for threading demo by adding mutex
  for delwin().

NEWS
dist.mk
ncurses/base/lib_delwin.c
ncurses/base/lib_freeall.c
ncurses/base/lib_newwin.c
ncurses/base/resizeterm.c
ncurses/base/wresize.c
ncurses/curses.priv.h
test/worm.c

diff --git a/NEWS b/NEWS
index b3519209aa8c5bdc25766f4014401df44bb1bcfe..5965909102f58936f5094fbef838bf78119d5885 100644 (file)
--- 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 7d02e7142f51aaf94dd159201a1e0986530260ac..a29dd36ec56b808fe91daf6756f323ed37f92a91 100644 (file)
--- 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)
index e16f7878b6ce93649cbe2bf6f6d087bef00e3218..fc68f9d68deeef6f3f7d1065e0151947ceb53a9f 100644 (file)
@@ -40,7 +40,7 @@
 
 #include <curses.priv.h>
 
-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);
 }
index 0fc86239c836970da256bc8cf2029ff831f1287f..dbf0483f24016d8f4532077f8f1396d18449a2f5 100644 (file)
@@ -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);
index 3f7275c110303f1f04f796f29c65328b5e6af564..b0f4603ae7aba1a6b72a40013a83518601d08cd8 100644 (file)
@@ -41,7 +41,7 @@
 
 #include <curses.priv.h>
 
-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);
 }
index 02057b18f0e9f4bae52afbdea046f536938c5aab..8bea743a3d22552b0ea39441e6f2c37334291609 100644 (file)
@@ -41,7 +41,7 @@
 #include <curses.priv.h>
 #include <term.h>
 
-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);
 }
 
index ae62806e02fc355598827f6a0e8979692721e165..f756f0f237f777c303655a46c67bf0a4bf914867 100644 (file)
@@ -32,7 +32,7 @@
 
 #include <curses.priv.h>
 
-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);
 }
 
 /*
index 57fd2409aae9ed13a2655fadf0bca4632590275a..54ffc8ec49a580fd8e573d0ee1c7fbce79159834 100644 (file)
@@ -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 <pthread.h>
 #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
index 534e626e23b8b8e945201ae8edf1bcb4dd7f91e2..61d97a9a404e866a774ee2671b23803d33de9b3a 100644 (file)
@@ -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 <test.priv.h>
@@ -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);
 }