/*************************************************************************** * (c)2004-2011 Broadcom Corporation * * This program is the proprietary software of Broadcom Corporation and/or its licensors, * and may only be used, duplicated, modified or distributed pursuant to the terms and * conditions of a separate, written license agreement executed between you and Broadcom * (an "Authorized License"). Except as set forth in an Authorized License, Broadcom grants * no license (express or implied), right to use, or waiver of any kind with respect to the * Software, and Broadcom expressly reserves all rights in and to the Software and all * intellectual property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU * HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY * NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. * * Except as expressly set forth in the Authorized License, * * 1. This program, including its structure, sequence and organization, constitutes the valuable trade * secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof, * and to use this information only in connection with your use of Broadcom integrated circuit products. * * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" * AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO * THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, * LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION * OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF * USE OR PERFORMANCE OF THE SOFTWARE. * * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS * LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR * EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR * USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT * ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF * ANY LIMITED REMEDY. * * $brcm_Workfile: b_objdb.h $ * $brcm_Revision: 5 $ * $brcm_Date: 9/16/11 3:40p $ * * Module Description: * * Revision History: * * $brcm_Log: /nexus/base/include/b_objdb.h $ * * 5 9/16/11 3:40p erickson * SW7420-2064: clean up unprotected callbacks when client exits, allow * re-registration when client connects * * 4 9/13/11 1:24p erickson * SW7420-1148: change client modes to unprotected/protected/untrusted * * 3 9/2/11 10:01a erickson * SW7420-1148: allow implicit insert on acquire. allows non-thunked * server to work with thunked client. * * 2 7/26/11 12:07p erickson * SW7420-1992: callback database must take client id so that callbacks * can be disconnected when a client releases * * 1 4/1/11 9:59a erickson * SW7420-1671: refactor object database for multiprocess stress * ************************************************************/ #ifndef B_OBJDB_H__ #define B_OBJDB_H__ #include "bdbg.h" #include "nexus_types.h" /** object database this api is internal to nexus. used by nexus kernel-mode proxy and user-mode multiprocess thunks. it uses static allocation and transparent structs, not dynamic allocation and opaque handles. **/ typedef enum b_objdb_verify { b_objdb_verify_full, /* verify handle, type and client */ b_objdb_verify_partial, /* verify handle and type, not client */ b_objdb_verify_none, /* do not verify the handle */ b_objdb_verify_max } b_objdb_verify; /* the address of the b_objdb_client instance is the id for the client */ struct b_objdb_client { b_objdb_verify verify; bool limited_api; }; /* entries in heap b_objdb_heap. one per handle instance. */ struct b_objdb_entry { void *handle; const struct b_objdb_client *client; /* each object is owned by one client. destroy must match. verify must match client or acquired_client. */ const struct b_objdb_client *acquired_client; /* each object can be acquired by one client. release must match. verify must match client or acquired_client. */ unsigned order; /* persistent order, used to destroy objects in exact opposite of create */ }; /* dynamically allocated array of entries. one per handle type. */ struct b_objdb_heap { unsigned count; /* number of entries in the heap */ struct b_objdb_entry data[1]; /* variable size trailer */ }; BDBG_OBJECT_ID_DECLARE(b_objdb); struct b_objdb_class; /* b_objdb is the object database. There is one instance of b_objdb per module. There is one mutex (nexus module handle) per objdb. */ struct b_objdb { BDBG_OBJECT(b_objdb) const char *name; /* debug */ NEXUS_ModuleHandle module; /* provides synchronization for this DB. _locked functions already have this acquired. */ unsigned object_count; struct b_objdb_class *class_table; /* callback to cancel callbacks for a handle */ void (*cancel_callbacks_locked)(void *context, void *handle, void *client_id); /* called with module lock already acquired */ void *cancel_callbacks_context; }; typedef void (*b_objdb_callback)(void *handle); /* There is one b_objdb_class per class, or interface type. A set of b_objdb_classes is assocatied with a single b_objdb. It is statically populated using macros in the thunk. */ struct b_objdb_class { struct b_objdb *db; const char *type_name; /* handle type name, for debug */ b_objdb_callback release; /* func to call for auto-release. this is called locked. */ b_objdb_callback destructor; /* func to call for auto-close. this is called locked. */ struct b_objdb_heap *objects; /* list of all instances for this object type */ }; #define B_OBJDB_TABLE_BEGIN(NAME) static struct b_objdb_class NAME[] = { #define B_OBJDB_TABLE_END {NULL,NULL,NULL,NULL,NULL}}; #define B_OBJDB_TABLE_ENTRY(handletype,releasefunc,destructorfunc) {NULL, #handletype, (b_objdb_callback)releasefunc, (b_objdb_callback)destructorfunc, NULL}, /* b_objdb_init will hook up the statically-declared class_table. the caller must still manually set db->module, name, cancel_callbacks and cancel_callbacks_context */ int b_objdb_init(struct b_objdb *db, struct b_objdb_class *class_table); void b_objdb_uninit(struct b_objdb *db); /* functions called from thunk. module lock is already acquired. */ int b_objdb_insert_locked(struct b_objdb_class *p_class, void *handle, const struct b_objdb_client *client, bool acquiring /* if false, this is an insert. if true, this is an acquire. */ ); int b_objdb_remove_locked(struct b_objdb_class *p_class, void *handle, const struct b_objdb_client *client, bool releasing /* if false, this pairs with an insert. if true, this pairs with an acquire. */ ); int b_objdb_verify_locked(struct b_objdb_class *p_class, void *handle, const struct b_objdb_client *client); /* clear out all entries, but do not uninit */ void b_objdb_clear(struct b_objdb *db); /* find newest entry for this client in this db. returns 0 if an entry was found. */ int b_objdb_get_newest_entry(struct b_objdb *db, const struct b_objdb_client *client, struct b_objdb_class **p_class, struct b_objdb_entry **p_entry); /* uninit is called on auto-close. it will test if the client owns or has acquiring the handle. will perform one or two removes as needed. */ void b_objdb_uninit_entry(struct b_objdb_class *p_class, struct b_objdb_entry *entry, const struct b_objdb_client *client); /* uninit all callbacks for this client */ void b_objdb_uninit_client(struct b_objdb *db, const struct b_objdb_client *client); #endif