Commit d0af6118 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add the 'signal' module

The signal module is Python code's interface to signal handling, but also the
way that the interpreter accepts and handles signals.

This commit just enables the first part, but things will crash if a signal
actually gets delivered.
parent f805eae3
...@@ -290,7 +290,7 @@ SRCS := $(MAIN_SRCS) $(STDLIB_SRCS) ...@@ -290,7 +290,7 @@ SRCS := $(MAIN_SRCS) $(STDLIB_SRCS)
STDLIB_OBJS := stdlib.bc.o stdlib.stripped.bc.o STDLIB_OBJS := stdlib.bc.o stdlib.stripped.bc.o
STDLIB_RELEASE_OBJS := stdlib.release.bc.o STDLIB_RELEASE_OBJS := stdlib.release.bc.o
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c $(EXTRA_STDMODULE_SRCS) STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c $(EXTRA_STDMODULE_SRCS)
STDOBJECT_SRCS := structseq.c capsule.c stringobject.c $(EXTRA_STDOBJECT_SRCS) STDOBJECT_SRCS := structseq.c capsule.c stringobject.c $(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS := pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c $(EXTRA_STDPYTHON_SRCS) STDPYTHON_SRCS := pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c $(EXTRA_STDPYTHON_SRCS)
FROM_CPYTHON_SRCS := $(addprefix from_cpython/Modules/,$(STDMODULE_SRCS)) $(addprefix from_cpython/Objects/,$(STDOBJECT_SRCS)) $(addprefix from_cpython/Python/,$(STDPYTHON_SRCS)) FROM_CPYTHON_SRCS := $(addprefix from_cpython/Modules/,$(STDMODULE_SRCS)) $(addprefix from_cpython/Objects/,$(STDOBJECT_SRCS)) $(addprefix from_cpython/Python/,$(STDPYTHON_SRCS))
......
...@@ -15,7 +15,7 @@ endforeach(STDLIB_FILE) ...@@ -15,7 +15,7 @@ endforeach(STDLIB_FILE)
add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS}) add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS})
# compile specified files in from_cpython/Modules # compile specified files in from_cpython/Modules
file(GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c) file(GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c)
# compile specified files in from_cpython/Objects # compile specified files in from_cpython/Objects
file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c) file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c)
......
// This file is originally from CPython 2.7, with modifications for Pyston
#ifndef Py_PYTHREAD_H
#define Py_PYTHREAD_H
typedef void *PyThread_type_lock;
typedef void *PyThread_type_sema;
#ifdef __cplusplus
extern "C" {
#endif
PyAPI_FUNC(void) PyThread_init_thread(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(long) PyThread_start_new_thread(void (*)(void *), void *) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyThread_exit_thread(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(long) PyThread_get_thread_ident(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int) PYSTON_NOEXCEPT;
#define WAIT_LOCK 1
#define NOWAIT_LOCK 0
PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock) PYSTON_NOEXCEPT;
PyAPI_FUNC(size_t) PyThread_get_stacksize(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyThread_set_stacksize(size_t) PYSTON_NOEXCEPT;
/* Thread Local Storage (TLS) API */
PyAPI_FUNC(int) PyThread_create_key(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyThread_delete_key(int) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyThread_set_key_value(int, void *) PYSTON_NOEXCEPT;
PyAPI_FUNC(void *) PyThread_get_key_value(int) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) PyThread_delete_key_value(int key) PYSTON_NOEXCEPT;
/* Cleanup after a fork */
PyAPI_FUNC(void) PyThread_ReInitTLS(void) PYSTON_NOEXCEPT;
#ifdef __cplusplus
}
#endif
#endif /* !Py_PYTHREAD_H */
...@@ -892,6 +892,10 @@ finisignal(void) ...@@ -892,6 +892,10 @@ finisignal(void)
int int
PyErr_CheckSignals(void) PyErr_CheckSignals(void)
{ {
// Pyston change:
Py_FatalError("TODO");
#if 0
int i; int i;
PyObject *f; PyObject *f;
...@@ -939,6 +943,7 @@ PyErr_CheckSignals(void) ...@@ -939,6 +943,7 @@ PyErr_CheckSignals(void)
Py_DECREF(result); Py_DECREF(result);
} }
} }
#endif
return 0; return 0;
} }
......
...@@ -607,5 +607,29 @@ void allowGLReadPreemption() { ...@@ -607,5 +607,29 @@ void allowGLReadPreemption() {
} }
#endif #endif
extern "C" long PyThread_get_thread_ident(void) noexcept {
return pthread_self();
}
// We don't support CPython's TLS (yet?)
extern "C" void PyThread_ReInitTLS(void) noexcept {
// don't have to do anything since we don't support TLS
}
extern "C" int PyThread_create_key(void) noexcept {
Py_FatalError("unimplemented");
}
extern "C" void PyThread_delete_key(int) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyThread_set_key_value(int, void*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" void* PyThread_get_key_value(int) noexcept {
Py_FatalError("unimplemented");
}
extern "C" void PyThread_delete_key_value(int key) noexcept {
Py_FatalError("unimplemented");
}
} // namespace threading } // namespace threading
} // namespace pyston } // namespace pyston
...@@ -735,10 +735,6 @@ extern "C" PyObject* PyErr_NoMemory() noexcept { ...@@ -735,10 +735,6 @@ extern "C" PyObject* PyErr_NoMemory() noexcept {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
extern "C" int PyErr_CheckSignals() noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyExceptionClass_Check(PyObject* o) noexcept { extern "C" int PyExceptionClass_Check(PyObject* o) noexcept {
return PyClass_Check(o) || (PyType_Check(o) && isSubclass(static_cast<BoxedClass*>(o), BaseException)); return PyClass_Check(o) || (PyType_Check(o) && isSubclass(static_cast<BoxedClass*>(o), BaseException));
} }
...@@ -1169,27 +1165,6 @@ Done: ...@@ -1169,27 +1165,6 @@ Done:
#undef _PyOS_vsnprintf_EXTRA_SPACE #undef _PyOS_vsnprintf_EXTRA_SPACE
} }
extern "C" void PyOS_AfterFork(void) noexcept {
// TODO CPython does a number of things after a fork:
// - clears pending signals
// - updates the cached "main_pid"
// - reinitialize and reacquire the GIL
// - reinitialize the import lock
// - change the definition of the main thread to the current thread
// - call threading._after_fork
// Also see PyEval_ReInitThreads
// Should we disable finalizers after a fork?
// In CPython, I think all garbage from other threads will never be freed and
// their destructors never run. I think for us, we will presumably collect it
// and run the finalizers. It's probably just safer to run no finalizers?
// Our handling right now is pretty minimal... you better just call exec().
PyEval_ReInitThreads();
_PyImport_ReInitLock();
}
extern "C" { extern "C" {
static int dev_urandom_python(char* buffer, Py_ssize_t size) noexcept { static int dev_urandom_python(char* buffer, Py_ssize_t size) noexcept {
int fd; int fd;
...@@ -1261,6 +1236,79 @@ extern "C" int _PyOS_URandom(void* buffer, Py_ssize_t size) noexcept { ...@@ -1261,6 +1236,79 @@ extern "C" int _PyOS_URandom(void* buffer, Py_ssize_t size) noexcept {
#endif #endif
} }
extern "C" PyOS_sighandler_t PyOS_getsig(int sig) noexcept {
#ifdef HAVE_SIGACTION
struct sigaction context;
if (sigaction(sig, NULL, &context) == -1)
return SIG_ERR;
return context.sa_handler;
#else
PyOS_sighandler_t handler;
/* Special signal handling for the secure CRT in Visual Studio 2005 */
#if defined(_MSC_VER) && _MSC_VER >= 1400
switch (sig) {
/* Only these signals are valid */
case SIGINT:
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGTERM:
case SIGBREAK:
case SIGABRT:
break;
/* Don't call signal() with other values or it will assert */
default:
return SIG_ERR;
}
#endif /* _MSC_VER && _MSC_VER >= 1400 */
handler = signal(sig, SIG_IGN);
if (handler != SIG_ERR)
signal(sig, handler);
return handler;
#endif
}
extern "C" PyOS_sighandler_t PyOS_setsig(int sig, PyOS_sighandler_t handler) noexcept {
if (sig == SIGUSR2) {
Py_FatalError("SIGUSR2 is reserved for Pyston internal use");
}
#ifdef HAVE_SIGACTION
/* Some code in Modules/signalmodule.c depends on sigaction() being
* used here if HAVE_SIGACTION is defined. Fix that if this code
* changes to invalidate that assumption.
*/
struct sigaction context, ocontext;
context.sa_handler = handler;
sigemptyset(&context.sa_mask);
context.sa_flags = 0;
if (sigaction(sig, &context, &ocontext) == -1)
return SIG_ERR;
return ocontext.sa_handler;
#else
PyOS_sighandler_t oldhandler;
oldhandler = signal(sig, handler);
#ifdef HAVE_SIGINTERRUPT
siginterrupt(sig, 1);
#endif
return oldhandler;
#endif
}
extern "C" int Py_AddPendingCall(int (*func)(void*), void* arg) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* _PyImport_FixupExtension(char* name, char* filename) noexcept {
// Don't have to do anything here, since we will error in _PyImport_FindExtension
// TODO is this ok?
return NULL;
}
extern "C" PyObject* _PyImport_FindExtension(char* name, char* filename) noexcept {
Py_FatalError("unimplemented");
}
BoxedModule* importTestExtension(const std::string& name) { BoxedModule* importTestExtension(const std::string& name) {
std::string pathname_name = "test/test_extension/" + name + ".pyston.so"; std::string pathname_name = "test/test_extension/" + name + ".pyston.so";
const char* pathname = pathname_name.c_str(); const char* pathname = pathname_name.c_str();
......
...@@ -53,6 +53,7 @@ extern "C" void init_functools(); ...@@ -53,6 +53,7 @@ extern "C" void init_functools();
extern "C" void init_collections(); extern "C" void init_collections();
extern "C" void inititertools(); extern "C" void inititertools();
extern "C" void initresource(); extern "C" void initresource();
extern "C" void initsignal();
namespace pyston { namespace pyston {
...@@ -1183,6 +1184,7 @@ void setupRuntime() { ...@@ -1183,6 +1184,7 @@ void setupRuntime() {
init_collections(); init_collections();
inititertools(); inititertools();
initresource(); initresource();
initsignal();
setupSysEnd(); setupSysEnd();
......
import signal
for k in sorted(dir(signal)):
if not k.startswith("SIG"):
continue
print k, getattr(signal, k)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment