void Binding::initialize( const ContextHandle context , const bool _useContext , const bool _resolveFunctions) { mutex.lock(); // TODO: use read lock if (bindings.find(context) != bindings.end()) { mutex.unlock(); return; } mutex.unlock(); const int pos = static_cast<int>(bindings.size()); mutex.lock(); // TODO: use write lock bindings[context] = pos; mutex.unlock(); mutex.lock(); // TODO: use read lock AbstractFunction::provideState(pos); mutex.unlock(); if (_useContext) useContext(context); if (_resolveFunctions) resolveFunctions(); }
void Binding::initialize( const ContextHandle context , const bool _useContext , const bool _resolveFunctions) { g_mutex.lock(); if (g_bindings.find(context) != g_bindings.end()) { g_mutex.unlock(); return; } g_mutex.unlock(); const int pos = static_cast<int>(g_bindings.size()); g_mutex.lock(); g_bindings[context] = pos; g_mutex.unlock(); g_mutex.lock(); AbstractFunction::provideState(pos); g_mutex.unlock(); if (_useContext) { useContext(context); } if (_resolveFunctions) { resolveFunctions(); } }
int QmcGroup::setArchiveMode(int mode, const struct timeval *when, int interval) { int sts, result = 0; for (unsigned int i = 0; i < numContexts(); i++) { if (my.contexts[i]->source().type() != PM_CONTEXT_ARCHIVE) continue; sts = pmUseContext(my.contexts[i]->handle()); if (sts < 0) { pmprintf("%s: Error: Unable to switch to context for %s: %s\n", pmProgname, my.contexts[i]->source().sourceAscii(), pmErrStr(sts)); result = sts; continue; } sts = pmSetMode(mode, when, interval); if (sts < 0) { pmprintf("%s: Error: Unable to set context mode for %s: %s\n", pmProgname, my.contexts[i]->source().sourceAscii(), pmErrStr(sts)); result = sts; } } sts = useContext(); if (sts < 0) result = sts; return result; }
void Binding::initialize( const ContextHandle context , const bool _useContext , const bool _resolveFunctions) { g_mutex.lock(); if (g_bindings.find(context) != g_bindings.cend()) { g_mutex.unlock(); return; } g_mutex.unlock(); const auto pos = static_cast<int>(g_bindings.size()); g_mutex.lock(); g_bindings[context] = pos; g_mutex.unlock(); g_mutex.lock(); AbstractFunction::provideState(pos); g_mutex.unlock(); const auto resolveWOUse = !_useContext & _resolveFunctions; const auto currentContext = resolveWOUse ? getCurrentContext() : static_cast<ContextHandle>(0); if(_useContext) useContext(context); if (_resolveFunctions) resolveFunctions(); // restore previous context if(resolveWOUse) useContext(currentContext); }
int QmcGroup::fetch(bool update) { int sts = 0; if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::fetch: " << numContexts() << " contexts" << endl; } for (unsigned int i = 0; i < numContexts(); i++) my.contexts[i]->fetch(update); if (numContexts()) sts = useContext(); if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::fetch: Done" << endl; } return sts; }
void Binding::useCurrentContext() { useContext(getCurrentContext()); }
int QmcGroup::use(int type, const QString &theSource, int flags) { int sts = 0; unsigned int i; QString source(theSource); if (type == PM_CONTEXT_LOCAL) { for (i = 0; i < numContexts(); i++) if (my.contexts[i]->source().type() == type) break; } else if (type == PM_CONTEXT_ARCHIVE) { if (source == QString::null) { pmprintf("%s: Error: Archive context requires archive path\n", pmProgname); return PM_ERR_NOCONTEXT; } // This doesn't take into account {.N,.meta,.index,} ... but // then again, nor does pmNewContext. More work ... useful? for (i = 0; i < numContexts(); i++) { if (source == my.contexts[i]->source().source()) break; } } else { if (source == QString::null) { if (!defaultDefined()) { createLocalContext(); if (!defaultDefined()) { pmprintf("%s: Error: " "Cannot connect to PMCD on localhost: %s\n", pmProgname, pmErrStr(my.localSource->status())); return my.localSource->status(); } } source = my.contexts[0]->source().source(); } for (i = 0; i < numContexts(); i++) { if (source == my.contexts[i]->source().source()) break; } } if (i == numContexts()) { if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: No direct match for context \"" << source << "\" (type " << type << ")." << endl; } // Determine live or archive mode by the first source if (i == 0) my.mode = type; // If the assumed mode differs from the requested context type // we may need to map the host to an archive if (my.mode != type) { if (my.mode == PM_CONTEXT_HOST && type == PM_CONTEXT_ARCHIVE) { pmprintf("%s: Error: Archive \"%s\" requested " "after live mode was assumed.\n", pmProgname, (const char *)source.toAscii()); return PM_ERR_NOCONTEXT; } // If we are in archive mode, map hosts to archives of same host if (my.mode == PM_CONTEXT_ARCHIVE && type == PM_CONTEXT_HOST) { QString chop1 = source.remove(PM_LOG_MAXHOSTLEN-1, INT_MAX); for (i = 0; i < numContexts(); i++) { QString chop2 = my.contexts[i]->source().host(); chop2.remove(PM_LOG_MAXHOSTLEN-1, INT_MAX); if (chop1 == chop2) break; } if (i == numContexts()) { pmprintf("%s: Error: No archives were specified " "for host \"%s\"\n", pmProgname, (const char *)source.toAscii()); return PM_ERR_NOTARCHIVE; } } } } if (i == numContexts()) { if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Creating new context for \"" << source << '\"' << endl; } QmcSource *src = QmcSource::getSource(type, source, flags, false); if (src == NULL) { pmprintf("%s: Error: No archives were specified for host \"%s\"\n", pmProgname, (const char *)source.toAscii()); return PM_ERR_NOTARCHIVE; } QmcContext *newContext = new QmcContext(src); if (newContext->handle() < 0) { sts = newContext->handle(); pmprintf("%s: Error: %s: %s\n", pmProgname, (const char *)source.toAscii(), pmErrStr(sts)); delete newContext; return sts; } // If we are in archive mode and are adding an archive, // make sure another archive for the same host does not exist if (my.restrictArchives && type == PM_CONTEXT_ARCHIVE) { for (i = 0; i < numContexts(); i++) // No need to restrict comparison here, both are from // log labels. if (my.contexts[i]->source().host() == newContext->source().host()) { pmprintf("%s: Error: Archives \"%s\" and \"%s\" are from " "the same host \"%s\"\n", pmProgname, my.contexts[i]->source().sourceAscii(), newContext->source().sourceAscii(), my.contexts[i]->source().hostAscii()); delete newContext; return PM_ERR_NOCONTEXT; } } my.contexts.append(newContext); my.use = my.contexts.size() - 1; if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Added context " << my.use << ": " << *newContext << endl; } } // We found a match, do we need to use a different context? else if (i != (unsigned int)my.use) { my.use = i; sts = useContext(); if (sts < 0) { pmprintf("%s: Error: Unable to use context to %s: %s\n", pmProgname, context()->source().sourceAscii(), pmErrStr(sts)); return sts; } if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Using existing context " << my.use << " for " << context()->source().desc() << endl; } } else if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Using current context " << my.use << " (handle = " << context()->handle() << ") for " << context()->source().desc() << endl; } return context()->handle(); }