void CSynapseServer::PushRequired( CSynapseClient *pClient ) { /* walk through the standard APIs and push them in */ int i,max = pClient->GetAPICount(); for ( i = 0; i < max; i++ ) { APIDescriptor_t* pAPI = pClient->GetAPIDescriptor( i ); if ( pAPI->mType == SYN_REQUIRE && !pAPI->mbTableInitDone ) { TryPushStack( pAPI ); } } /* if this client has 'List' API Manager types, walk through them for addition too */ max = pClient->GetManagerListCount(); for ( i = 0; i < max; i++ ) { CSynapseAPIManager *pManager = pClient->GetManagerList( i ); assert( pManager->GetType() == API_LIST ); pManager->InitializeAPIList(); int j; for ( j = 0; j < pManager->GetAPICount(); j++ ) { TryPushStack( pManager->GetAPI( j ) ); } } /* if there are loose match managers, prompt them against the current list of SYN_PROVIDE interfaces * and let them decide which ones they might want */ max = pClient->GetManagerMatchCount(); for ( i = 0; i < max; i++ ) { CSynapseAPIManager *pManager = pClient->GetManagerMatch( i ); // start matching all known SYN_PROVIDE APIs against this manager list<CSynapseClientSlot>::iterator iClientSlot; for ( iClientSlot = mClients.begin(); iClientSlot != mClients.end(); iClientSlot++ ) { CSynapseClient *pScanClient = ( *iClientSlot ). mpClient; int j,jmax = pScanClient->GetAPICount(); for ( j = 0; j < jmax; j++ ) { APIDescriptor_t *pAPI = pScanClient->GetAPIDescriptor( j ); if ( pAPI->mType == SYN_PROVIDE ) { if ( pManager->MatchAPI( pAPI->major_name, pAPI->minor_name ) ) { /*! we are going to want to load this one * NOTE TTimo: what if this can not be resolved in the end? * if this happens, then the whole startup will fail instead * or we can use SYN_REQUIRE_ANY and drop it without consequences */ APIDescriptor_t *pPushAPI = pManager->BuildRequireAPI( pAPI ); TryPushStack( pPushAPI ); } } } } } }
void CSynapseServer::DumpActiveClients() { list<CSynapseClientSlot>::iterator iClient; for ( iClient = mClients.begin(); iClient != mClients.end(); iClient++ ) { CSynapseClient *pClient = ( *iClient ).mpClient; Syn_Printf( "%s", pClient->GetInfo() ); if ( pClient->IsActive() ) { Syn_Printf( "\n" ); } else { Syn_Printf( " (not active)\n" ); } } }
static void add_model_apis( CSynapseClient& client ){ char **ext; for ( ext = supportedmodelformats; *ext != NULL; ext++ ) { client.AddAPI( MODEL_MAJOR, *ext, sizeof( _QERPlugModelTable ) ); } }
bool CSynapseServer::Resolve( CSynapseClient *pClient ) { bool ret = DoResolve( pClient ); list<CSynapseClientSlot>::iterator iClient; iClient = mClients.begin(); while ( iClient != mClients.end() ) { CSynapseClient *pClient = ( *iClient ).mpClient; if ( !pClient->IsActive() ) { Syn_Printf( "Unloading an unused module: '%s'\n", pClient->GetInfo() ); iClient = ShutdownClient( iClient ); } else { iClient++; } } return ret; }
static void add_model_apis( CSynapseClient& client ){ const picoModule_t** modules = PicoModuleList( NULL ); while ( *modules != NULL ) { const picoModule_t* module = *modules++; if ( module->canload && module->load ) { for ( unsigned int j = 0; module->defaultExts[j] != NULL; j++ ) client.AddAPI( MODEL_MAJOR, module->defaultExts[j], sizeof( _QERPlugModelTable ) ); } } }
int CSynapseServer::FindActiveMajorClient( const char * major, APIDescriptor_t ** ret ) const { Syn_Printf( "checking if we have a single active client for major \"%s\"\n", major ); *ret = NULL; list<CSynapseClientSlot>::const_iterator iClient; for ( iClient = mClients.begin(); iClient != mClients.end(); iClient++ ) { CSynapseClient *pClient = ( *iClient ).mpClient; if ( !pClient->IsActive() ) { continue; } APIDescriptor_t * found = pClient->FindProvidesMajor( major ); if ( found == NULL ) { continue; } Syn_Printf( " found in %s\n", pClient->GetInfo() ); if ( *ret != NULL ) { return 2; } *ret = found; } if ( *ret == NULL ) { return 0; } return 1; }
bool CSynapseServer::ResolveAPI( APIDescriptor_t* pAPI ) { //Syn_Printf("In ResolveAPI %s %p '%s' '%s'\n", APITypeName[pAPI->mType], pAPI, pAPI->major_name, pAPI->minor_name); // loop through active clients, search for a client providing what we are looking for list<CSynapseClientSlot>::iterator iClient; for ( iClient = mClients.begin(); iClient != mClients.end(); iClient++ ) { // walk through interfaces on this client for a match CSynapseClient *pScanClient = ( *iClient ).mpClient; int i,max = pScanClient->GetAPICount(); for ( i = 0; i < max; i++ ) { APIDescriptor_t *pScanClientAPI = pScanClient->GetAPIDescriptor( i ); if ( pScanClientAPI->mType == SYN_PROVIDE ) { if ( MatchAPI( pAPI, pScanClientAPI ) ) { // can this client provide APIs yet // it is possible that all of it's APIs have been filled and it's not been activated yet pScanClient->CheckSetActive(); if ( pScanClient->IsActive() ) { // make sure this interface has correct size (this is our version check) if ( pAPI->mSize != pScanClientAPI->mSize ) { Syn_Printf( "ERROR: version mismatch for API '%s' '%s' found in '%s' (size %d != %d)\n", pAPI->major_name, pAPI->minor_name, pScanClient->GetInfo(), pAPI->mSize, pScanClientAPI->mSize ); Syn_Printf( " the module and the server are incompatible\n" ); // keep going to other APIs continue; } // this is an active client, we can request #ifdef SYNAPSE_VERBOSE Syn_Printf( "RequestAPI '%s' '%s' from '%s' for API %p\n", pAPI->major_name, pAPI->minor_name, pScanClient->GetInfo(), pAPI ); #endif if ( !pScanClient->RequestAPI( pAPI ) ) { // this should never happen, means we think this module provides the API, but it answers that it doesn't Syn_Printf( "ERROR: RequestAPI failed\n" ); return false; } pScanClientAPI->mRefCount++; pAPI->mbTableInitDone = true; return true; // job done } else { // this client is not active yet, some of it's required interfaces are not filled in PushRequired( pScanClient ); // we will exit the scan through the APIDescriptor of this client and look at other clients break; } } } } } return false; }