1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * Callback facility designed to allow interested parties (dmods, targets, or 31 * even the core debugger framework) to register for notification when certain 32 * "interesting" events occur. 33 */ 34 35 #include <mdb/mdb_list.h> 36 #include <mdb/mdb_debug.h> 37 #include <mdb/mdb_callb.h> 38 #include <mdb/mdb_module.h> 39 #include <mdb/mdb.h> 40 41 mdb_callb_t * 42 mdb_callb_add(mdb_module_t *m, int class, mdb_callb_f fp, void *arg) 43 { 44 mdb_callb_t *new = mdb_zalloc(sizeof (mdb_callb_t), UM_SLEEP); 45 46 ASSERT(class == MDB_CALLB_STCHG || class == MDB_CALLB_PROMPT); 47 48 new->cb_mod = m; 49 new->cb_class = class; 50 new->cb_func = fp; 51 new->cb_arg = arg; 52 53 if (m == NULL) { 54 mdb_list_prepend(&mdb.m_cblist, new); 55 } else { 56 mdb_list_insert(&mdb.m_cblist, m->mod_cb, new); 57 if (m->mod_cb == NULL) 58 m->mod_cb = new; 59 } 60 61 return (new); 62 } 63 64 void 65 mdb_callb_remove(mdb_callb_t *cb) 66 { 67 if (cb->cb_mod != NULL) { 68 mdb_callb_t *next = mdb_list_next(cb); 69 mdb_module_t *mod = cb->cb_mod; 70 71 if (mod->mod_cb == cb) { 72 if (next == NULL || next->cb_mod != mod) 73 mod->mod_cb = NULL; 74 else 75 mod->mod_cb = next; 76 } 77 } 78 79 mdb_list_delete(&mdb.m_cblist, cb); 80 81 mdb_free(cb, sizeof (mdb_callb_t)); 82 } 83 84 void 85 mdb_callb_remove_by_mod(mdb_module_t *m) 86 { 87 while (m->mod_cb != NULL) 88 mdb_callb_remove(m->mod_cb); 89 } 90 91 void 92 mdb_callb_remove_all(void) 93 { 94 mdb_callb_t *cb; 95 96 while ((cb = mdb_list_next(&mdb.m_cblist)) != NULL) 97 mdb_callb_remove(cb); 98 } 99 100 void 101 mdb_callb_fire(int class) 102 { 103 mdb_callb_t *cb, *next; 104 105 ASSERT(class == MDB_CALLB_STCHG || class == MDB_CALLB_PROMPT); 106 107 mdb_dprintf(MDB_DBG_CALLB, "invoking %s callbacks\n", 108 (class == MDB_CALLB_STCHG ? "state change" : "prompt")); 109 110 for (cb = mdb_list_next(&mdb.m_cblist); cb != NULL; cb = next) { 111 next = mdb_list_next(cb); 112 if (cb->cb_class == class) 113 cb->cb_func(cb->cb_arg); 114 } 115 } 116