summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/ceval.h72
-rw-r--r--Include/eval.h27
-rw-r--r--Modules/cdmodule.c1
-rw-r--r--Modules/cgen.py4
-rw-r--r--Modules/flmodule.c4
-rw-r--r--Modules/posixmodule.c67
-rw-r--r--Modules/selectmodule.c3
-rw-r--r--Modules/socketmodule.c110
-rw-r--r--Modules/stdwinmodule.c36
-rw-r--r--Modules/threadmodule.c16
-rw-r--r--Modules/timemodule.c42
-rw-r--r--Objects/fileobject.c59
-rw-r--r--Objects/listobject.c3
-rw-r--r--Python/bltinmodule.c7
-rw-r--r--Python/ceval.c35
-rw-r--r--Python/import.c2
-rw-r--r--Python/pythonmain.c2
-rw-r--r--Python/pythonrun.c34
-rw-r--r--Python/thread.c8
19 files changed, 382 insertions, 150 deletions
diff --git a/Include/ceval.h b/Include/ceval.h
index 2ddb7d0..d9708a2 100644
--- a/Include/ceval.h
+++ b/Include/ceval.h
@@ -22,10 +22,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
******************************************************************/
-/* Interface to execute compiled code */
-/* This header depends on "compile.h" */
-
-object *eval_code PROTO((codeobject *, object *, object *, object *));
+/* Interface to random parts in ceval.c */
object *call_object PROTO((object *, object *));
@@ -34,3 +31,70 @@ object *getlocals PROTO((void));
void printtraceback PROTO((FILE *));
void flushline PROTO((void));
+
+
+/* Interface for threads.
+
+ A module that plans to do a blocking system call (or something else
+ that lasts a long time and doesn't touch Python data) can allow other
+ threads to run as follows:
+
+ ...preparations here...
+ BGN_SAVE
+ ...blocking system call here...
+ END_SAVE
+ ...interpretr result here...
+
+ The BGN_SAVE/END_SAVE pair expands to a {}-surrounded block.
+ To leave the block in the middle (e.g., with return), you must insert
+ a line containing RET_SAVE before the return, e.g.
+
+ if (...premature_exit...) {
+ RET_SAVE
+ err_errno(IOError);
+ return NULL;
+ }
+
+ An alternative is:
+
+ RET_SAVE
+ if (...premature_exit...) {
+ err_errno(IOError);
+ return NULL;
+ }
+ RES_SAVE
+
+ For convenience, that the value of 'errno' is restored across
+ END_SAVE and RET_SAVE.
+
+ WARNING: NEVER NEST CALLS TO BGN_SAVE AND END_SAVE!!!
+
+ The function init_save_thread() should be called only from
+ initthread() in "threadmodule.c".
+
+ Note that not yet all candidates have been converted to use this
+ mechanism!
+*/
+
+extern void init_save_thread PROTO((void));
+extern void *save_thread PROTO((void));
+extern void restore_thread PROTO((void *));
+
+#ifdef USE_THREAD
+
+#define BGN_SAVE { \
+ void *_save; \
+ _save = save_thread();
+#define RET_SAVE restore_thread(_save);
+#define RES_SAVE _save = save_thread();
+#define END_SAVE restore_thread(_save); \
+ }
+
+#else /* !USE_THREAD */
+
+#define BGN_SAVE {
+#define RET_SAVE
+#define RES_SAVE
+#define END_SAVE }
+
+#endif /* !USE_THREAD */
diff --git a/Include/eval.h b/Include/eval.h
new file mode 100644
index 0000000..da4bbde
--- /dev/null
+++ b/Include/eval.h
@@ -0,0 +1,27 @@
+/***********************************************************
+Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
+Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Interface to execute compiled code */
+
+object *eval_code PROTO((codeobject *, object *, object *, object *));
diff --git a/Modules/cdmodule.c b/Modules/cdmodule.c
index 332b54b..04451a1 100644
--- a/Modules/cdmodule.c
+++ b/Modules/cdmodule.c
@@ -30,7 +30,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h"
#include "import.h"
#include "modsupport.h"
-#include "compile.h"
#include "ceval.h"
#define NCALLBACKS 8
diff --git a/Modules/cgen.py b/Modules/cgen.py
index d6e9c96..2775d3d 100644
--- a/Modules/cgen.py
+++ b/Modules/cgen.py
@@ -459,4 +459,8 @@ print
print 'initgl()'
print '{'
print '\tinitmodule("gl", gl_methods);'
+print '\t/* Initialize GL and don\'t go in the background */'
+print '\tforeground();'
+print '\tnoport();'
+print '\twinopen("");'
print '}'
diff --git a/Modules/flmodule.c b/Modules/flmodule.c
index d8c423c..bd5ff56 100644
--- a/Modules/flmodule.c
+++ b/Modules/flmodule.c
@@ -35,9 +35,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "import.h"
#include "modsupport.h"
#include "structmember.h"
-
-/* #include "ceval.h" */
-extern object *call_object(object *, object *);
+#include "ceval.h"
/* Generic Forms Objects */
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 8ae1758..367e21c 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -73,6 +73,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h"
#include "modsupport.h"
+#include "ceval.h"
extern char *strerror PROTO((int));
@@ -128,9 +129,13 @@ posix_1str(args, func)
int (*func) FPROTO((const char *));
{
char *path1;
+ int res;
if (!getstrarg(args, &path1))
return NULL;
- if ((*func)(path1) < 0)
+ BGN_SAVE
+ res = (*func)(path1);
+ END_SAVE
+ if (res < 0)
return posix_error();
INCREF(None);
return None;
@@ -142,9 +147,13 @@ posix_2str(args, func)
int (*func) FPROTO((const char *, const char *));
{
char *path1, *path2;
+ int res;
if (!getstrstrarg(args, &path1, &path2))
return NULL;
- if ((*func)(path1, path2) < 0)
+ BGN_SAVE
+ res = (*func)(path1, path2);
+ END_SAVE
+ if (res < 0)
return posix_error();
INCREF(None);
return None;
@@ -157,9 +166,13 @@ posix_strint(args, func)
{
char *path;
int i;
+ int res;
if (!getstrintarg(args, &path, &i))
return NULL;
- if ((*func)(path, i) < 0)
+ BGN_SAVE
+ res = (*func)(path, i);
+ END_SAVE
+ if (res < 0)
return posix_error();
INCREF(None);
return None;
@@ -174,9 +187,13 @@ posix_do_stat(self, args, statfunc)
struct stat st;
char *path;
object *v;
+ int res;
if (!getstrarg(args, &path))
return NULL;
- if ((*statfunc)(path, &st) != 0)
+ BGN_SAVE
+ res = (*statfunc)(path, &st);
+ END_SAVE
+ if (res != 0)
return posix_error();
v = newtupleobject(10);
if (v == NULL)
@@ -227,10 +244,14 @@ posix_getcwd(self, args)
object *args;
{
char buf[1026];
+ char *res;
extern char *getcwd PROTO((char *, int));
if (!getnoarg(args))
return NULL;
- if (getcwd(buf, sizeof buf) == NULL)
+ BGN_SAVE
+ res = getcwd(buf, sizeof buf);
+ END_SAVE
+ if (res == NULL)
return posix_error();
return newstringobject(buf);
}
@@ -284,10 +305,14 @@ posix_listdir(self, args)
struct direct *ep;
if (!getstrarg(args, &name))
return NULL;
- if ((dirp = opendir(name)) == NULL)
+ BGN_SAVE
+ if ((dirp = opendir(name)) == NULL) {
+ RET_SAVE
return posix_error();
+ }
if ((d = newlistobject(0)) == NULL) {
closedir(dirp);
+ RET_SAVE
return NULL;
}
while ((ep = readdir(dirp)) != NULL) {
@@ -306,6 +331,7 @@ posix_listdir(self, args)
DECREF(v);
}
closedir(dirp);
+ END_SAVE
#endif /* !MSDOS */
return d;
@@ -368,11 +394,13 @@ posix_system(self, args)
object *args;
{
char *command;
- int sts;
+ long sts;
if (!getstrarg(args, &command))
return NULL;
+ BGN_SAVE
sts = system(command);
- return newintobject((long)sts);
+ END_SAVE
+ return newintobject(sts);
}
#ifndef MSDOS
@@ -411,9 +439,13 @@ posix_uname(self, args)
extern int uname PROTO((struct utsname *));
struct utsname u;
object *v;
+ int res;
if (!getnoarg(args))
return NULL;
- if (uname(&u) < 0)
+ BGN_SAVE
+ res = uname(&u);
+ END_SAVE
+ if (res < 0)
return posix_error();
v = newtupleobject(5);
if (v == NULL)
@@ -443,6 +475,7 @@ posix_utime(self, args)
object *args;
{
char *path;
+ int res;
#ifdef UTIME_STRUCT
struct utimbuf buf;
@@ -459,7 +492,10 @@ posix_utime(self, args)
if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
return NULL;
- if (utime(path, UTIME_ARG) < 0)
+ BGN_SAVE
+ res = utime(path, UTIME_ARG);
+ END_SAVE
+ if (res < 0)
return posix_error();
INCREF(None);
return None;
@@ -648,7 +684,9 @@ posix_popen(self, args)
FILE *fp;
if (!getargs(args, "(ss)", &name, &mode))
return NULL;
+ BGN_SAVE
fp = popen(name, mode);
+ END_SAVE
if (fp == NULL)
return posix_error();
/* From now on, ignore SIGPIPE and let the error checking
@@ -664,8 +702,11 @@ posix_wait(self, args) /* Also waitpid() */
{
object *v;
int pid, sts;
- if (args == NULL)
+ if (args == NULL) {
+ BGN_SAVE
pid = wait(&sts);
+ END_SAVE
+ }
else {
#ifdef NO_WAITPID
err_setstr(PosixError,
@@ -674,7 +715,9 @@ posix_wait(self, args) /* Also waitpid() */
int options;
if (!getintintarg(args, &pid, &options))
return NULL;
+ BGN_SAVE
pid = waitpid(pid, &sts, options);
+ END_SAVE
#endif
}
if (pid == -1)
@@ -719,7 +762,9 @@ posix_readlink(self, args)
int n;
if (!getstrarg(args, &path))
return NULL;
+ BGN_SAVE
n = readlink(path, buf, (int) sizeof buf);
+ END_SAVE
if (n < 0)
return posix_error();
return newsizedstringobject(buf, n);
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 8afd208..3a5644b 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -26,7 +26,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h"
#include "modsupport.h"
-#include "compile.h"
#include "ceval.h"
#include "myselect.h"
@@ -154,7 +153,9 @@ select_select(self, args)
if ( omax > max ) max = omax;
if ( emax > max ) max = emax;
+ BGN_SAVE
n = select(max, &ifdset, &ofdset, &efdset, tvp);
+ END_SAVE
if ( n < 0 ) {
err_errno(SelectError);
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 839d46e..ab8c6b5 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -24,8 +24,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Socket module */
-/* XXX Ought to fix getStr*arg calls to use getargs(args, "s#", ...) */
-
/*
This module provides an interface to Berkeley socket IPC.
@@ -72,6 +70,7 @@ Socket methods:
#include "allobjects.h"
#include "modsupport.h"
+#include "ceval.h"
#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
@@ -171,7 +170,9 @@ setipaddr(name, addr_ret)
((long) d3 << 8) | ((long) d4 << 0));
return 4;
}
+ BGN_SAVE
hp = gethostbyname(name);
+ END_SAVE
if (hp == NULL) {
err_setstr(SocketError, "host not found");
return -1;
@@ -256,16 +257,16 @@ getsockaddrarg(s, args, addr_ret, len_ret)
case AF_UNIX:
{
static struct sockaddr_un addr;
- object *path;
+ char *path;
int len;
- if (!getStrarg(args, &path))
+ if (!getargs(args, "s#", &path, &len))
return 0;
- if ((len = getstringsize(path)) > sizeof addr.sun_path) {
+ if (len > sizeof addr.sun_path) {
err_setstr(SocketError, "AF_UNIX path too long");
return 0;
}
addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, getstringvalue(path), len);
+ memcpy(addr.sun_path, path, len);
*addr_ret = (struct sockaddr *) &addr;
*len_ret = len + sizeof addr.sun_family;
return 1;
@@ -274,11 +275,11 @@ getsockaddrarg(s, args, addr_ret, len_ret)
case AF_INET:
{
static struct sockaddr_in addr;
- object *host;
+ char *host;
int port;
- if (!getStrintarg(args, &host, &port))
+ if (!getargs(args, "(si)", &host, &port))
return 0;
- if (setipaddr(getstringvalue(host), &addr) < 0)
+ if (setipaddr(host, &addr) < 0)
return 0;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
@@ -344,7 +345,9 @@ sock_accept(s, args)
return NULL;
if (!getsockaddrlen(s, &addrlen))
return NULL;
+ BGN_SAVE
newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
+ END_SAVE
if (newfd < 0)
return socket_error();
/* Create the new object with unspecified family,
@@ -370,7 +373,7 @@ sock_allowbroadcast(s, args)
{
int flag;
int res;
- if (!getintarg(args, &flag))
+ if (!getargs(args, "i", &flag))
return NULL;
res = setsockopt(s->sock_fd, SOL_SOCKET, SO_BROADCAST,
&flag, sizeof flag);
@@ -461,9 +464,13 @@ sock_bind(s, args)
{
struct sockaddr *addr;
int addrlen;
+ int res;
if (!getsockaddrarg(s, args, &addr, &addrlen))
return NULL;
- if (bind(s->sock_fd, addr, addrlen) < 0)
+ BGN_SAVE
+ res = bind(s->sock_fd, addr, addrlen);
+ END_SAVE
+ if (res < 0)
return socket_error();
INCREF(None);
return None;
@@ -481,7 +488,9 @@ sock_close(s, args)
{
if (!getnoarg(args))
return NULL;
+ BGN_SAVE
(void) close(s->sock_fd);
+ END_SAVE
s->sock_fd = -1;
INCREF(None);
return None;
@@ -497,9 +506,13 @@ sock_connect(s, args)
{
struct sockaddr *addr;
int addrlen;
+ int res;
if (!getsockaddrarg(s, args, &addr, &addrlen))
return NULL;
- if (connect(s->sock_fd, addr, addrlen) < 0)
+ BGN_SAVE
+ res = connect(s->sock_fd, addr, addrlen);
+ END_SAVE
+ if (res < 0)
return socket_error();
INCREF(None);
return None;
@@ -527,9 +540,13 @@ sock_listen(s, args)
object *args;
{
int backlog;
+ int res;
if (!getintarg(args, &backlog))
return NULL;
- if (listen(s->sock_fd, backlog) < 0)
+ BGN_SAVE
+ res = listen(s->sock_fd, backlog);
+ END_SAVE
+ if (res < 0)
return socket_error();
INCREF(None);
return None;
@@ -549,15 +566,15 @@ sock_makefile(s, args)
object *args;
{
extern int fclose PROTO((FILE *));
- object *mode;
+ char *mode;
int fd;
FILE *fp;
- if (!getStrarg(args, &mode))
+ if (!getargs(args, "s", &mode))
return NULL;
if ((fd = dup(s->sock_fd)) < 0 ||
- (fp = fdopen(fd, getstringvalue(mode))) == NULL)
+ (fp = fdopen(fd, mode)) == NULL)
return socket_error();
- return newopenfileobject(fp, "<socket>", getstringvalue(mode), fclose);
+ return newopenfileobject(fp, "<socket>", mode, fclose);
}
@@ -579,7 +596,9 @@ sock_recv(s, args)
buf = newsizedstringobject((char *) 0, len);
if (buf == NULL)
return NULL;
+ BGN_SAVE
n = recv(s->sock_fd, getstringvalue(buf), len, flags);
+ END_SAVE
if (n < 0)
return socket_error();
if (resizestring(&buf, n) < 0)
@@ -600,10 +619,13 @@ sock_recvfrom(s, args)
int addrlen, len, n;
if (!getintarg(args, &len))
return NULL;
+ if (!getsockaddrlen(s, &addrlen))
+ return NULL;
buf = newsizedstringobject((char *) 0, len);
- addrlen = sizeof addrbuf;
+ BGN_SAVE
n = recvfrom(s->sock_fd, getstringvalue(buf), len, 0,
addrbuf, &addrlen);
+ END_SAVE
if (n < 0)
return socket_error();
if (resizestring(&buf, n) < 0)
@@ -620,16 +642,17 @@ sock_send(s, args)
sockobject *s;
object *args;
{
- object *buf;
+ char *buf;
int len, n, flags;
- if (!getStrintarg(args, &buf, &flags)) {
+ if (!getargs(args, "(s#i)", &buf, &len, &flags)) {
err_clear();
- if (!getStrarg(args, &buf))
+ if (!getargs(args, "s#", &buf, &len))
return NULL;
flags = 0;
}
- len = getstringsize(buf);
- n = send(s->sock_fd, getstringvalue(buf), len, flags);
+ BGN_SAVE
+ n = send(s->sock_fd, buf, len, flags);
+ END_SAVE
if (n < 0)
return socket_error();
INCREF(None);
@@ -644,19 +667,20 @@ sock_sendto(s, args)
sockobject *s;
object *args;
{
- object *buf;
+ object *addro;
+ char *buf;
struct sockaddr *addr;
int addrlen, len, n;
if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
err_badarg();
return NULL;
}
- if (!getStrarg(gettupleitem(args, 0), &buf) ||
- !getsockaddrarg(s, gettupleitem(args, 1), &addr, &addrlen))
+ if (!getargs(args, "(s#O)", &buf, &len, &addro) ||
+ !getsockaddrarg(s, addro, &addr, &addrlen))
return NULL;
- len = getstringsize(buf);
- n = sendto(s->sock_fd, getstringvalue(buf), len, 0,
- addr, addrlen);
+ BGN_SAVE
+ n = sendto(s->sock_fd, buf, len, 0, addr, addrlen);
+ END_SAVE
if (n < 0)
return socket_error();
INCREF(None);
@@ -672,9 +696,13 @@ sock_shutdown(s, args)
object *args;
{
int how;
+ int res;
if (!getintarg(args, &how))
return NULL;
- if (shutdown(s->sock_fd, how) < 0)
+ BGN_SAVE
+ res = shutdown(s->sock_fd, how);
+ END_SAVE
+ if (res < 0)
return socket_error();
INCREF(None);
return None;
@@ -758,13 +786,19 @@ socket_gethostname(self, args)
object *args;
{
char buf[1024];
+ int res;
if (!getnoarg(args))
return NULL;
- if (gethostname(buf, (int) sizeof buf - 1) < 0)
+ BGN_SAVE
+ res = gethostname(buf, (int) sizeof buf - 1);
+ END_SAVE
+ if (res < 0)
return socket_error();
buf[sizeof buf - 1] = '\0';
return newstringobject(buf);
}
+
+
/* Python interface to gethostbyname(name). */
/*ARGSUSED*/
@@ -775,9 +809,9 @@ socket_gethostbyname(self, args)
{
object *name;
struct sockaddr_in addrbuf;
- if (!getStrarg(args, &name))
+ if (!getargs(args, "s", &name))
return NULL;
- if (setipaddr(getstringvalue(name), &addrbuf) < 0)
+ if (setipaddr(name, &addrbuf) < 0)
return NULL;
return makeipaddr(&addrbuf);
}
@@ -793,11 +827,13 @@ socket_getservbyname(self, args)
object *self;
object *args;
{
- object *name, *proto;
+ char *name, *proto;
struct servent *sp;
- if (!getStrStrarg(args, &name, &proto))
+ if (!getargs(args, "(ss)", &name, &proto))
return NULL;
- sp = getservbyname(getstringvalue(name), getstringvalue(proto));
+ BGN_SAVE
+ sp = getservbyname(name, proto);
+ END_SAVE
if (sp == NULL) {
err_setstr(SocketError, "service/proto not found");
return NULL;
@@ -827,7 +863,9 @@ socket_socket(self, args)
return NULL;
proto = 0;
}
+ BGN_SAVE
fd = socket(family, type, proto);
+ END_SAVE
if (fd < 0)
return socket_error();
s = newsockobject(fd, family, type, proto);
diff --git a/Modules/stdwinmodule.c b/Modules/stdwinmodule.c
index 537777e..e33610d 100644
--- a/Modules/stdwinmodule.c
+++ b/Modules/stdwinmodule.c
@@ -63,11 +63,29 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "allobjects.h"
-
#include "modsupport.h"
+#include "ceval.h"
#include "stdwin.h"
+#ifdef USE_THREAD
+
+#include "thread.h"
+
+static type_lock StdwinLock; /* Lock held when interpreter not locked */
+
+#define BGN_STDWIN BGN_SAVE acquire_lock(StdwinLock, 1);
+#define RET_STDWIN release_lock(StdwinLock); RET_SAVE
+#define END_STDWIN release_lock(StdwinLock); END_SAVE
+
+#else
+
+#define BGN_STDWIN BGN_SAVE
+#define RET_STDWIN RET_SAVE
+#define END_STDWIN END_SAVE
+
+#endif
+
static object *StdwinError; /* Exception stdwin.error */
/* Window and menu object types declared here because of forward references */
@@ -1727,14 +1745,17 @@ stdwin_get_poll_event(poll, args)
return NULL;
}
again:
+ BGN_STDWIN
if (poll) {
if (!wpollevent(&e)) {
+ RET_STDWIN
INCREF(None);
return None;
}
}
else
wgetevent(&e);
+ END_STDWIN
if (e.type == WE_COMMAND && e.u.command == WC_CANCEL) {
/* Turn keyboard interrupts into exceptions */
err_set(KeyboardInterrupt);
@@ -1919,7 +1940,9 @@ stdwin_askfile(self, args)
return NULL;
strncpy(buf, dflt, sizeof buf);
buf[sizeof buf - 1] = '\0';
+ BGN_STDWIN
ret = waskfile(prompt, buf, sizeof buf, new);
+ END_STDWIN
if (!ret) {
err_set(KeyboardInterrupt);
return NULL;
@@ -1936,7 +1959,9 @@ stdwin_askync(self, args)
int new, ret;
if (!getstrintarg(args, &prompt, &new))
return NULL;
+ BGN_STDWIN
ret = waskync(prompt, new);
+ END_STDWIN
if (ret < 0) {
err_set(KeyboardInterrupt);
return NULL;
@@ -1956,7 +1981,9 @@ stdwin_askstr(self, args)
return NULL;
strncpy(buf, dflt, sizeof buf);
buf[sizeof buf - 1] = '\0';
+ BGN_STDWIN
ret = waskstr(prompt, buf, sizeof buf);
+ END_STDWIN
if (!ret) {
err_set(KeyboardInterrupt);
return NULL;
@@ -1972,7 +1999,9 @@ stdwin_message(self, args)
char *msg;
if (!getstrarg(args, &msg))
return NULL;
+ BGN_STDWIN
wmessage(msg);
+ END_STDWIN
INCREF(None);
return None;
}
@@ -2185,4 +2214,9 @@ initstdwin()
StdwinError = newstringobject("stdwin.error");
if (StdwinError == NULL || dictinsert(d, "error", StdwinError) != 0)
fatal("can't define stdwin.error");
+#ifdef USE_THREAD
+ StdwinLock = allocate_lock();
+ if (StdwinLock == NULL)
+ fatal("can't allocate stdwin lock");
+#endif
}
diff --git a/Modules/threadmodule.c b/Modules/threadmodule.c
index c4de295..6ab7ea8 100644
--- a/Modules/threadmodule.c
+++ b/Modules/threadmodule.c
@@ -27,15 +27,10 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h"
#include "modsupport.h"
-#include "compile.h"
#include "ceval.h"
#include "thread.h"
-extern void init_save_thread PROTO((void));
-extern void* save_thread PROTO((void));
-extern void restore_thread PROTO((void *));
-
object *ThreadError;
@@ -83,7 +78,6 @@ lock_acquire_lock(self, args)
lockobject *self;
object *args;
{
- void *save;
int i;
if (args != NULL) {
@@ -93,11 +87,9 @@ lock_acquire_lock(self, args)
else
i = 1;
- save = save_thread();
-
+ BGN_SAVE
i = acquire_lock(self->lock_lock, i);
-
- restore_thread(save);
+ END_SAVE
if (args == NULL) {
INCREF(None);
@@ -193,8 +185,6 @@ t_bootstrap(args_raw)
if (res == NULL) {
fprintf(stderr, "Unhandled exception in thread:\n");
print_error(); /* From pythonmain.c */
- fprintf(stderr, "Exiting the entire program\n");
- goaway(1);
}
(void) save_thread();
exit_thread();
@@ -251,7 +241,7 @@ thread_allocate_lock(self, args)
{
if (!getnoarg(args))
return NULL;
- return newlockobject();
+ return (object *) newlockobject();
}
static struct methodlist thread_methods[] = {
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 5a278a9bd..4d13611 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -25,8 +25,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Time module */
#include "allobjects.h"
-
#include "modsupport.h"
+#include "ceval.h"
#include "sigtype.h"
@@ -104,14 +104,13 @@ time_sleep(self, args)
object *self;
object *args;
{
- void *save, *save_thread(), restore_thread();
- int secs;
+ long secs;
SIGTYPE (*sigsave)() = 0; /* Initialized to shut lint up */
- if (!getintarg(args, &secs))
+ if (!getargs(args, "l", &secs))
return NULL;
- save = save_thread();
+ BGN_SAVE
if (setjmp(sleep_intr)) {
- restore_thread(save);
+ RET_SAVE
signal(SIGINT, sigsave);
err_set(KeyboardInterrupt);
return NULL;
@@ -119,8 +118,12 @@ time_sleep(self, args)
sigsave = signal(SIGINT, SIG_IGN);
if (sigsave != (SIGTYPE (*)()) SIG_IGN)
signal(SIGINT, sleep_catcher);
- sleep(secs);
- restore_thread(save);
+#ifdef BSD_TIME
+ longsleep(secs);
+#else
+ sleep((int)secs);
+#endif
+ END_SAVE
signal(SIGINT, sigsave);
INCREF(None);
return None;
@@ -151,14 +154,13 @@ time_millisleep(self, args)
object *self;
object *args;
{
- void *save, *save_thread(), restore_thread();
long msecs;
SIGTYPE (*sigsave)();
if (!getlongarg(args, &msecs))
return NULL;
- save = save_thread();
+ BGN_SAVE
if (setjmp(sleep_intr)) {
- restore_thread(save);
+ RET_SAVE
signal(SIGINT, sigsave);
err_set(KeyboardInterrupt);
return NULL;
@@ -167,7 +169,7 @@ time_millisleep(self, args)
if (sigsave != (SIGTYPE (*)()) SIG_IGN)
signal(SIGINT, sleep_catcher);
millisleep(msecs);
- restore_thread(save);
+ END_SAVE
signal(SIGINT, sigsave);
INCREF(None);
return None;
@@ -249,12 +251,12 @@ inittime()
#define MacTicks (* (long *)0x16A)
#ifdef THINK_C_3_0
-sleep(msecs)
- int msecs;
+sleep(secs)
+ int secs;
{
register long deadline;
- deadline = MacTicks + msecs * 60;
+ deadline = MacTicks + mecs * 60;
while (MacTicks < deadline) {
if (intrcheck())
sleep_catcher(SIGINT);
@@ -295,7 +297,6 @@ millitimer()
if (gettimeofday(&t, &tz) != 0)
return -1;
return t.tv_sec*1000 + t.tv_usec/1000;
-
}
millisleep(msecs)
@@ -307,6 +308,15 @@ millisleep(msecs)
(void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
}
+longsleep(secs)
+ long secs;
+{
+ struct timeval t;
+ t.tv_sec = secs;
+ t.tv_usec = 0;
+ (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
+}
+
#endif /* BSD_TIME */
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 99f4e5e..e649792 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -26,6 +26,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h"
#include "modsupport.h"
+#include "ceval.h"
#define BUF(v) GETSTRINGVALUE((stringobject *)v)
@@ -93,7 +94,11 @@ newfileobject(name, mode)
}
else
#endif
- f->f_fp = fopen(name, mode);
+ {
+ BGN_SAVE
+ f->f_fp = fopen(name, mode);
+ END_SAVE
+ }
if (f->f_fp == NULL) {
err_errno(IOError);
DECREF(f);
@@ -115,8 +120,11 @@ static void
file_dealloc(f)
fileobject *f;
{
- if (f->f_fp != NULL && f->f_close != NULL)
+ if (f->f_fp != NULL && f->f_close != NULL) {
+ BGN_SAVE
(*f->f_close)(f->f_fp);
+ END_SAVE
+ }
if (f->f_name != NULL)
DECREF(f->f_name);
if (f->f_mode != NULL)
@@ -162,10 +170,13 @@ file_close(f, args)
int sts = 0;
if (!getnoarg(args))
return NULL;
- errno = 0;
if (f->f_fp != NULL) {
- if (f->f_close != NULL)
+ if (f->f_close != NULL) {
+ BGN_SAVE
+ errno = 0;
sts = (*f->f_close)(f->f_fp);
+ END_SAVE
+ }
f->f_fp = NULL;
}
if (sts == EOF)
@@ -183,6 +194,7 @@ file_seek(f, args)
{
long offset;
int whence;
+ int ret;
if (f->f_fp == NULL)
return err_closed();
@@ -192,8 +204,11 @@ file_seek(f, args)
if (!getargs(args, "(li)", &offset, &whence))
return NULL;
}
+ BGN_SAVE
errno = 0;
- if (fseek(f->f_fp, offset, whence) != 0) {
+ ret = fseek(f->f_fp, offset, whence);
+ END_SAVE
+ if (ret != 0) {
err_errno(IOError);
clearerr(f->f_fp);
return NULL;
@@ -212,8 +227,10 @@ file_tell(f, args)
return err_closed();
if (!getnoarg(args))
return NULL;
+ BGN_SAVE
errno = 0;
offset = ftell(f->f_fp);
+ END_SAVE
if (offset == -1L) {
err_errno(IOError);
clearerr(f->f_fp);
@@ -239,12 +256,17 @@ file_flush(f, args)
fileobject *f;
object *args;
{
+ int res;
+
if (f->f_fp == NULL)
return err_closed();
if (!getnoarg(args))
return NULL;
+ BGN_SAVE
errno = 0;
- if (fflush(f->f_fp) != 0) {
+ res = fflush(f->f_fp);
+ END_SAVE
+ if (res != 0) {
err_errno(IOError);
clearerr(f->f_fp);
return NULL;
@@ -258,11 +280,15 @@ file_isatty(f, args)
fileobject *f;
object *args;
{
+ long res;
if (f->f_fp == NULL)
return err_closed();
if (!getnoarg(args))
return NULL;
- return newintobject((long)isatty((int)fileno(f->f_fp)));
+ BGN_SAVE
+ res = isatty((int)fileno(f->f_fp));
+ END_SAVE
+ return newintobject(res);
}
static object *
@@ -290,6 +316,7 @@ file_read(f, args)
if (v == NULL)
return NULL;
n1 = 0;
+ BGN_SAVE
for (;;) {
n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
/* XXX Error check? */
@@ -300,10 +327,13 @@ file_read(f, args)
break;
if (n == 0) {
n2 = n1 + BUFSIZ;
+ RET_SAVE
if (resizestring(&v, n2) < 0)
return NULL;
+ RES_SAVE
}
}
+ END_SAVE
if (n1 != n2)
resizestring(&v, n1);
return v;
@@ -321,7 +351,6 @@ getline(f, n)
fileobject *f;
int n;
{
- void *save, *save_thread(), restore_thread();
register FILE *fp;
register int c;
register char *buf, *end;
@@ -336,18 +365,18 @@ getline(f, n)
buf = BUF(v);
end = buf + n2;
- save = save_thread();
+ BGN_SAVE
for (;;) {
if ((c = getc(fp)) == EOF) {
clearerr(fp);
if (intrcheck()) {
- restore_thread(save);
+ RET_SAVE
DECREF(v);
err_set(KeyboardInterrupt);
return NULL;
}
if (n < 0 && buf == BUF(v)) {
- restore_thread(save);
+ RET_SAVE
DECREF(v);
err_setstr(EOFError,
"EOF when reading a line");
@@ -365,15 +394,15 @@ getline(f, n)
break;
n1 = n2;
n2 += 1000;
- restore_thread(save);
+ RET_SAVE
if (resizestring(&v, n2) < 0)
return NULL;
- save = save_thread();
+ RES_SAVE
buf = BUF(v) + n1;
end = BUF(v) + n2;
}
}
- restore_thread(save);
+ END_SAVE
n1 = buf - BUF(v);
if (n1 != n2)
@@ -464,8 +493,10 @@ file_write(f, args)
if (!getargs(args, "s#", &s, &n))
return NULL;
f->f_softspace = 0;
+ BGN_SAVE
errno = 0;
n2 = fwrite(s, 1, n, f->f_fp);
+ END_SAVE
if (n2 != n) {
err_errno(IOError);
clearerr(f->f_fp);
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 996c289..0f51735 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -26,8 +26,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h"
#include "modsupport.h"
-#include "compile.h" /* Needed by ceval.h */
-#include "ceval.h" /* For call_object() */
+#include "ceval.h"
object *
newlistobject(size)
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index d6ae46f..ca5043d 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -33,7 +33,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "bltinmodule.h"
#include "import.h"
#include "pythonrun.h"
-#include "compile.h" /* For ceval.h */
#include "ceval.h"
#include "modsupport.h"
@@ -218,13 +217,17 @@ builtin_execfile(self, v)
"execfile arguments must be filename[,dict[,dict]]");
return NULL;
}
+ BGN_SAVE
fp = fopen(getstringvalue(str), "r");
+ END_SAVE
if (fp == NULL) {
err_setstr(IOError, "execfile cannot open the file argument");
return NULL;
}
w = run_file(fp, getstringvalue(str), file_input, globals, locals);
+ BGN_SAVE
fclose(fp);
+ END_SAVE
return w;
}
@@ -324,9 +327,11 @@ builtin_input(self, v)
}
m = add_module("__main__");
d = getmoduledict(m);
+ BGN_SAVE
while ((c = getc(in)) != EOF && (c == ' ' || c == '\t'))
;
ungetc(c, in);
+ END_SAVE
return run_file(in, "<stdin>", expr_input, d, d);
}
diff --git a/Python/ceval.c b/Python/ceval.c
index 32c52c7..252b1dc 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -30,6 +30,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "sysmodule.h"
#include "compile.h"
#include "frameobject.h"
+#include "eval.h"
#include "ceval.h"
#include "opcode.h"
#include "bltinmodule.h"
@@ -83,48 +84,28 @@ static object *build_class PROTO((object *, object *));
static frameobject *current_frame;
-
-/* Interface for threads.
-
- A module that plans to do a blocking system call (or something else
- that lasts a long time and doesn't touch Python data) can allow other
- threads to run as follows:
-
- void *x;
-
- ...preparations here...
- x = save_thread();
- ...blocking system call here...
- restore_thread(x);
- ...interpretr result here...
-
- For convenience, that the value of 'errno' is restored across the
- the call to restore_thread().
-
- The function init_save_thread() should be called only from
- initthread() in "threadmodule.c".
-
- Note that not yet all candidates have been converted to use this
- mechanism!
-*/
-
#ifdef USE_THREAD
+
#include <errno.h>
#include "thread.h"
+
static type_lock interpreter_lock;
void
init_save_thread()
{
-#ifdef USE_THREAD
if (interpreter_lock)
fatal("2nd call to init_save_thread");
interpreter_lock = allocate_lock();
acquire_lock(interpreter_lock, 1);
-#endif
}
+
#endif
+/* Functions save_thread and restore_thread are always defined so
+ dynamically loaded modules needn't be compiled separately for use
+ with and without threads: */
+
void *
save_thread()
{
diff --git a/Python/import.c b/Python/import.c
index 5667c77..44f6d7b 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -35,7 +35,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "pythonrun.h"
#include "marshal.h"
#include "compile.h"
-#include "ceval.h"
+#include "eval.h"
#include "osdefs.h"
extern int verbose; /* Defined in pythonmain.c */
diff --git a/Python/pythonmain.c b/Python/pythonmain.c
index 0f76bfd..4344cde 100644
--- a/Python/pythonmain.c
+++ b/Python/pythonmain.c
@@ -26,8 +26,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h"
-extern char *getpythonpath();
-
extern int debugging; /* Needed by parser.c */
extern int verbose; /* Needed by import.c */
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 2a68f24..c8921da 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -33,14 +33,11 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "errcode.h"
#include "sysmodule.h"
#include "compile.h"
+#include "eval.h"
#include "ceval.h"
#include "pythonrun.h"
#include "import.h"
-#ifdef USE_THREAD
-extern void *save_thread();
-#endif
-
extern char *getpythonpath();
extern grammar gram; /* From graminit.c */
@@ -127,7 +124,6 @@ run_tty_1(fp, filename)
FILE *fp;
char *filename;
{
- void *save, *save_thread(), restore_thread();
object *m, *d, *v, *w;
node *n;
char *ps1, *ps2;
@@ -150,9 +146,9 @@ run_tty_1(fp, filename)
w = NULL;
ps2 = "";
}
- save = save_thread();
+ BGN_SAVE
err = parsefile(fp, filename, &gram, single_input, ps1, ps2, &n);
- restore_thread(save);
+ END_SAVE
XDECREF(v);
XDECREF(w);
if (err == E_EOF)
@@ -330,8 +326,12 @@ parse_file(fp, filename, start, n_ret)
int start;
node **n_ret;
{
- return parsefile(fp, filename, &gram, start,
+ int ret;
+ BGN_SAVE
+ ret = parsefile(fp, filename, &gram, start,
(char *)0, (char *)0, n_ret);
+ END_SAVE
+ return ret;
}
/* Simplified interface to parsestring */
@@ -366,6 +366,18 @@ goaway(sts)
int sts;
{
flushline();
+
+#ifdef USE_THREAD
+
+ /* Other threads may still be active, so skip most of the
+ cleanup actions usually done (these are mostly for
+ debugging anyway). */
+
+ (void *) save_thread();
+ donecalls();
+ exit_prog(sts);
+
+#else /* USE_THREAD */
/* XXX Call doneimport() before donecalls(), since donecalls()
calls wdone(), and doneimport() may close windows */
@@ -384,12 +396,8 @@ goaway(sts)
}
#endif /* TRACE_REFS */
-#ifdef USE_THREAD
- (void) save_thread();
- exit_prog(sts);
-#else
exit(sts);
-#endif
+#endif /* USE_THREAD */
/*NOTREACHED*/
}
diff --git a/Python/thread.c b/Python/thread.c
index 1f0633a..4aa06cf 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -17,7 +17,7 @@ static int exiting;
#include <lwp/lwp.h>
#include <lwp/stackdep.h>
-#define STACKSIZE 1000 /* stacksize for a thread */
+#define STACKSIZE 16000 /* stacksize for a thread */
#define NSTACKS 2 /* # stacks to be put in cache initialy */
struct lock {
@@ -90,7 +90,7 @@ void exit_thread _P0()
exit(0);
#ifdef __sgi
exiting = 1;
- exit(0);
+ _exit(0);
#endif
#ifdef SOLARIS
thread_exit();
@@ -113,7 +113,7 @@ static void exit_sig _P0()
#ifdef DEBUG
printf("exiting in exit_sig\n");
#endif
- exit(exit_status);
+ _exit(exit_status);
}
}
#endif
@@ -255,7 +255,7 @@ void exit_prog _P1(status, int status)
exiting = 1;
do_exit = 1;
exit_status = status;
- exit(status);
+ _exit(status);
#endif
#ifdef sun
pod_exit(status);