move hooks into python

This commit is contained in:
Michael Davidsaver
2013-04-14 12:01:56 -04:00
parent 4d2c3c4fd3
commit 1e34cf9b76
2 changed files with 42 additions and 57 deletions

View File

@ -23,9 +23,6 @@
#include "pydevsup.h"
/* dictionary of initHook names */
static PyObject *hooktable;
typedef struct {
const initHookState state;
const char * const name;
@ -98,46 +95,30 @@ void evalFilePy(const char* file)
static void pyhook(initHookState state)
{
static int madenoise = 0;
PyGILState_STATE gilstate;
PyObject *mod, *ret;
/* ignore deprecated init hooks */
if(state==initHookAfterInterruptAccept || state==initHookAtEnd)
return;
gilstate = PyGILState_Ensure();
if(hooktable && PyDict_Check(hooktable)) {
PyObject *next;
PyObject *key = PyInt_FromLong((long)state);
PyObject *list = PyDict_GetItem(hooktable, key);
Py_DECREF(key);
if(list) {
list = PyObject_GetIter(list);
if(!list) {
fprintf(stderr, "hook sequence not iterable!");
} else {
while((next=PyIter_Next(list))!=NULL) {
PyObject *obj;
if(!PyCallable_Check(next))
continue;
obj = PyObject_CallFunction(next, "");
Py_DECREF(next);
if(obj)
Py_DECREF(obj);
else {
PyErr_Print();
PyErr_Clear();
}
}
if(!PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
}
Py_DECREF(list);
}
}
mod = PyImport_ImportModule("devsup.hooks");
if(!mod) {
if(!madenoise)
fprintf(stderr, "Couldn't import devsup.hooks\n");
madenoise=1;
return;
}
ret = PyObject_CallMethod(mod, "_runhook", "l", (long)state);
Py_DECREF(mod);
if(PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
}
Py_XDECREF(ret);
PyGILState_Release(gilstate);
}
@ -174,10 +155,6 @@ PyMODINIT_FUNC init_dbapi(void)
import_array();
hooktable = PyDict_New();
if(!hooktable)
MODINIT_RET(NULL);
if(pyField_prepare())
MODINIT_RET(NULL);
if(pyRecord_prepare())
@ -202,8 +179,6 @@ PyMODINIT_FUNC init_dbapi(void)
for(st = statenames; st->name; st++) {
PyDict_SetItemString(hookdict, st->name, PyInt_FromLong((long)st->state));
}
Py_INCREF(hooktable); /* an extra ref for the global pointer */
PyModule_AddObject(mod, "_hooktable", hooktable);
pyField_setup(mod);
pyRecord_setup(mod);
@ -224,10 +199,6 @@ static void cleanupPy(void *junk)
pyField_cleanup();
/* release extra reference for hooktable */
Py_XDECREF(hooktable);
hooktable = NULL;
Py_Finalize();
}

View File

@ -1,5 +1,8 @@
from __future__ import print_function
import traceback
from collections import defaultdict
try:
import _dbapi
except ImportError:
@ -13,12 +16,16 @@ __all__ = [
hooknames = _dbapi._hooks.keys()
_revnames = dict([(v,k) for k,v in _dbapi._hooks.iteritems()])
_hooktable = defaultdict(list)
def addHook(state, func):
"""addHook("stats", funcion)
Add callable to IOC start sequence.
Callables are run in the reverse of the order in
which they were added.
Callables are run in the order in
which they were added (except for 'AtIocExit').
>>> def show():
... print 'State Occurred'
@ -28,13 +35,7 @@ def addHook(state, func):
for cleanup actions during IOC shutdown.
"""
sid = _dbapi._hooks[state]
try:
slist = _dbapi._hooktable[sid]
except KeyError:
slist = []
_dbapi._hooktable[sid] = slist
slist.append(func)
_hooktable[sid].append(func)
def debugHooks():
@ -44,3 +45,16 @@ def debugHooks():
def _showstate(state=h):
print('Reached state',state)
addHook(h, _showstate)
def _runhook(sid):
name = _revnames[sid]
pop = -1 if name=='AtIocExit' else 0
fns = _hooktable.get(sid)
if fns is not None:
while len(fns)>0:
fn = fns.pop(pop)
try:
fn()
except:
print("Error running",name,"hook",fn)
traceback.print_exc()