[Libsysio-commit] HEAD: libsysio/src init.c
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2005-09-15 21:31:46
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19135/src Modified Files: init.c Log Message: Support user-defined entry/exit callbacks and switch existing trace-print support to the new mechanism. Introduces: _sysio_entry_trace_q and _sysio_exit_trace_q; pointers to the 2 callback queues. _sysio_register_trace; To register a callback _sysio_remove_trace; To remove a previously registered callback _sysio_run_trace_q; To execute the callbacks in a trace queue. Index: init.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/init.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -w -b -B -p -r1.21 -r1.22 --- init.c 25 Jan 2005 00:37:11 -0000 1.21 +++ init.c 15 Sep 2005 21:31:38 -0000 1.22 @@ -80,7 +80,23 @@ #endif #if SYSIO_TRACING -int _sysio_tracing = 0; + +struct trace_callback { + TAILQ_ENTRY(trace_callback) links; + void (*f)(const char *file, const char *func, int line); +}; + +#define TCB_INIT(__tcb, __f) \ + do { \ + (__tcb)->f = (__f); \ + } while (0); + +TAILQ_HEAD(trace_q, trace_callback); + +static struct trace_q _sysio_entry_trace_head; +void *_sysio_entry_trace_q = &_sysio_entry_trace_head; +static struct trace_q _sysio_exit_trace_head; +void *_sysio_exit_trace_q = &_sysio_exit_trace_head; #endif /* @@ -111,6 +127,12 @@ _sysio_init() extern int _sysio_sockets_init(void); #endif + /* + * Initialize tracing callback queues. + */ + TAILQ_INIT(&_sysio_entry_trace_head); + TAILQ_INIT(&_sysio_exit_trace_head); + err = _sysio_ioctx_init(); if (err) goto error; @@ -161,6 +183,20 @@ _sysio_shutdown() _sysio_fd_shutdown(); _sysio_i_shutdown(); _sysio_fssw_shutdown(); +#if SYSIO_TRACING + { + struct trace_callback *tcb; + + while ((tcb = _sysio_entry_trace_head.tqh_first) != NULL) { + TAILQ_REMOVE(&_sysio_entry_trace_head, tcb, links); + free(tcb); + } + while ((tcb = _sysio_exit_trace_head.tqh_first) != NULL) { + TAILQ_REMOVE(&_sysio_exit_trace_head, tcb, links); + free(tcb); + } + } +#endif #endif } @@ -247,6 +283,68 @@ _sysio_cprintf(const char *fmt, ...) _sysio_cwrite(buf, len); free(buf); } + +/* + * Register a trace callback. + * + * The pointer to the tracde record is returned. + */ +void * +_sysio_register_trace(void *q, + void (*f)(const char *file, + const char *func, + int line)) +{ + struct trace_callback *tcb; + + tcb = malloc(sizeof(struct trace_callback)); + if (!tcb) + return NULL; + TCB_INIT(tcb, f); + TAILQ_INSERT_TAIL((struct trace_q *)q, tcb, links); + return tcb; +} + +void +_sysio_remove_trace(void *q, void *p) +{ + + TAILQ_REMOVE((struct trace_q *)q, (struct trace_callback *)p, links); + free(p); +} + +void +_sysio_run_trace_q(void *q, + const char *file, + const char *func, + int line) +{ + struct trace_callback *tcb; + + tcb = ((struct trace_q *)q)->tqh_first; + while (tcb) { + (*tcb->f)(file, func, line); + tcb = tcb->links.tqe_next; + } +} + +static void +_sysio_trace_entry(const char *file __IS_UNUSED, + const char *func, + int line __IS_UNUSED) +{ + + _sysio_cprintf("+ENTER+ %s\n", func); +} + +static void +_sysio_trace_exit(const char *file __IS_UNUSED, + const char *func, + int line __IS_UNUSED) +{ + + _sysio_cprintf("+EXIT+ %s\n", func); +} #endif /* defined(SYSIO_TRACING) */ /* @@ -776,6 +874,9 @@ _sysio_boot_tracing(const char *arg) { long l; char *cp; + static struct trace_callback + *entcb = NULL, + *exitcb = NULL; l = 0; if (arg) { @@ -783,7 +884,27 @@ _sysio_boot_tracing(const char *arg) if (*cp || !(l == 0 || l == 1)) return -EINVAL; } - _sysio_tracing = (int )l; + if (l) { + if (entcb == NULL) + entcb = + _sysio_register_trace(_sysio_entry_trace_q, + _sysio_trace_entry); + if (entcb == NULL) + return -errno; + if (exitcb == NULL) + exitcb = + _sysio_register_trace(_sysio_exit_trace_q, + _sysio_trace_exit); + if (exitcb == NULL) + return -errno; + } else { + if (entcb != NULL) + _sysio_remove_trace(_sysio_entry_trace_q, entcb); + entcb = NULL; + if (exitcb != NULL) + _sysio_remove_trace(_sysio_exit_trace_q, exitcb); + exitcb = NULL; + } return 0; } #endif |