From ff4949eeee7f86117d4a69599777ff5564315e39 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 5 Aug 1992 19:58:53 +0000 Subject: * Makefile: cosmetics * socketmodule.c: get rid of makepair(); fix makesocketaddr to fix broken recvfrom() * socketmodule: get rid of getStrarg() * ceval.h: move eval_code() to new file eval.h, so compile.h is no longer needed. * ceval.c: move thread comments to ceval.h; always make save/restore thread functions available (for dynloaded modules) * cdmodule.c, listobject.c: don't include compile.h * flmodule.c: include ceval.h * import.c: include eval.h instead of ceval.h * cgen.py: add forground(); noport(); winopen(""); to initgl(). * bltinmodule.c, socketmodule.c, fileobject.c, posixmodule.c, selectmodule.c: adapt to threads (add BGN/END SAVE macros) * stdwinmodule.c: adapt to threads and use a special stdwin lock. * pythonmain.c: don't include getpythonpath(). * pythonrun.c: use BGN/END SAVE instead of direct calls; also more BGN/END SAVE calls etc. * thread.c: bigger stack size for sun; change exit() to _exit() * threadmodule.c: use BGN/END SAVE macros where possible * timemodule.c: adapt better to threads; use BGN/END SAVE; add longsleep internal function if BSD_TIME; cosmetics --- Include/ceval.h | 72 ++++++++++++++++++++++++++++++-- Include/eval.h | 27 ++++++++++++ Modules/cdmodule.c | 1 - Modules/cgen.py | 4 ++ Modules/flmodule.c | 4 +- Modules/posixmodule.c | 67 +++++++++++++++++++++++++----- Modules/selectmodule.c | 3 +- Modules/socketmodule.c | 110 +++++++++++++++++++++++++++++++++---------------- Modules/stdwinmodule.c | 36 +++++++++++++++- Modules/threadmodule.c | 16 ++----- Modules/timemodule.c | 42 ++++++++++++------- Objects/fileobject.c | 59 +++++++++++++++++++------- Objects/listobject.c | 3 +- Python/bltinmodule.c | 7 +++- Python/ceval.c | 35 ++++------------ Python/import.c | 2 +- Python/pythonmain.c | 2 - Python/pythonrun.c | 34 +++++++++------ Python/thread.c | 8 ++-- 19 files changed, 382 insertions(+), 150 deletions(-) create mode 100644 Include/eval.h 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 , , */ @@ -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, "", getstringvalue(mode), fclose); + return newopenfileobject(fp, "", 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, "", 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 #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 #include -#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); -- cgit v0.12