diff options
author | Guido van Rossum <guido@python.org> | 1992-08-04 12:41:02 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1992-08-04 12:41:02 (GMT) |
commit | 1984f1e1c6306d4e8073c28d2395638f80ea509b (patch) | |
tree | 4366039e7665e689aef04549c3e3d73f99bdab32 /Modules | |
parent | 4fbf798f866b10ee50cc91a394d19c0d4b2f79ab (diff) | |
download | cpython-1984f1e1c6306d4e8073c28d2395638f80ea509b.zip cpython-1984f1e1c6306d4e8073c28d2395638f80ea509b.tar.gz cpython-1984f1e1c6306d4e8073c28d2395638f80ea509b.tar.bz2 |
* Makefile adapted to changes below.
* split pythonmain.c in two: most stuff goes to pythonrun.c, in the library.
* new optional built-in threadmodule.c, build upon Sjoerd's thread.{c,h}.
* new module from Sjoerd: mmmodule.c (dynamically loaded).
* new module from Sjoerd: sv (svgen.py, svmodule.c.proto).
* new files thread.{c,h} (from Sjoerd).
* new xxmodule.c (example only).
* myselect.h: bzero -> memset
* select.c: bzero -> memset; removed global variable
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/config.c.in | 16 | ||||
-rw-r--r-- | Modules/threadmodule.c | 294 | ||||
-rw-r--r-- | Modules/timemodule.c | 8 | ||||
-rw-r--r-- | Modules/xxmodule.c | 92 |
4 files changed, 403 insertions, 7 deletions
diff --git a/Modules/config.c.in b/Modules/config.c.in index 0973b77..8ed889a 100644 --- a/Modules/config.c.in +++ b/Modules/config.c.in @@ -123,6 +123,7 @@ extern void initpwd(); extern void initgrp(); extern void initmarshal(); extern void initselect(); +extern void initsocket(); #ifdef USE_AUDIO extern void initaudio(); @@ -148,15 +149,15 @@ extern void initpanel(); #ifdef USE_STDWIN extern void initstdwin(); #endif -#ifdef USE_SOCKET -extern void initsocket(); -#endif #ifdef USE_JPEG extern void initjpeg(); #endif #ifdef USE_CD extern void initcd(); #endif +#ifdef USE_THREAD +extern void initthread(); +#endif struct { char *name; @@ -173,6 +174,7 @@ struct { {"grp", initgrp}, {"marshal", initmarshal}, {"select", initselect}, + {"socket", initsocket}, /* Optional modules */ @@ -206,10 +208,6 @@ struct { {"stdwin", initstdwin}, #endif -#ifdef USE_SOCKET - {"socket", initsocket}, -#endif - #ifdef USE_JPEG {"jpeg", initjpeg}, #endif @@ -218,5 +216,9 @@ struct { {"cd", initcd}, #endif +#ifdef USE_THREAD + {"thread", initthread}, +#endif + {0, 0} /* Sentinel */ }; diff --git a/Modules/threadmodule.c b/Modules/threadmodule.c new file mode 100644 index 0000000..c4de295 --- /dev/null +++ b/Modules/threadmodule.c @@ -0,0 +1,294 @@ +/*********************************************************** +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. + +******************************************************************/ + +/* Thread module */ +/* Interface to Sjoerd's portable C thread library */ + +#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; + + +/* Lock objects */ + +typedef struct { + OB_HEAD + type_lock lock_lock; +} lockobject; + +extern typeobject Locktype; /* Really static, forward */ + +#define is_lockobject(v) ((v)->ob_type == &Locktype) + +static lockobject * +newlockobject() +{ + lockobject *self; + self = NEWOBJ(lockobject, &Locktype); + if (self == NULL) + return NULL; + self->lock_lock = allocate_lock(); + if (self->lock_lock == NULL) { + DEL(self); + self = NULL; + err_setstr(ThreadError, "can't allocate lock"); + } + return self; +} + +static void +lock_dealloc(self) + lockobject *self; +{ + /* Unlock the lock so it's safe to free it */ + acquire_lock(self->lock_lock, 0); + release_lock(self->lock_lock); + + free_lock(self->lock_lock); + DEL(self); +} + +static object * +lock_acquire_lock(self, args) + lockobject *self; + object *args; +{ + void *save; + int i; + + if (args != NULL) { + if (!getargs(args, "i", &i)) + return NULL; + } + else + i = 1; + + save = save_thread(); + + i = acquire_lock(self->lock_lock, i); + + restore_thread(save); + + if (args == NULL) { + INCREF(None); + return None; + } + else + return newintobject((long)i); +} + +static object * +lock_release_lock(self, args) + lockobject *self; + object *args; +{ + if (!getnoarg(args)) + return NULL; + + /* Sanity check: the lock must be locked */ + if (acquire_lock(self->lock_lock, 0)) { + release_lock(self->lock_lock); + err_setstr(ThreadError, "release unlocked lock"); + return NULL; + } + + release_lock(self->lock_lock); + INCREF(None); + return None; +} + +static object * +lock_locked_lock(self, args) + lockobject *self; + object *args; +{ + if (!getnoarg(args)) + return NULL; + + if (acquire_lock(self->lock_lock, 0)) { + release_lock(self->lock_lock); + return newintobject(0L); + } + return newintobject(1L); +} + +static struct methodlist lock_methods[] = { + {"acquire_lock", lock_acquire_lock}, + {"acquire", lock_acquire_lock}, + {"release_lock", lock_release_lock}, + {"release", lock_release_lock}, + {"locked_lock", lock_locked_lock}, + {"locked", lock_locked_lock}, + {NULL, NULL} /* sentinel */ +}; + +static object * +lock_getattr(self, name) + lockobject *self; + char *name; +{ + return findmethod(lock_methods, (object *)self, name); +} + +static typeobject Locktype = { + OB_HEAD_INIT(&Typetype) + 0, /*ob_size*/ + "lock", /*tp_name*/ + sizeof(lockobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + lock_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + lock_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ +}; + + +/* Module functions */ + +static void +t_bootstrap(args_raw) + void *args_raw; +{ + object *args = (object *) args_raw; + object *func, *arg, *res; + + restore_thread((void *)NULL); + func = gettupleitem(args, 0); + arg = gettupleitem(args, 1); + res = call_object(func, arg); + DECREF(arg); /* Matches the INCREF(arg) in thread_start_new_thread */ + 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(); +} + +static object * +thread_start_new_thread(self, args) + object *self; /* Not used */ + object *args; +{ + object *func, *arg; + + if (!getargs(args, "(OO)", &func, &arg)) + return NULL; + INCREF(args); + if (!start_new_thread(t_bootstrap, (void*) args)) { + DECREF(args); + err_setstr(ThreadError, "can't start new thread\n"); + return NULL; + } + /* Otherwise the DECREF(args) is done by t_bootstrap */ + INCREF(None); + return None; +} + +static object * +thread_exit_thread(self, args) + object *self; /* Not used */ + object *args; +{ + if (!getnoarg(args)) + return NULL; + (void) save_thread(); + exit_thread(); + for (;;) { } /* Should not be reached */ +} + +static object * +thread_exit_prog(self, args) + object *self; /* Not used */ + object *args; +{ + int sts; + if (!getargs(args, "i", &sts)) + return NULL; + goaway(sts); + for (;;) { } /* Should not be reached */ +} + +static object * +thread_allocate_lock(self, args) + object *self; /* Not used */ + object *args; +{ + if (!getnoarg(args)) + return NULL; + return newlockobject(); +} + +static struct methodlist thread_methods[] = { + {"start_new_thread", thread_start_new_thread}, + {"start_new", thread_start_new_thread}, + {"allocate_lock", thread_allocate_lock}, + {"allocate", thread_allocate_lock}, + {"exit_thread", thread_exit_thread}, + {"exit", thread_exit_thread}, + {"exit_prog", thread_exit_prog}, + {NULL, NULL} /* sentinel */ +}; + + +/* Initialization function */ + +void +initthread() +{ + object *m, *d, *x; + + /* Create the module and add the functions */ + m = initmodule("thread", thread_methods); + + /* Add a symbolic constant */ + d = getmoduledict(m); + ThreadError = newstringobject("thread.error"); + INCREF(ThreadError); + dictinsert(d, "error", ThreadError); + + /* Check for errors */ + if (err_occurred()) + fatal("can't initialize module thread"); + + /* Initialize the C thread library */ + init_thread(); + + /* Initialize the interpreter's stack save/restore mechanism */ + init_save_thread(); +} diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 4a921f0..5a278a9bd 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -104,11 +104,14 @@ time_sleep(self, args) object *self; object *args; { + void *save, *save_thread(), restore_thread(); int secs; SIGTYPE (*sigsave)() = 0; /* Initialized to shut lint up */ if (!getintarg(args, &secs)) return NULL; + save = save_thread(); if (setjmp(sleep_intr)) { + restore_thread(save); signal(SIGINT, sigsave); err_set(KeyboardInterrupt); return NULL; @@ -117,6 +120,7 @@ time_sleep(self, args) if (sigsave != (SIGTYPE (*)()) SIG_IGN) signal(SIGINT, sleep_catcher); sleep(secs); + restore_thread(save); signal(SIGINT, sigsave); INCREF(None); return None; @@ -147,11 +151,14 @@ 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(); if (setjmp(sleep_intr)) { + restore_thread(save); signal(SIGINT, sigsave); err_set(KeyboardInterrupt); return NULL; @@ -160,6 +167,7 @@ time_millisleep(self, args) if (sigsave != (SIGTYPE (*)()) SIG_IGN) signal(SIGINT, sleep_catcher); millisleep(msecs); + restore_thread(save); signal(SIGINT, sigsave); INCREF(None); return None; diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c new file mode 100644 index 0000000..070a622 --- /dev/null +++ b/Modules/xxmodule.c @@ -0,0 +1,92 @@ +/*********************************************************** +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. + +******************************************************************/ + +/* xx module */ + +#include "allobjects.h" +#include "modsupport.h" + + +/* Function of two integers returning integer */ + +static object * +xx_foo(self, args) + object *self; /* Not used */ + object *args; +{ + long i, j; + long res; + if (!getargs(args, "(ll)", &i, &j)) + return NULL; + res = i+j; /* XXX Do something here */ + return newintobject(res); +} + + +/* Function of no arguments returning None */ + +static object * +xx_bar(self, args) + object *self; /* Not used */ + object *args; +{ + int i, j; + if (!getnoarg(args)) + return NULL; + /* XXX Do something here */ + INCREF(None); + return None; +} + + +/* List of functions defined in the module */ + +static struct methodlist xx_methods[] = { + {"foo", xx_foo}, + {"bar", xx_bar}, + {NULL, NULL} /* sentinel */ +}; + + +/* Initialization function for the module (*must* be called initxx) */ + +void +initxx() +{ + object *m, *d, *x; + + /* Create the module and add the functions */ + m = initmodule("xx", xx_methods); + + /* Add some symbolic constants to the module */ + d = getmoduledict(m); + x = newstringobject("xx.error"); + dictinsert(d, "error", x); + x = newintobject(42L); + dictinsert(d, "magic", x); + + /* Check for errors */ + if (err_occurred()) + fatal("can't initialize module xx"); +} |