Exemplo n.º 1
0
/* Reference-Counting object access: subract one from the current refcount. Must
 * by called by anyone who no longer needs a module. If count reaches 0, the 
 * module is unloaded. -- rgerhards, 20080-03-10
 */
static rsRetVal
Release(char *srcFile, modInfo_t **ppThis)
{
	DEFiRet;
	modInfo_t *pThis;

	assert(ppThis != NULL);
	pThis = *ppThis;
	assert(pThis != NULL);
	if(pThis->uRefCnt == 0) {
		/* oops, we are already at 0? */
		dbgprintf("internal error: module '%s' already has a refcount of 0 (released by %s)!\n",
			  pThis->pszName, srcFile);
	} else {
		--pThis->uRefCnt;
		dbgprintf("file %s released module '%s', reference count now %u\n",
			  srcFile, pThis->pszName, pThis->uRefCnt);
#		ifdef DEBUG
		modUsrDel(pThis, srcFile);
		modUsrPrint(pThis);
#		endif
	}

	if(pThis->uRefCnt == 0) {
		/* we have a zero refcount, so we must unload the module */
		dbgprintf("module '%s' has zero reference count, unloading...\n", pThis->pszName);
		modUnlinkAndDestroy(&pThis);
		/* we must NOT do a *ppThis = NULL, because ppThis now points into freed memory!
		 * If in doubt, see obj.c::ReleaseObj() for how we are called.
		 */
	}

	RETiRet;

}
Exemplo n.º 2
0
/* unload all loaded modules of a specific type (use eMOD_ALL if you want to
 * unload all module types). The unload happens only if the module is no longer
 * referenced. So some modules may survive this call.
 * rgerhards, 2008-03-11
 */
static rsRetVal
modUnloadAndDestructAll(eModLinkType_t modLinkTypesToUnload)
{
	DEFiRet;
	modInfo_t *pModCurr; /* module currently being processed */

	pModCurr = GetNxt(NULL);
	while(pModCurr != NULL) {
		if(modLinkTypesToUnload == eMOD_LINK_ALL || pModCurr->eLinkType == modLinkTypesToUnload) {
			if(modUnlinkAndDestroy(&pModCurr) == RS_RET_MODULE_STILL_REFERENCED) {
				pModCurr = GetNxt(pModCurr);
			}
			/* Note: if the module was successfully unloaded, it has updated the
			 * pModCurr pointer to the next module. So we do NOT need to advance
			 * to the next module on successful unload.
			 */
		} else {
			pModCurr = GetNxt(pModCurr);
		}
	}

#	ifdef DEBUG
		if(pLoadedModules != NULL) {
			dbgprintf("modules still loaded after module.UnloadAndDestructAll:\n");
			modUsrPrintAll();
		}
#	endif

	RETiRet;
}
Exemplo n.º 3
0
/* unload all loaded modules of a specific type (use eMOD_ALL if you want to
 * unload all module types). The unload happens only if the module is no longer
 * referenced. So some modules may survive this call.
 * rgerhards, 2008-03-11
 */
static rsRetVal
modUnloadAndDestructAll(eModLinkType_t modLinkTypesToUnload)
{
	DEFiRet;
	modInfo_t *pModCurr; /* module currently being processed */

	pModCurr = GetNxt(NULL);
	while(pModCurr != NULL) {
		if(modLinkTypesToUnload == eMOD_LINK_ALL || pModCurr->eLinkType == modLinkTypesToUnload) {
			if(modUnlinkAndDestroy(&pModCurr) == RS_RET_MODULE_STILL_REFERENCED) {
				pModCurr = GetNxt(pModCurr);
			} else {
				/* Note: if the module was successfully unloaded, it has updated the
				 * pModCurr pointer to the next module. However, the unload process may
				 * still have indirectly referenced the pointer list in a way that the
				 * unloaded module is not aware of. So we restart the unload process
				 * to make sure we do not fall into a trap (what we did ;)). The
				 * performance toll is minimal. -- rgerhards, 2008-04-28
				 */
				pModCurr = GetNxt(NULL);
			}
		} else {
			pModCurr = GetNxt(pModCurr);
		}
	}

#	ifdef DEBUG
	/* DEV DEBUG only!
		if(pLoadedModules != NULL) {
			dbgprintf("modules still loaded after module.UnloadAndDestructAll:\n");
			modUsrPrintAll();
		}
	*/
#	endif

	RETiRet;
}