+ continue implementing support for threading demo by adding mutex
for delwin().
-- sale, use or other dealings in this Software without prior written --
-- authorization. --
-------------------------------------------------------------------------------
-- 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
-------------------------------------------------------------------------------
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.
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).
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. #
##############################################################################
# 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
# 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
# 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)
# We don't append the patch to the version, since this only applies to releases
VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
-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)
static bool
cannot_delete(WINDOW *win)
T((T_CALLED("delwin(%p)"), 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);
extern int malloc_errfd; /* FIXME */
#endif
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
/*
* Free all ncurses data. This is used for testing only (there's no practical
+ _nc_lock_global(windowlist);
+
while (_nc_windows != 0) {
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;
/* Delete only windows that're not a parent */
for (p = _nc_windows; p != 0; p = p->next) {
bool found = FALSE;
+ if (delwin(&(p->win)) != ERR)
+ deleted = TRUE;
+
+ /*
+ * Don't continue to loop if the list is trashed.
+ */
+ if (!deleted)
+ break;
+ _nc_unlock_global(windowlist);
}
if (cur_term != 0)
del_curterm(cur_term);
}
if (cur_term != 0)
del_curterm(cur_term);
-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)
static WINDOW *
remove_window_from_screen(WINDOW *win)
+ T((T_CALLED("_nc_freewin(%p)"), win));
+
- 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);
}
NCURSES_EXPORT(WINDOW *)
}
NCURSES_EXPORT(WINDOW *)
+ _nc_lock_global(windowlist);
+
win->_curx = 0;
win->_cury = 0;
win->_maxy = num_lines - 1;
win->_curx = 0;
win->_cury = 0;
win->_maxy = num_lines - 1;
T((T_CREATE("window %p"), win));
T((T_CREATE("window %p"), win));
+ _nc_unlock_global(windowlist);
#include <curses.priv.h>
#include <term.h>
#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)
#define stolen_lines (screen_lines - SP->_lines_avail)
+ _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) {
_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);
}
(long) wp->win._begy,
(long) wp->win._begx);
}
+ _nc_unlock_global(windowlist);
if (SP == 0) {
returnCode(ERR);
}
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;
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);
SET_LINES(ToLines - was_stolen);
SET_COLS(ToCols);
+ _nc_unlock_global(windowlist);
+
-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)
static int
cleanup_lines(struct ldat *data, int length)
struct ldat *pline = cmp->_line;
int row;
struct ldat *pline = cmp->_line;
int row;
+ _nc_lock_global(windowlist);
+
for (wp = _nc_windows; wp != 0; wp = wp->next) {
WINDOW *tst = &(wp->win);
for (wp = _nc_windows; wp != 0; wp = wp->next) {
WINDOW *tst = &(wp->win);
repair_subwindows(tst);
}
}
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 $
#define SET_COLS(value) COLS = value
#endif
#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)
#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 *);
#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 */
#endif
#else
#define _nc_lock_global(name) /* nothing */
+#define _nc_try_global(name) 0
#define _nc_unlock_global(name) /* nothing */
#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
#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.
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>
*/
#include <test.priv.h>
+static bool quitting = FALSE;
+
static WORM worm[40];
static short **refs;
static WORM worm[40];
static short **refs;
#endif
#ifdef USE_PTHREADS
#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)
{
static void *
start_worm(void *arg)
{
- for (;;) {
- napms(20);
use_window(stdscr, draw_worm, arg);
}
return NULL;
use_window(stdscr, draw_worm, arg);
}
return NULL;
* normal operation -T.Dickey
*/
if (ch == 'q') {
* normal operation -T.Dickey
*/
if (ch == 'q') {
done = TRUE;
continue;
} else if (ch == 's') {
done = TRUE;
continue;
} else if (ch == 's') {
free(w->xpos);
free(w->ypos);
}
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);
}
#endif
ExitProgram(EXIT_SUCCESS);
}