static void _ObjectRegistryDeregister ( _ObjectRegistry registry, gapi_handle handle) { assert(registry); assert(handle); os_mutexLock(®istry->mutex); c_iterTake(registry->active, handle); if (handle->kind != OBJECT_KIND_WAITSET) { if (registry->trash[registry->ptr]) { UT_TRACE("_ObjectRegistryDeregister(%x,%x) %d freed\n", (unsigned int)registry, (unsigned int)registry->trash[registry->ptr], ((gapi_handle)registry->trash[registry->ptr])->kind); gapi__free(registry->trash[registry->ptr]); } UT_TRACE("_ObjectRegistryDeregister(%x,%x) %d added to trash\n", (unsigned int)registry, (unsigned int)handle, handle->kind); registry->trash[registry->ptr] = handle; registry->ptr = (registry->ptr+1)%TRASH_LENGTH; } os_mutexUnlock(®istry->mutex); }
v_handleResult v_handleRelease ( v_handle handle) { v_handleInfo *info; v_handleResult result; result = v_handleServerInfo(handle, &info); if (result == V_HANDLE_OK) { assert(info != NULL); assert(info->count > 0); info->count--; #if CHECK_REF if (v_object(info->object)->kind == CHECK_REF_TYPE) { UT_TRACE("\n\n=========== Release (0x%x): %d -> %d ============\n", info->object, info->count+1, info->count); } #endif if (info->count == 0) { if (info->freed) { /* at this point the handle was deregistered but could not * be invalidated because it was claimed, so it must be invalidated now. */ v_handleInvalidate(handle,info); } else { c_mutexUnlock(&info->mutex); } } else { c_mutexUnlock(&info->mutex); } } return result; }
void d_objectFree( d_object object, d_kind kind) { os_uint32 refCount; OS_UNUSED_ARG(kind); assert(d_objectIsValid(object, kind) == TRUE); if(object){ assert(object->confidence == D_CONFIDENCE); assert(object->kind == kind); assert(object->refCount >= 1); refCount = pa_decrement(&(object->refCount)); if(refCount == 0){ if(object->deinit){ object->deinit(object); } object->confidence = D_CONFIDENCE_NULL; object->kind = D_BAD_TYPE; os_free(object); assert(doSub(kind)); } #if CHECK_REF if (kind == CHECK_REF_TYPE) { UT_TRACE("\n\n============ Free(%p): %d -> %d =============\n", (void*)object, refCount+1, refCount); } #endif } }
void gapi__free ( void *object) { contextHeader *context; gapi_boolean result; if (object != NULL) { context = (contextHeader *)((PA_ADDRCAST)object - CONTEXTHEADER_SIZE); UT_TRACE("gapi__free(%x) header %x context %x\n", (unsigned int)object, (unsigned int)context->alloc_addr, (unsigned int)context); if (context->magic == HMM_MAGIC) { if (context->deallocator == NULL) { context->magic = 0; os_free(context->alloc_addr); } else { result = context->deallocator(object); if (result) { context->magic = 0; os_free(context->alloc_addr); } } } } }
static gapi_boolean gapi_handleFree ( void *o) { gapi_handle handle = (gapi_handle) o; gapi_deleteEntityAction action = NULL; gapi_boolean result = TRUE; void *userData; void *actionData; UT_TRACE("gapi_handleFree(%x) %d\n",(unsigned int)handle, handle->kind); if (gapi_handleClaim(handle) == GAPI_RETCODE_OK) { assert(handle->deallocator); if ( handle->userData && handle->deleteActionInfo.action ) { action = handle->deleteActionInfo.action; userData = handle->userData; actionData = handle->deleteActionInfo.argument; } handle->beingDeleted = TRUE; if ( handle->object != NULL ) { result = handle->deallocator(handle->object); if ((handle->kind == OBJECT_KIND_WAITSET) && (handle->registry != NULL)) { _ObjectRegistryDeregister(handle->registry, handle); handle->registry = NULL; handle->object = NULL; } /* Only release _Object when deallocator returned successfully. */ if (result) { os_free(handle->object); handle->object = NULL; } } if ( result && action ) { action(userData, actionData); } /* Only release handle when deallocator returned successfully. */ if (result == TRUE) { assert(handle->registry == NULL); handle->magic = 0; gapi_handleRelease(handle); os_condDestroy(&handle->cv); os_mutexDestroy(&handle->mutex); #ifdef _RWLOCK_ os_mutexDestroy(&handle->read); #endif } else { gapi_handleRelease(handle); } } return result; }
v_handleResult v_handleClaim ( v_handle handle, v_object *o) { v_handleInfo *info; v_handleResult result; v_handleServer server; server = v_handleServer((c_object)handle.server); if (server == NULL) { return V_HANDLE_ILLEGAL; } if(server->suspended == TRUE) { /* For now the suspended state means that an unrecoverable error has * occured. This implies that from now on any access to the kernel is * unsafe and the result is undefined. * So because of this skip this action and return NULL. */ return V_HANDLE_SUSPENDED; } result = v_handleServerInfo(handle, &info); if (result != V_HANDLE_OK) { *o = NULL; return result; } if (info->freed) { /* Too late, it is already being freed... */ result = V_HANDLE_EXPIRED; *o = NULL; } else { info->count++; #if CHECK_REF if (v_object(info->object)->kind == CHECK_REF_TYPE) { UT_TRACE("\n\n============ Claim (0x%x): %d -> %d =============\n", info->object, info->count -1, info->count); } #endif *o = (v_object)info->object; if(*o == NULL) { OS_REPORT(OS_WARNING, "v_handleClaim", 0, "Unable to obtain kernel entity for handle"); result = V_HANDLE_ILLEGAL; } } c_mutexUnlock(&info->mutex); return result; }
void d_objectInit( d_object object, d_kind kind, d_objectDeinitFunc deinit) { assert(object); if(object){ object->confidence = D_CONFIDENCE; object->kind = kind; object->refCount = 1; object->deinit = deinit; #if CHECK_REF if (kind == CHECK_REF_TYPE) { UT_TRACE("\n\n============ New(%p) =============\n", (void*)object); } #endif assert(doAdd(kind)); } }
d_object d_objectKeep( d_object object) { d_object result = NULL; assert(object); assert(object->confidence == D_CONFIDENCE); if(object){ pa_increment(&(object->refCount)); result = object; #if CHECK_REF if (object->kind == CHECK_REF_TYPE) { UT_TRACE("\n\n============ Keep(%p): %d -> %d =============\n", (void*)object, refCount-1, refCount); } #endif } return result; }