-- 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
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).
# 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
# 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)
#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)
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);
}
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
}
#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;
}
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);
#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)
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 *)
returnWin(0);
}
+ _nc_lock_global(windowlist);
+
win->_curx = 0;
win->_cury = 0;
win->_maxy = num_lines - 1;
T((T_CREATE("window %p"), win));
+ _nc_unlock_global(windowlist);
returnWin(win);
}
#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)
{
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) {
(long) wp->win._begy,
(long) wp->win._begx);
}
+ _nc_unlock_global(windowlist);
}
#endif
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;
SET_LINES(ToLines - was_stolen);
SET_COLS(ToCols);
+ _nc_unlock_global(windowlist);
+
returnCode(result);
}
#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)
struct ldat *pline = cmp->_line;
int row;
+ _nc_lock_global(windowlist);
+
for (wp = _nc_windows; wp != 0; wp = wp->next) {
WINDOW *tst = &(wp->win);
repair_subwindows(tst);
}
}
+ _nc_unlock_global(windowlist);
}
/*
/*
- * $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
*
#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 *);
#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
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>
#endif
} WORM;
+static bool quitting = FALSE;
+
static WORM worm[40];
static short **refs;
#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;
* normal operation -T.Dickey
*/
if (ch == 'q') {
+ quitting = TRUE;
done = TRUE;
continue;
} else if (ch == 's') {
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);
}