📄 resource.c
字号:
SSMResourceID tmpID; /* We should have been called from a subclass destructor. */ PR_ASSERT(doFree == PR_FALSE); SSM_DEBUG("Destroying %s (rid %ld).\n", res->m_class->m_className, (long) res->m_id); rv = SSM_HashRemove(res->m_connection->m_resourceDB, res->m_id, (void **) &res); if (rv != PR_SUCCESS) return PR_FAILURE; rv = SSM_HashRemove(res->m_connection->m_resourceIdDB, (SSMHashKey)res, (void **) &tmpID); if (rv != PR_SUCCESS) return PR_FAILURE; if (res->m_lock) { PR_DestroyMonitor(res->m_lock); res->m_lock = NULL; } if (res->m_UILock) { PR_DestroyMonitor(res->m_UILock); res->m_UILock = NULL; } if (res->m_formName) { PR_Free(res->m_formName); res->m_formName = NULL; } return PR_SUCCESS;}SSMStatusSSMResource_Init(SSMControlConnection * conn, SSMResource *res, SSMResourceType type){ SSMResourceClass *cls; SSMStatus rv; rv = SSM_FindResourceClass(type, &cls); if (rv != PR_SUCCESS) goto loser; res->m_class = cls; res->m_classType = type; res->m_buttonType = SSM_BUTTON_NONE; res->m_clientDest = cls->m_clientDest; res->m_destroy_func = cls->m_destroy_func; res->m_shutdown_func = cls->m_shutdown_func; res->m_getids_func = cls->m_getids_func; res->m_get_func = cls->m_get_func; res->m_set_func = cls->m_set_func; res->m_pickle_func = cls->m_pickle_func; res->m_html_func = cls->m_html_func; res->m_print_func = cls->m_print_func; res->m_submit_func = cls->m_submit_func; res->m_connection = conn; res->m_lock = PR_NewMonitor(); if (!res->m_lock) goto loser; if (conn != NULL) res->m_id = SSMControlConnection_GenerateResourceID(conn); /* will create this monitor when needed */ res->m_UILock = NULL; res->m_formName = NULL; res->m_fileName = NULL; res->m_clientContext.len = 0; res->m_clientContext.data = NULL; res->m_clientCount = 0; res->m_refCount = 1; res->m_resourceShutdown = PR_FALSE; SSM_DEBUG("Created %s with rid %ld.\n", cls->m_className, (long)res->m_id); if (SSMControlConnection_AddResource(res, res->m_id) != PR_SUCCESS) goto loser; return PR_SUCCESS; loser: if (rv == PR_SUCCESS) rv = PR_FAILURE; return rv;}SSMStatusSSM_FindResourceClass(SSMResourceType type, SSMResourceClass **cls){ SSMStatus rv = PR_SUCCESS; *cls = NULL; /* in case we fail */ PR_ASSERT(ssm_classRegistry != NULL); rv = SSM_HashFind(ssm_classRegistry, type, (void **) cls); return rv;}PRBoolSSM_IsA(SSMResource *res, SSMResourceType type){ return (res && (res->m_classType == type));}PRBoolSSM_IsAKindOf(SSMResource *res, SSMResourceType type){ PRBool result = PR_FALSE; SSMResourceClass *cls; if (!res) return PR_FALSE; SSM_FindResourceClass( res->m_classType, &cls); while (cls && (cls->m_classType != type)) SSM_FindResourceClass(cls->m_superclass, &cls); result = (cls != NULL); return result;}SSMStatusSSM_RegisterResourceType(char *name, SSMResourceType type, SSMResourceType superClass, SSMClientDestroyAction destAction, SSMResourceCreateFunc createFunc, SSMResourceDestroyFunc destFunc, SSMResourceShutdownFunc shutFunc, SSMResourceGetAttrIDsFunc getIDsFunc, SSMResourceGetAttrFunc getFunc, SSMResourceSetAttrFunc setFunc, SSMResourcePickleFunc pickleFunc, SSMResourceUnpickleFunc unpickleFunc, SSMResourceHTMLFunc htmlFunc, SSMResourcePrintFunc printFunc, SSMSubmitHandlerFunc submitFunc){ SSMResourceClass *cls, *super = NULL; SSMStatus rv = PR_SUCCESS; /* If a superclass was specified, find it. */ if (superClass) { rv = SSM_FindResourceClass(superClass, &super); if (rv != PR_SUCCESS) goto loser; } /* Create a new entry for the class. */ cls = (SSMResourceClass *) PR_CALLOC(sizeof(SSMResourceClass)); if (!cls) goto loser; /* Start with the superclass' methods, then overlay the new ones. */ if (super) (void) memcpy(cls, super, sizeof(SSMResourceClass)); cls->m_className = name; cls->m_classType = type; cls->m_superclass = superClass; cls->m_clientDest = destAction; if (createFunc != NULL) cls->m_create_func = createFunc; if (destFunc != NULL) cls->m_destroy_func = destFunc; if (shutFunc != NULL) cls->m_shutdown_func = shutFunc; if (getIDsFunc != NULL) cls->m_getids_func = getIDsFunc; if (getFunc != NULL) cls->m_get_func = getFunc; if (setFunc != NULL) cls->m_set_func = setFunc; if (pickleFunc != NULL) cls->m_pickle_func = pickleFunc; if (unpickleFunc != NULL) cls->m_unpickle_func = unpickleFunc; if (htmlFunc != NULL) cls->m_html_func = htmlFunc; if (printFunc != NULL) cls->m_print_func = printFunc; if (submitFunc != NULL) cls->m_submit_func = submitFunc; rv = SSM_HashInsert(ssm_classRegistry, type, cls); if (rv != PR_SUCCESS) goto loser; return PR_SUCCESS; loser: if (rv == PR_SUCCESS) rv = PR_FAILURE; if (cls) PR_Free(cls); return rv;}SSMStatusSSM_CreateResource(SSMResourceType type, void *arg, SSMControlConnection * connection, SSMResourceID *resID, SSMResource **result){ SSMStatus rv; SSMResourceClass *cls = NULL; SSMResource *res = NULL; rv = SSM_FindResourceClass(type, &cls); if (rv != PR_SUCCESS) goto loser; PR_ASSERT(cls != NULL); /* Call the create function in this class. */ rv = (*cls->m_create_func)(arg, connection, &res); if ((rv != PR_SUCCESS) && (rv != SSM_ERR_DEFER_RESPONSE)) goto loser; *resID = res->m_id; *result = res; return rv; loser: if (res) { res->m_refCount = 1; /* so that it is destroyed */ SSM_FreeResource(res); } return rv;}SSMStatusSSM_GetResourceReference(SSMResource *res){ SSMResource_Invariant(res); SSM_LockResource(res); res->m_refCount++; SSM_DEBUG("Get ref - rsrcid: %ld ++refcnt: %ld\n", res->m_id, res->m_refCount); SSM_UnlockResource(res); return PR_SUCCESS;}SSMStatusSSM_FreeResource(SSMResource *res){ PRIntn refcnt; PR_ASSERT(res != NULL); SSMResource_Invariant(res); PR_ASSERT(res->m_refCount > 0); SSM_LockResource(res); refcnt = --(res->m_refCount); SSM_DEBUG("Free ref - rsrcid: %ld --refcnt: %ld\n", res->m_id, res->m_refCount); res->m_refCount = refcnt; SSM_UnlockResource(res); /* need to handle race condition on destroy */ if (refcnt <= 0) { SSM_DEBUG("Destroying resource.\n", refcnt); return (*res->m_destroy_func)(res, PR_TRUE); } return PR_SUCCESS;}SSMStatusSSM_GetResAttribute(SSMResource *res, SSMAttributeID fieldID, SSMResourceAttrType attrType, SSMAttributeValue *value){ PR_ASSERT(res != NULL); SSMResource_Invariant(res); return (*res->m_get_func)(res,fieldID,attrType,value);}SSMStatusSSM_SetResAttribute(SSMResource *res, SSMAttributeID fieldID, SSMAttributeValue *value){ PR_ASSERT(res != NULL); SSMResource_Invariant(res); return (*res->m_set_func)(res,fieldID,value);}SSMStatus SSM_PickleResource(SSMResource * res, PRIntn * len, void ** value){ PR_ASSERT(res != NULL); return(*res->m_pickle_func)(res, len, value);}SSMStatus SSM_HTMLResource(SSMResource *res, PRIntn *len, void **value){ PR_ASSERT(res != NULL); return(*res->m_html_func)(res, len, value);}SSMStatusSSM_ClientGetResourceReference(SSMResource *res, SSMResourceID *id){ SSM_LockResource(res); res->m_clientCount++; SSM_DEBUG("Get client ref - rsrcid: %ld ++clientcnt: %ld\n", res->m_id, res->m_clientCount); SSM_GetResourceReference(res); if (id) *id = res->m_id; SSM_UnlockResource(res); return PR_SUCCESS;} /* * Unpickle function is similar to create function. Need the switch statement * to call * Unpickle function for different resources. */ SSMStatus SSM_UnpickleResource(SSMResource ** res, SSMResourceType type, SSMControlConnection * connection, PRIntn len, void * value){ SSMStatus rv = PR_SUCCESS; PR_ASSERT(res != NULL); if (!res || !value) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); goto loser; } *res = NULL; /* in case we fail */ switch (type) { case SSM_RESTYPE_CERTIFICATE: rv = SSMResourceCert_Unpickle(res, connection, len, value); break; case SSM_RESTYPE_SSL_SOCKET_STATUS: rv = SSMSSLSocketStatus_Unpickle(res, connection, len, value); break; case SSM_RESTYPE_HASH_CONNECTION: case SSM_RESTYPE_PKCS7_DECODE_CONNECTION: case SSM_RESTYPE_SSL_DATA_CONNECTION: default: rv = PR_FAILURE; } goto done;loser: if (rv == PR_SUCCESS) rv = PR_FAILURE; if (res && *res) { PR_Free(*res); *res = NULL; }done: return rv;}SSMStatusSSM_ShutdownResource(SSMResource *res, SSMStatus status){ PR_ASSERT(res->m_shutdown_func); if (res->m_shutdown_func) return (*res->m_shutdown_func)(res, status); else return PR_FAILURE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -