ENGINE_PILE tmplate, *fnd;
ENGINE_PILE tmplate, *fnd=NULL;
ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)#elseENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)#endif	{	ENGINE *ret = NULL;	ENGINE_PILE tmplate, *fnd;	int initres, loop = 0;	/* If 'engine_ciphers' is NULL, then it's absolutely *sure* that no	 * ENGINEs have registered any implementations! */	if(!(*table))		{#ifdef ENGINE_TABLE_DEBUG		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "			"registered for anything!\n", f, l, nid);#endif		return NULL;		}	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);	/* Check again inside the lock otherwise we could race against cleanup	 * operations. But don't worry about a fprintf(stderr). */	if(!int_table_check(table, 0))		goto end;	tmplate.nid = nid;	fnd = lh_retrieve(&(*table)->piles, &tmplate);	if(!fnd)		goto end;	if(fnd->funct && engine_unlocked_init(fnd->funct))		{#ifdef ENGINE_TABLE_DEBUG		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "			"ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);#endif		ret = fnd->funct;		goto end;		}	if(fnd->uptodate)		{		ret = fnd->funct;		goto end;		}trynext:	ret = sk_ENGINE_value(fnd->sk, loop++);	if(!ret)		{#ifdef ENGINE_TABLE_DEBUG		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "				"registered implementations would initialise\n",				f, l, nid);#endif		goto end;		}#if 0	/* Don't need to get a reference if we hold the lock. If the locking has	 * to change in future, that would be different ... */	ret->struct_ref++; engine_ref_debug(ret, 0, 1)#endif	/* Try and initialise the ENGINE if it's already functional *or* if the	 * ENGINE_TABLE_FLAG_NOINIT flag is not set. */	if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))		initres = engine_unlocked_init(ret);	else		initres = 0;#if 0	/* Release the structural reference */	ret->struct_ref--; engine_ref_debug(ret, 0, -1);#endif	if(initres)		{		/* If we didn't have a default (functional reference) for this		 * 'nid' (or we had one but for whatever reason we're now		 * initialising a different one), use this opportunity to set		 * 'funct'. */		if((fnd->funct != ret) && engine_unlocked_init(ret))			{			/* If there was a previous default we release it. */			if(fnd->funct)				engine_unlocked_finish(fnd->funct, 0);			/* We got an extra functional reference for the			 * per-'nid' default */			fnd->funct = ret;#ifdef ENGINE_TABLE_DEBUG			fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "				"setting default to '%s'\n", f, l, nid, ret->id);#endif			}#ifdef ENGINE_TABLE_DEBUG		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "				"newly initialised '%s'\n", f, l, nid, ret->id);#endif		goto end;		}	goto trynext;end:	/* Whatever happened - we should "untouch" our uptodate file seeing as	 * we have tried our best to find a functional reference for 'nid'. If	 * it failed, it is unlikely to succeed again until some future	 * registrations (or unregistrations) have taken place that affect that	 * 'nid'. */	if(fnd)		fnd->uptodate = 1;#ifdef ENGINE_TABLE_DEBUG	if(ret)		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "				"ENGINE '%s'\n", f, l, nid, ret->id);	else		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "				"'no matching ENGINE'\n", f, l, nid);#endif	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);	/* Whatever happened, any failed init()s are not failures in this	 * context, so clear our error state. */	ERR_clear_error();	return ret;	}