bool sphPluginDrop ( PluginType_e eType, const char * sName, CSphString & sError ) { #if !HAVE_DLOPEN sError = "no dlopen(), no plugins"; return false; #else CSphScopedLock<CSphMutex> tLock ( g_tPluginMutex ); PluginKey_t tKey ( eType, sName ); PluginDesc_c ** ppPlugin = g_hPlugins(tKey); if ( !ppPlugin || !*ppPlugin ) { sError.SetSprintf ( "plugin '%s' does not exist", sName ); return false; } PluginDesc_c * pPlugin = *ppPlugin; PluginLib_c * pLib = pPlugin->GetLib(); Verify ( g_hPlugins.Delete(tKey) ); pPlugin->Release(); if ( --pLib->m_iHashedPlugins==0 ) { g_hPluginLibs.Delete ( pLib->GetName() ); pLib->Release(); } return true; #endif // HAVE_DLOPEN }
bool XQNode_t::IsEqualTo ( const XQNode_t * pNode ) { if ( !pNode || pNode->GetHash()!=GetHash() || pNode->GetOp()!=GetOp() ) return false; if ( m_dWords.GetLength() ) { // two plain nodes. let's compare the keywords if ( pNode->m_dWords.GetLength()!=m_dWords.GetLength() ) return false; if ( !m_dWords.GetLength() ) return true; SmallStringHash_T<int> hSortedWords; ARRAY_FOREACH ( i, pNode->m_dWords ) hSortedWords.Add ( 0, pNode->m_dWords[i].m_sWord ); ARRAY_FOREACH ( i, m_dWords ) if ( !hSortedWords.Exists ( m_dWords[i].m_sWord ) ) return false; return true; } // two non-plain nodes. let's compare the children if ( pNode->m_dChildren.GetLength()!=m_dChildren.GetLength() ) return false; if ( !m_dChildren.GetLength() ) return true; ARRAY_FOREACH ( i, m_dChildren ) if ( !pNode->m_dChildren[i]->IsEqualTo ( m_dChildren[i] ) ) return false; return true; }
bool sphPluginCreate ( const char * szLib, PluginType_e eType, const char * sName, ESphAttr eUDFRetType, CSphString & sError ) { #if !HAVE_DLOPEN sError = "no dlopen(), no plugins"; return false; #else if ( !g_bPluginsEnabled ) { sError = "plugin support disabled (requires a valid plugin_dir)"; return false; } // validate library name for ( const char * p = szLib; *p; p++ ) if ( *p=='/' || *p=='\\' ) { sError = "restricted character (path delimiter) in a library file name"; return false; } CSphString sLib = szLib; sLib.ToLower(); // FIXME? preregister known rankers instead? if ( eType==PLUGIN_RANKER ) { for ( int i=0; i<SPH_RANK_TOTAL; i++ ) { const char * r = sphGetRankerName ( ESphRankMode(i) ); if ( r && strcasecmp ( sName, r )==0 ) { sError.SetSprintf ( "%s is a reserved ranker name", r ); return false; } } } // from here, we need a lock (we intend to update the plugin hash) CSphScopedLock<CSphMutex> tLock ( g_tPluginMutex ); // validate function name PluginKey_t k ( eType, sName ); if ( g_hPlugins(k) ) { sError.SetSprintf ( "plugin '%s' already exists", k.m_sName.cstr() ); return false; } // lookup or load library PluginLib_c * pLib = NULL; if ( g_hPluginLibs ( sLib ) ) { pLib = g_hPluginLibs [ sLib ]; pLib->AddRef(); } else { pLib = LoadPluginLibrary ( sLib.cstr(), sError ); if ( !pLib ) return false; } assert ( pLib->GetHandle() ); PluginDesc_c * pPlugin = NULL; const SymbolDesc_t * pSym = NULL; switch ( eType ) { case PLUGIN_RANKER: pPlugin = new PluginRanker_c ( pLib ); pSym = g_dSymbolsRanker; break; case PLUGIN_INDEX_TOKEN_FILTER: pPlugin = new PluginTokenFilter_c ( pLib ); pSym = g_dSymbolsTokenFilter; break; case PLUGIN_QUERY_TOKEN_FILTER: pPlugin = new PluginQueryTokenFilter_c ( pLib ); pSym = g_dSymbolsQueryTokenFilter; break; case PLUGIN_FUNCTION: pPlugin = new PluginUDF_c ( pLib, eUDFRetType ); pSym = g_dSymbolsUDF; break; default: sError.SetSprintf ( "INTERNAL ERROR: unknown plugin type %d in CreatePlugin()", (int)eType ); pLib->Release(); return false; } // release the refcount that this very function is holding // or in other words, transfer the refcount to newly created plugin instance (it does its own addref) pLib->Release(); if ( !PluginLoadSymbols ( pPlugin, pSym, pLib->GetHandle(), k.m_sName.cstr(), sError ) ) { sError.SetSprintf ( "%s in %s", sError.cstr(), sLib.cstr() ); pPlugin->Release(); return false; } // add library if needed if ( !g_hPluginLibs ( sLib ) ) { Verify ( g_hPluginLibs.Add ( pLib, pLib->GetName() ) ); pLib->AddRef(); // the hash reference } // add function Verify ( g_hPlugins.Add ( pPlugin, k ) ); pPlugin->GetLib()->m_iHashedPlugins++; return true; #endif // HAVE_DLOPEN }