2004-01-04 23:36:49 +00:00
|
|
|
|
/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2004 Free Software Foundation, Inc.
|
2000-04-04 20:07:11 +00:00
|
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2000-04-04 20:07:11 +00:00
|
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
1996-07-25 22:56:11 +00:00
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
* Lesser General Public License for more details.
|
2000-04-04 20:07:11 +00:00
|
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
*/
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2003-03-25 23:52:33 +00:00
|
|
|
|
#if HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
#include <signal.h>
|
2000-04-21 14:16:44 +00:00
|
|
|
|
#include "libguile/_scm.h"
|
|
|
|
|
|
#include "libguile/eval.h"
|
|
|
|
|
|
#include "libguile/throw.h"
|
|
|
|
|
|
#include "libguile/root.h"
|
|
|
|
|
|
#include "libguile/smob.h"
|
2002-01-22 23:31:39 +00:00
|
|
|
|
#include "libguile/lang.h"
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
#include "libguile/dynwind.h"
|
2002-10-04 13:49:13 +00:00
|
|
|
|
#include "libguile/deprecation.h"
|
C files should #include only the header files they need, not
libguile.h (which #includes all the header files); the pointless
recompilation was wasting my time.
* Makefile.in (all .o dependency lists): Regenerated.
* libguile.h: Don't try to get a definition for size_t here...
* __scm.h: Do it here.
* _scm.h: Since this is the internal libguile header, put things
here that all (or a majority) of the libguile files will want.
Don't #include <libguile.h> here; that generates dependencies on
way too much. Instead, get "__scm.h", "error.h", "pairs.h",
"list.h", "gc.h", "gsubr.h", "procs.h", "numbers.h", "symbols.h",
"boolean.h", "strings.h", "vectors.h", "root.h", "ports.h", and
"async.h".
* alist.c: Get "eq.h", "list.h", "alist.h".
* append.c: Get "append.h", "list.h".
* arbiters.c: Get "arbiters.h", "smob.h".
* async.c: Get "async.h", "smob.h", "throw.h", "eval.h".
* boolean.c: Get "boolean.h".
* chars.c: Get "chars.h".
* continuations.c: Get "continuations.h", "dynwind.h", "debug.h",
"stackchk.h".
* debug.c: Get "debug.h", "feature.h", "read.h", "strports.h",
"continuations.h", "alist.h", "srcprop.h", "procprop.h", "smob.h",
"genio.h", "throw.h", "eval.h".
* dynwind.c: Get "dynwind.h", "alist.h", "eval.h".
* eq.c: Get "eq.h", "unif.h", "smob.h", "strorder.h",
"stackchk.h".
* error.c: Get "error.h", "throw.h", "genio.h", "pairs.h".
* eval.c: Get "eval.h", "stackchk.h", "srcprop.h", "debug.h",
"hashtab.h", "procprop.h", "markers.h", "smob.h", "throw.h",
"continuations.h", "eq.h", "sequences.h", "alist.h", "append.h",
"debug.h".
* fdsocket.c: Get "fdsocket.h", "unif.h", "filesys.h".
* feature.c: Get "feature.h".
* files.c: Get "files.h".
* filesys.c: Get "filesys.h", "smob.h", "genio.h".
* fports.c: Get "fports.h", "markers.h".
* gc.c: Get "async.h", "unif.h", "smob.h", "weaks.h",
"genio.h", "struct.h", "stackchk.h", "stime.h".
* gdbint.c: Get "gdbint.h", "chars.h", "eval.h", "print.h",
"read.h", "strports.h", "tag.h".
* genio.c: Get "genio.h", "chars.h".
* gsubr.c: Get "gsubr.h", "genio.h".
* hash.c: Get "hash.h", "chars.h".
* hashtab.c: Get "hashtab.h", "eval.h", "hash.h", "alist.h".
* init.c: Get everyone who has an scm_init_mumble function:
"weaks.h", "vports.h", "version.h", "vectors.h", "variable.h",
"unif.h", "throw.h", "tag.h", "symbols.h", "struct.h",
"strports.h", "strorder.h", "strop.h", "strings.h", "stime.h",
"stackchk.h", "srcprop.h", "socket.h", "simpos.h", "sequences.h",
"scmsigs.h", "read.h", "ramap.h", "procs.h", "procprop.h",
"print.h", "posix.h", "ports.h", "pairs.h", "options.h",
"objprop.h", "numbers.h", "mbstrings.h", "mallocs.h", "load.h",
"list.h", "kw.h", "ioext.h", "hashtab.h", "hash.h", "gsubr.h",
"gdbint.h", "gc.h", "fports.h", "filesys.h", "files.h",
"feature.h", "fdsocket.h", "eval.h", "error.h", "eq.h",
"dynwind.h", "debug.h", "continuations.h", "chars.h", "boolean.h",
"async.h", "arbiters.h", "append.h", "alist.h".
* ioext.c: Get "ioext.h", "fports.h".
* kw.c: Get "kw.h", "smob.h", "mbstrings.h", "genio.h".
* list.c: Get "list.h", "eq.h".
* load.c: Get "load.h", "eval.h", "read.h", "fports.h".
* mallocs.c: Get "smob.h", "genio.h".
* markers.c: Get "markers.h".
* mbstrings.c: Get "mbstrings.h", "read.h", "genio.h", "unif.h",
"chars.h".
* numbers.c: Get "unif.h", "genio.h".
* objprop.c: Get "objprop.h", "weaks.h", "alist.h", "hashtab.h".
* options.c: Get "options.h".
* ports.c: Get "ports.h", "vports.h", "strports.h", "fports.h",
"markers.h", "chars.h", "genio.h".
* posix.c: Get "posix.h", "sequences.h", "feature.h", "unif.h",
"read.h", "scmsigs.h", "genio.h", "fports.h".
* print.c: Get "print.h", "unif.h", "weaks.h", "read.h",
"procprop.h", "eval.h", "smob.h", "mbstrings.h", "genio.h",
"chars.h".
* procprop.c: Get "procprop.h", "eval.h", "alist.h".
* procs.c: Get "procs.h".
* ramap.c: Get "ramap.h", "feature.h", "eval.h", "eq.h",
"chars.h", "smob.h", "unif.h".
* read.c: Get "alist.h", "kw.h", "mbstrings.h", "unif.h",
"eval.h", "genio.h", "chars.h".
* root.c: Get "root.h", "stackchk.h".
* scmsigs.c: Get "scmsigs.h".
* sequences.c: Get "sequences.h".
* simpos.c: Get "simpos.h", "scmsigs.h".
* smob.c: Get "smob.h".
* socket.c: Get "socket.h", "feature.h".
* srcprop.c: Get "srcprop.h", "weaks.h", "hashtab.h", "debug.h",
"alist.h", "smob.h".
* stackchk.c: Get "stackchk.h", "genio.h".
* stime.c: Get "stime.h"."libguile/continuations.h".
* strings.c: Get "strings.h", "chars.h".
* strop.c: Get "strop.h", "chars.h".
* strorder.c: Get "strorder.h", "chars.h".
* strports.c: Get "strports.h", "print.h", "eval.h", "unif.h".
* struct.c: Get "struct.h", "chars.h".
* symbols.c: Get "symbols.h", "mbstrings.h", "alist.h",
"variable.h", "eval.h", "chars.h".
* tag.c: Get "tag.h", "struct.h", "chars.h".
* throw.c: Get "throw.h", "continuations.h", "debug.h",
"dynwind.h", "eval.h", "alist.h", "smob.h", "genio.h".
* unif.c: Get "unif.h", "feature.h", "strop.h", "sequences.h",
"smob.h", "genio.h", "eval.h", "chars.h".
* variable.c: Get "variable.h", "smob.h", "genio.h".
* vectors.c: Get "vectors.h", "eq.h".
* version.c: Get "version.h".
* vports.c: Get "vports.h", "fports.h", "chars.h", "eval.h".
* weaks.c: Get "weaks.h".
1996-09-10 02:26:07 +00:00
|
|
|
|
|
2000-04-21 14:16:44 +00:00
|
|
|
|
#include "libguile/validate.h"
|
|
|
|
|
|
#include "libguile/async.h"
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
1996-08-07 09:46:41 +00:00
|
|
|
|
#ifdef HAVE_STRING_H
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
#endif
|
1996-07-25 22:56:11 +00:00
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* {Asynchronous Events}
|
|
|
|
|
|
*
|
2002-10-04 13:49:13 +00:00
|
|
|
|
* There are two kinds of asyncs: system asyncs and user asyncs. The
|
|
|
|
|
|
* two kinds have some concepts in commen but work slightly
|
|
|
|
|
|
* differently and are not interchangeable.
|
1996-07-25 22:56:11 +00:00
|
|
|
|
*
|
2002-10-04 13:49:13 +00:00
|
|
|
|
* System asyncs are used to run arbitrary code at the next safe point
|
|
|
|
|
|
* in a specified thread. You can use them to trigger execution of
|
|
|
|
|
|
* Scheme code from signal handlers or to interrupt a thread, for
|
|
|
|
|
|
* example.
|
1996-07-25 22:56:11 +00:00
|
|
|
|
*
|
2002-10-04 13:49:13 +00:00
|
|
|
|
* Each thread has a list of 'activated asyncs', which is a normal
|
|
|
|
|
|
* Scheme list of procedures with zero arguments. When a thread
|
|
|
|
|
|
* executes a SCM_ASYNC_TICK statement (which is included in
|
|
|
|
|
|
* SCM_TICK), it will call all procedures on this list.
|
2000-04-04 20:07:11 +00:00
|
|
|
|
*
|
2002-10-04 13:49:13 +00:00
|
|
|
|
* Also, a thread will wake up when a procedure is added to its list
|
|
|
|
|
|
* of active asyncs and call them. After that, it will go to sleep
|
|
|
|
|
|
* again. (Not implemented yet.)
|
1996-07-25 22:56:11 +00:00
|
|
|
|
*
|
|
|
|
|
|
*
|
2002-10-04 13:49:13 +00:00
|
|
|
|
* User asyncs are a little data structure that consists of a
|
|
|
|
|
|
* procedure of zero arguments and a mark. There are functions for
|
|
|
|
|
|
* setting the mark of a user async and for calling all procedures of
|
|
|
|
|
|
* marked asyncs in a given list. Nothing you couldn't quickly
|
|
|
|
|
|
* implement yourself.
|
1996-07-25 22:56:11 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
/* User asyncs. */
|
2000-04-05 15:28:28 +00:00
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
static scm_t_bits tc16_async;
|
2000-04-05 15:28:28 +00:00
|
|
|
|
|
|
|
|
|
|
/* cmm: this has SCM_ prefix because SCM_MAKE_VALIDATE expects it.
|
|
|
|
|
|
this is ugly. */
|
2000-12-08 17:32:56 +00:00
|
|
|
|
#define SCM_ASYNCP(X) SCM_TYP16_PREDICATE (tc16_async, X)
|
2002-10-20 22:59:01 +00:00
|
|
|
|
#define VALIDATE_ASYNC(pos, a) SCM_MAKE_VALIDATE_MSG(pos, a, ASYNCP, "user async")
|
2000-04-05 15:28:28 +00:00
|
|
|
|
|
|
|
|
|
|
#define ASYNC_GOT_IT(X) (SCM_CELL_WORD_0 (X) >> 16)
|
2000-10-25 11:01:03 +00:00
|
|
|
|
#define SET_ASYNC_GOT_IT(X, V) (SCM_SET_CELL_WORD_0 ((X), SCM_TYP16 (X) | ((V) << 16)))
|
2000-04-05 15:28:28 +00:00
|
|
|
|
#define ASYNC_THUNK(X) SCM_CELL_OBJECT_1 (X)
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
static SCM
|
2002-10-04 13:49:13 +00:00
|
|
|
|
async_gc_mark (SCM obj)
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2000-04-05 15:28:28 +00:00
|
|
|
|
return ASYNC_THUNK (obj);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2000-04-04 20:07:11 +00:00
|
|
|
|
SCM_DEFINE (scm_async, "async", 1, 0, 0,
|
2001-02-16 15:22:58 +00:00
|
|
|
|
(SCM thunk),
|
|
|
|
|
|
"Create a new async for the procedure @var{thunk}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_async
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2000-04-05 15:28:28 +00:00
|
|
|
|
SCM_RETURN_NEWSMOB (tc16_async, SCM_UNPACK (thunk));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2000-04-04 20:07:11 +00:00
|
|
|
|
SCM_DEFINE (scm_async_mark, "async-mark", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM a),
|
2001-02-16 15:22:58 +00:00
|
|
|
|
"Mark the async @var{a} for future execution.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_async_mark
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2000-04-05 15:28:28 +00:00
|
|
|
|
VALIDATE_ASYNC (1, a);
|
|
|
|
|
|
SET_ASYNC_GOT_IT (a, 1);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2000-04-04 20:07:11 +00:00
|
|
|
|
SCM_DEFINE (scm_run_asyncs, "run-asyncs", 1, 0, 0,
|
2001-02-16 15:22:58 +00:00
|
|
|
|
(SCM list_of_a),
|
|
|
|
|
|
"Execute all thunks from the asyncs of the list @var{list_of_a}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_run_asyncs
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-01-22 23:31:39 +00:00
|
|
|
|
while (! SCM_NULL_OR_NIL_P (list_of_a))
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
|
|
|
|
|
SCM a;
|
2000-03-21 23:14:31 +00:00
|
|
|
|
SCM_VALIDATE_CONS (1, list_of_a);
|
1999-12-12 02:36:16 +00:00
|
|
|
|
a = SCM_CAR (list_of_a);
|
2000-04-05 15:28:28 +00:00
|
|
|
|
VALIDATE_ASYNC (SCM_ARG1, a);
|
|
|
|
|
|
if (ASYNC_GOT_IT (a))
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2000-04-05 15:28:28 +00:00
|
|
|
|
SET_ASYNC_GOT_IT (a, 0);
|
2001-06-26 15:46:40 +00:00
|
|
|
|
scm_call_0 (ASYNC_THUNK (a));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
list_of_a = SCM_CDR (list_of_a);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
/* System asyncs. */
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
void
|
|
|
|
|
|
scm_async_click ()
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-10-27 20:22:01 +00:00
|
|
|
|
/* Reset pending_asyncs even when asyncs are blocked and not really
|
|
|
|
|
|
executed.
|
|
|
|
|
|
*/
|
2002-10-04 13:49:13 +00:00
|
|
|
|
|
2002-10-27 20:22:01 +00:00
|
|
|
|
scm_root->pending_asyncs = 0;
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
if (scm_root->block_asyncs == 0)
|
2002-10-04 13:49:13 +00:00
|
|
|
|
{
|
2002-10-27 20:22:01 +00:00
|
|
|
|
SCM asyncs;
|
2004-09-22 17:41:37 +00:00
|
|
|
|
while (!scm_is_null(asyncs = scm_root->active_asyncs))
|
2002-10-04 13:49:13 +00:00
|
|
|
|
{
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
scm_root->active_asyncs = SCM_EOL;
|
2002-10-04 13:49:13 +00:00
|
|
|
|
do
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_call_0 (SCM_CAR (asyncs));
|
2002-10-27 20:22:01 +00:00
|
|
|
|
asyncs = SCM_CDR (asyncs);
|
2002-10-04 13:49:13 +00:00
|
|
|
|
}
|
2004-09-22 17:41:37 +00:00
|
|
|
|
while (!scm_is_null(asyncs));
|
2002-10-04 13:49:13 +00:00
|
|
|
|
}
|
2004-09-22 17:41:37 +00:00
|
|
|
|
for (asyncs = scm_root->signal_asyncs; !scm_is_null(asyncs);
|
2002-10-27 20:22:01 +00:00
|
|
|
|
asyncs = SCM_CDR (asyncs))
|
|
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
|
if (scm_is_true (SCM_CAR (asyncs)))
|
2002-10-27 20:22:01 +00:00
|
|
|
|
{
|
|
|
|
|
|
SCM proc = SCM_CAR (asyncs);
|
|
|
|
|
|
SCM_SETCAR (asyncs, SCM_BOOL_F);
|
|
|
|
|
|
scm_call_0 (proc);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2002-10-04 13:49:13 +00:00
|
|
|
|
}
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2002-10-19 08:22:50 +00:00
|
|
|
|
#if (SCM_ENABLE_DEPRECATED == 1)
|
|
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
SCM_DEFINE (scm_system_async, "system-async", 1, 0, 0,
|
|
|
|
|
|
(SCM thunk),
|
|
|
|
|
|
"This function is deprecated. You can use @var{thunk} directly\n"
|
2002-10-19 08:22:50 +00:00
|
|
|
|
"instead of explicitely creating an async object.\n")
|
2002-10-04 13:49:13 +00:00
|
|
|
|
#define FUNC_NAME s_scm_system_async
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_c_issue_deprecation_warning
|
|
|
|
|
|
("'system-async' is deprecated. "
|
|
|
|
|
|
"Use the procedure directly with 'system-async-mark'.");
|
|
|
|
|
|
return thunk;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2002-10-19 08:22:50 +00:00
|
|
|
|
#endif /* SCM_ENABLE_DEPRECATED == 1 */
|
|
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
void
|
|
|
|
|
|
scm_i_queue_async_cell (SCM c, scm_root_state *root)
|
|
|
|
|
|
{
|
2002-10-27 20:22:01 +00:00
|
|
|
|
SCM p = root->active_asyncs;
|
|
|
|
|
|
SCM_SETCDR (c, SCM_EOL);
|
|
|
|
|
|
if (p == SCM_EOL)
|
|
|
|
|
|
root->active_asyncs = c;
|
|
|
|
|
|
else
|
2002-10-04 13:49:13 +00:00
|
|
|
|
{
|
2002-10-27 20:22:01 +00:00
|
|
|
|
SCM pp;
|
|
|
|
|
|
while ((pp = SCM_CDR(p)) != SCM_EOL)
|
2002-10-05 13:06:58 +00:00
|
|
|
|
{
|
2002-10-27 20:22:01 +00:00
|
|
|
|
if (SCM_CAR (p) == SCM_CAR (c))
|
|
|
|
|
|
return;
|
|
|
|
|
|
p = pp;
|
2002-10-05 13:06:58 +00:00
|
|
|
|
}
|
2002-10-27 20:22:01 +00:00
|
|
|
|
SCM_SETCDR (p, c);
|
2002-10-04 13:49:13 +00:00
|
|
|
|
}
|
2002-10-27 20:22:01 +00:00
|
|
|
|
root->pending_asyncs = 1;
|
2002-10-04 13:49:13 +00:00
|
|
|
|
}
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
SCM_DEFINE (scm_system_async_mark_for_thread, "system-async-mark", 1, 1, 0,
|
|
|
|
|
|
(SCM proc, SCM thread),
|
2002-10-19 16:33:25 +00:00
|
|
|
|
"Mark @var{proc} (a procedure with zero arguments) for future execution\n"
|
|
|
|
|
|
"in @var{thread}. If @var{proc} has already been marked for\n"
|
|
|
|
|
|
"@var{thread} but has not been executed yet, this call has no effect.\n"
|
|
|
|
|
|
"If @var{thread} is omitted, the thread that called\n"
|
|
|
|
|
|
"@code{system-async-mark} is used.\n\n"
|
|
|
|
|
|
"This procedure is not safe to be called from C signal handlers. Use\n"
|
|
|
|
|
|
"@code{scm_sigaction} or @code{scm_sigaction_for_thread} to install\n"
|
|
|
|
|
|
"signal handlers.")
|
2002-10-04 13:49:13 +00:00
|
|
|
|
#define FUNC_NAME s_scm_system_async_mark_for_thread
|
|
|
|
|
|
{
|
2002-10-16 16:27:46 +00:00
|
|
|
|
if (SCM_UNBNDP (thread))
|
|
|
|
|
|
thread = scm_current_thread ();
|
|
|
|
|
|
else
|
2002-10-27 20:22:01 +00:00
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_THREAD (2, thread);
|
|
|
|
|
|
if (scm_c_thread_exited_p (thread))
|
|
|
|
|
|
SCM_MISC_ERROR ("thread has already exited", SCM_EOL);
|
|
|
|
|
|
}
|
2002-10-05 13:06:58 +00:00
|
|
|
|
scm_i_queue_async_cell (scm_cons (proc, SCM_BOOL_F),
|
2002-10-16 16:27:46 +00:00
|
|
|
|
scm_i_thread_root (thread));
|
2002-10-04 13:49:13 +00:00
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
2000-03-21 23:14:31 +00:00
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_system_async_mark (SCM proc)
|
|
|
|
|
|
#define FUNC_NAME s_scm_system_async_mark_for_thread
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-10-04 13:49:13 +00:00
|
|
|
|
return scm_system_async_mark_for_thread (proc, SCM_UNDEFINED);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-10-04 13:49:13 +00:00
|
|
|
|
SCM_DEFINE (scm_noop, "noop", 0, 0, 1,
|
|
|
|
|
|
(SCM args),
|
|
|
|
|
|
"Do nothing. When called without arguments, return @code{#f},\n"
|
|
|
|
|
|
"otherwise return the first argument.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_noop
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-10-04 13:49:13 +00:00
|
|
|
|
SCM_VALIDATE_REST_ARGUMENT (args);
|
|
|
|
|
|
return (SCM_NULL_OR_NIL_P (args) ? SCM_BOOL_F : SCM_CAR (args));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-10-19 08:22:50 +00:00
|
|
|
|
#if (SCM_ENABLE_DEPRECATED == 1)
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
|
2000-04-04 20:07:11 +00:00
|
|
|
|
SCM_DEFINE (scm_unmask_signals, "unmask-signals", 0, 0, 0,
|
2001-02-16 15:22:58 +00:00
|
|
|
|
(),
|
|
|
|
|
|
"Unmask signals. The returned value is not specified.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_unmask_signals
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
scm_c_issue_deprecation_warning
|
|
|
|
|
|
("'unmask-signals' is deprecated. "
|
|
|
|
|
|
"Use 'call-with-blocked-asyncs' instead.");
|
|
|
|
|
|
|
|
|
|
|
|
if (scm_root->block_asyncs == 0)
|
|
|
|
|
|
SCM_MISC_ERROR ("signals already unmasked", SCM_EOL);
|
|
|
|
|
|
scm_root->block_asyncs = 0;
|
2002-10-27 20:22:01 +00:00
|
|
|
|
scm_async_click ();
|
1996-07-25 22:56:11 +00:00
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-04-04 20:07:11 +00:00
|
|
|
|
SCM_DEFINE (scm_mask_signals, "mask-signals", 0, 0, 0,
|
2001-02-16 15:22:58 +00:00
|
|
|
|
(),
|
|
|
|
|
|
"Mask signals. The returned value is not specified.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_mask_signals
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
scm_c_issue_deprecation_warning
|
|
|
|
|
|
("'mask-signals' is deprecated. Use 'call-with-blocked-asyncs' instead.");
|
|
|
|
|
|
|
|
|
|
|
|
if (scm_root->block_asyncs > 0)
|
|
|
|
|
|
SCM_MISC_ERROR ("signals already masked", SCM_EOL);
|
|
|
|
|
|
scm_root->block_asyncs = 1;
|
1996-07-25 22:56:11 +00:00
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2002-10-19 08:22:50 +00:00
|
|
|
|
#endif /* SCM_ENABLE_DEPRECATED == 1 */
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
increase_block (void *unused)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_root->block_asyncs++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
decrease_block (void *unused)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_root->block_asyncs--;
|
2002-10-27 20:22:01 +00:00
|
|
|
|
if (scm_root->block_asyncs == 0)
|
|
|
|
|
|
scm_async_click ();
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_call_with_blocked_asyncs, "call-with-blocked-asyncs", 1, 0, 0,
|
|
|
|
|
|
(SCM proc),
|
|
|
|
|
|
"Call @var{proc} with no arguments and block the execution\n"
|
|
|
|
|
|
"of system asyncs by one level for the current thread while\n"
|
|
|
|
|
|
"it is running. Return the value returned by @var{proc}.\n")
|
|
|
|
|
|
#define FUNC_NAME s_scm_call_with_blocked_asyncs
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_internal_dynamic_wind (increase_block,
|
|
|
|
|
|
(scm_t_inner) scm_call_0,
|
|
|
|
|
|
decrease_block,
|
2002-10-27 20:22:01 +00:00
|
|
|
|
(void *)proc, NULL);
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
|
scm_c_call_with_blocked_asyncs (void *(*proc) (void *data), void *data)
|
|
|
|
|
|
{
|
2002-10-27 20:22:01 +00:00
|
|
|
|
return (void *)scm_internal_dynamic_wind (increase_block,
|
|
|
|
|
|
(scm_t_inner) proc,
|
|
|
|
|
|
decrease_block,
|
|
|
|
|
|
data, NULL);
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_call_with_unblocked_asyncs, "call-with-unblocked-asyncs", 1, 0, 0,
|
|
|
|
|
|
(SCM proc),
|
|
|
|
|
|
"Call @var{proc} with no arguments and unblock the execution\n"
|
|
|
|
|
|
"of system asyncs by one level for the current thread while\n"
|
|
|
|
|
|
"it is running. Return the value returned by @var{proc}.\n")
|
|
|
|
|
|
#define FUNC_NAME s_scm_call_with_unblocked_asyncs
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_root->block_asyncs == 0)
|
|
|
|
|
|
SCM_MISC_ERROR ("asyncs already unblocked", SCM_EOL);
|
|
|
|
|
|
return scm_internal_dynamic_wind (decrease_block,
|
|
|
|
|
|
(scm_t_inner) scm_call_0,
|
|
|
|
|
|
increase_block,
|
2002-10-27 20:22:01 +00:00
|
|
|
|
(void *)proc, NULL);
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
|
scm_c_call_with_unblocked_asyncs (void *(*proc) (void *data), void *data)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_root->block_asyncs == 0)
|
|
|
|
|
|
scm_misc_error ("scm_c_call_with_unblocked_asyncs",
|
|
|
|
|
|
"asyncs already unblocked", SCM_EOL);
|
2002-10-27 20:22:01 +00:00
|
|
|
|
return (void *)scm_internal_dynamic_wind (decrease_block,
|
|
|
|
|
|
(scm_t_inner) proc,
|
|
|
|
|
|
increase_block,
|
|
|
|
|
|
data, NULL);
|
* async.h (scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New prototypes.
(scm_mask_signals, scm_unmask_signals): Deprecated.
(scm_mask_ints): Turned into a macro.
* async.c (scm_mask_ints): Removed.
(scm_run_asyncs): Do not set scm_mask_ints while running an async.
this should not be necessary.
(scm_async_click): Test block_asyncs instead of scm_mask_ints.
(scm_mask_signals, scm_unmask_signals): Deprecated. Emit
deprecation warning and check for errornous use. Set block_asyncs
instead of scm_mask_ints.
(increase_block, decrease_block, scm_call_with_blocked_asyncs,
scm_call_with_unblocked_asyncs, scm_c_call_with_blocked_asyncs,
scm_c_call_with_unblocked_asyncs): New.
2002-10-09 22:44:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-01-04 23:36:49 +00:00
|
|
|
|
void
|
2004-01-07 18:03:18 +00:00
|
|
|
|
scm_frame_block_asyncs ()
|
2004-01-04 23:36:49 +00:00
|
|
|
|
{
|
2004-01-11 00:51:19 +00:00
|
|
|
|
scm_frame_rewind_handler (increase_block, NULL, SCM_F_WIND_EXPLICITLY);
|
|
|
|
|
|
scm_frame_unwind_handler (decrease_block, NULL, SCM_F_WIND_EXPLICITLY);
|
2004-01-04 23:36:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2004-01-07 18:03:18 +00:00
|
|
|
|
scm_frame_unblock_asyncs ()
|
2004-01-04 23:36:49 +00:00
|
|
|
|
{
|
|
|
|
|
|
if (scm_root->block_asyncs == 0)
|
|
|
|
|
|
scm_misc_error ("scm_with_unblocked_asyncs",
|
|
|
|
|
|
"asyncs already unblocked", SCM_EOL);
|
2004-01-11 00:51:19 +00:00
|
|
|
|
scm_frame_rewind_handler (decrease_block, NULL, SCM_F_WIND_EXPLICITLY);
|
|
|
|
|
|
scm_frame_unwind_handler (increase_block, NULL, SCM_F_WIND_EXPLICITLY);
|
2004-01-04 23:36:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_init_async ()
|
|
|
|
|
|
{
|
2000-06-28 10:26:52 +00:00
|
|
|
|
scm_asyncs = SCM_EOL;
|
2000-06-27 16:00:01 +00:00
|
|
|
|
tc16_async = scm_make_smob_type ("async", 0);
|
2002-10-04 13:49:13 +00:00
|
|
|
|
scm_set_smob_mark (tc16_async, async_gc_mark);
|
2000-06-27 16:00:01 +00:00
|
|
|
|
|
2000-04-21 14:16:44 +00:00
|
|
|
|
#include "libguile/async.x"
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
2000-03-19 19:01:16 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Local Variables:
|
|
|
|
|
|
c-file-style: "gnu"
|
|
|
|
|
|
End:
|
|
|
|
|
|
*/
|